Skip to content

Commit d94ad25

Browse files
authored
Merge pull request #22 from Fresa/support-openapi32
Support openapi 3.2
2 parents 6288f19 + 1d71c62 commit d94ad25

35 files changed

Lines changed: 2211 additions & 8593 deletions

.github/workflows/lint-openapi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ jobs:
1818

1919
- name: Lint OpenAPI specs
2020
run: |
21-
vacuum lint --globbed-files="*/**/openapi.json"
21+
vacuum lint --globbed-files="tests/{*/,*/*/}openapi*.json"

OpenAPI.WebApiGenerator.sln

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.OpenApi31", "tests\
2424
EndProject
2525
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.OpenApi31.IntegrationTests", "tests\Example.OpenApi31.IntegrationTests\Example.OpenApi31.IntegrationTests.csproj", "{FE9CE314-77B1-4064-B4E3-F2FCE3EDB63C}"
2626
EndProject
27+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.OpenApi32", "tests\Example.OpenApi32\Example.OpenApi32.csproj", "{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}"
28+
EndProject
29+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example.OpenApi32.IntegrationTests", "tests\Example.OpenApi32.IntegrationTests\Example.OpenApi32.IntegrationTests.csproj", "{CFC6595B-DAA2-4866-AE50-6A9AD7863160}"
30+
EndProject
2731
Global
2832
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2933
Debug|Any CPU = Debug|Any CPU
@@ -130,6 +134,30 @@ Global
130134
{FE9CE314-77B1-4064-B4E3-F2FCE3EDB63C}.Release|x64.Build.0 = Release|Any CPU
131135
{FE9CE314-77B1-4064-B4E3-F2FCE3EDB63C}.Release|x86.ActiveCfg = Release|Any CPU
132136
{FE9CE314-77B1-4064-B4E3-F2FCE3EDB63C}.Release|x86.Build.0 = Release|Any CPU
137+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
138+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|Any CPU.Build.0 = Debug|Any CPU
139+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|x64.ActiveCfg = Debug|Any CPU
140+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|x64.Build.0 = Debug|Any CPU
141+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|x86.ActiveCfg = Debug|Any CPU
142+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Debug|x86.Build.0 = Debug|Any CPU
143+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|Any CPU.ActiveCfg = Release|Any CPU
144+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|Any CPU.Build.0 = Release|Any CPU
145+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|x64.ActiveCfg = Release|Any CPU
146+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|x64.Build.0 = Release|Any CPU
147+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|x86.ActiveCfg = Release|Any CPU
148+
{91D58EA1-8ECF-4C18-AB2F-84CDABD22092}.Release|x86.Build.0 = Release|Any CPU
149+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
150+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|Any CPU.Build.0 = Debug|Any CPU
151+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|x64.ActiveCfg = Debug|Any CPU
152+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|x64.Build.0 = Debug|Any CPU
153+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|x86.ActiveCfg = Debug|Any CPU
154+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Debug|x86.Build.0 = Debug|Any CPU
155+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|Any CPU.ActiveCfg = Release|Any CPU
156+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|Any CPU.Build.0 = Release|Any CPU
157+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|x64.ActiveCfg = Release|Any CPU
158+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|x64.Build.0 = Release|Any CPU
159+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|x86.ActiveCfg = Release|Any CPU
160+
{CFC6595B-DAA2-4866-AE50-6A9AD7863160}.Release|x86.Build.0 = Release|Any CPU
133161
EndGlobalSection
134162
GlobalSection(SolutionProperties) = preSolution
135163
HideSolutionNode = FALSE

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@ Generates scaffolding for Web APIs from OpenAPI specifications.
55
The generated functionality will route, serialize/deserialize and validate payloads according to the specification.
66

77
Supported OpenAPI version:
8-
- [2.0](https://spec.openapis.org/oas/v2.0.html)
9-
- [3.0.0](https://spec.openapis.org/oas/v3.0.0.html)
10-
- [3.0.1](https://spec.openapis.org/oas/v3.0.1.html)
11-
- [3.0.2](https://spec.openapis.org/oas/v3.0.2.html)
12-
- [3.0.3](https://spec.openapis.org/oas/v3.0.3.html)
13-
- [3.0.4](https://spec.openapis.org/oas/v3.0.4.html)
14-
- [3.1.0](https://spec.openapis.org/oas/v3.1.0.html)
15-
- [3.1.1](https://spec.openapis.org/oas/v3.1.1.html)
8+
- [3.2.0](https://spec.openapis.org/oas/v3.2.0.html)
169
- [3.1.2](https://spec.openapis.org/oas/v3.1.2.html)
10+
- [3.1.1](https://spec.openapis.org/oas/v3.1.1.html)
11+
- [3.1.0](https://spec.openapis.org/oas/v3.1.0.html)
12+
- [3.0.4](https://spec.openapis.org/oas/v3.0.4.html)
13+
- [3.0.3](https://spec.openapis.org/oas/v3.0.3.html)
14+
- [3.0.2](https://spec.openapis.org/oas/v3.0.2.html)
15+
- [3.0.1](https://spec.openapis.org/oas/v3.0.1.html)
16+
- [3.0.0](https://spec.openapis.org/oas/v3.0.0.html)
17+
- [2.0](https://spec.openapis.org/oas/v2.0.html)
1718

1819
API frameworks supported:
1920
- [Minimal API](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/minimal-apis)
@@ -67,10 +68,11 @@ Examples:
6768
- [OpenAPI 2.0](tests/Example.OpenApi20)
6869
- [OpenAPI 3.0](tests/Example.OpenApi30)
6970
- [OpenAPI 3.1](tests/Example.OpenApi31)
71+
- [OpenAPI 3.2](tests/Example.OpenApi32)
7072

7173
All specifications mostly generate similar abstractions. What might differ is the location of generated resources, which follows the respective structure of the OpenAPI specification, and the JSON types, which are based on the respective schema version.
7274

73-
**Note**: The Examples reference the generator through a project reference. Use a package reference instead as described above.
75+
**Note**: The examples reference the generator through a project reference. Use a package reference instead as described above.
7476

7577
## Implementing an [API Operation](https://swagger.io/specification/#operation-object)
7678
The generator generates stubbed partial classes for any operation handlers (`Foo.Bar.Operation.Handler.cs`) if there are none existing in the project and logs it with a compiler warning (AF1001). The classes should be copied into source control and the operation methods implemented. The operation methods have a familiar request/response design:

src/OpenAPI.WebApiGenerator/ApiGenerator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ private static void GenerateCode(SourceProductionContext context, (
141141
{
142142
var contentGenerators = body.GetContent().Select(pair =>
143143
{
144-
var requestBodyContent = pair.Value;
145-
var schemaReference = openApiOperationVisitor.GetSchemaReference(requestBodyContent);
144+
var mediaType = pair.Value;
145+
var schemaReference = openApiOperationVisitor.GetSchemaReference(mediaType);
146146
var typeDeclaration = schemaGenerator.Generate(schemaReference);
147147
return new RequestBodyContentGenerator(
148148
pair.Key,

src/OpenAPI.WebApiGenerator/CodeGeneration/SchemaGenerator.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ internal static SchemaGenerator For(
3838
Corvus.Json.CodeGeneration.OpenApi30.VocabularyAnalyser.DefaultVocabulary,
3939
OpenApiSpecVersion.OpenApi3_1 =>
4040
Corvus.Json.CodeGeneration.Draft202012.VocabularyAnalyser.DefaultVocabulary,
41+
OpenApiSpecVersion.OpenApi3_2 =>
42+
Corvus.Json.CodeGeneration.Draft202012.VocabularyAnalyser.DefaultVocabulary,
4143
_ => throw new InvalidOperationException($"OpenAPI specification {openApiSpecVersion} is not supported")
4244
};
4345
var globalOptions =

src/OpenAPI.WebApiGenerator/OpenAPI.WebApiGenerator.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5959
</PackageReference>
6060
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.14.0" PrivateAssets="all" />
61-
<PackageReference Include="Microsoft.OpenApi" Version="2.3.0" OutputItemType="Analyzer" PrivateAssets="all" GeneratePathProperty="true" />
61+
<PackageReference Include="Microsoft.OpenApi" Version="3.1.3" OutputItemType="Analyzer" PrivateAssets="all" GeneratePathProperty="true" />
6262
<PackageReference Include="Nullable" Version="1.3.1">
6363
<PrivateAssets>all</PrivateAssets>
6464
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>

src/OpenAPI.WebApiGenerator/OpenApi/OpenApiRequestBodyExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ namespace OpenAPI.WebApiGenerator.OpenApi;
66

77
internal static class OpenApiRequestBodyExtensions
88
{
9-
internal static IDictionary<string, OpenApiMediaType> GetContent(this IOpenApiRequestBody requestBody) =>
9+
internal static IDictionary<string, IOpenApiMediaType> GetContent(this IOpenApiRequestBody requestBody) =>
1010
requestBody.Content ?? throw new NullReferenceException("Request body content is required");
1111
}

src/OpenAPI.WebApiGenerator/OpenApi/OpenApiVersionExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ internal static class OpenApiVersionExtensions
1212
OpenApiSpecVersion.OpenApi2_0 => "2.0",
1313
OpenApiSpecVersion.OpenApi3_0 => "3.0",
1414
OpenApiSpecVersion.OpenApi3_1 => "3.1",
15+
OpenApiSpecVersion.OpenApi3_2 => "3.2",
1516
_ => throw new NotSupportedException($"OpenAPI version {Enum.GetName(typeof(OpenApiSpecVersion), version)} not supported")
1617
};
1718

1819
internal static Action<IOpenApiWriter> GetSerializer(this IOpenApiSerializable parameter, OpenApiSpecVersion version) => version switch
1920
{
21+
OpenApiSpecVersion.OpenApi3_2 => parameter.SerializeAsV32,
2022
OpenApiSpecVersion.OpenApi3_1 => parameter.SerializeAsV31,
2123
OpenApiSpecVersion.OpenApi3_0 => parameter.SerializeAsV3,
2224
OpenApiSpecVersion.OpenApi2_0 => parameter.SerializeAsV2,

src/OpenAPI.WebApiGenerator/OpenApi/Visitor/IOpenApiOperationVisitor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ namespace OpenAPI.WebApiGenerator.OpenApi.Visitor;
66
internal interface IOpenApiOperationVisitor : IVisitor
77
{
88
public JsonReference GetSchemaReference(IOpenApiParameter parameter);
9-
public JsonReference GetSchemaReference(OpenApiMediaType requestBodyContent);
9+
public JsonReference GetSchemaReference(IOpenApiMediaType requestBodyContent);
1010
public IOpenApiResponseVisitor Visit(IOpenApiResponse response);
1111
}

src/OpenAPI.WebApiGenerator/OpenApi/Visitor/IOpenApiResponseVisitor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace OpenAPI.WebApiGenerator.OpenApi.Visitor;
55

66
internal interface IOpenApiResponseVisitor
77
{
8-
public JsonReference GetSchemaReference(OpenApiMediaType mediaType);
9-
public bool HasContent(OpenApiMediaType mediaType);
8+
public JsonReference GetSchemaReference(IOpenApiMediaType mediaType);
9+
public bool HasContent(IOpenApiMediaType mediaType);
1010
public JsonReference GetSchemaReference(IOpenApiHeader header);
1111
}

0 commit comments

Comments
 (0)