-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PHAIN-133: Generate OpenAPI schema via CLI
This change adds a `make generate-openapi-spec` command to generate an OpenAPI schema JSON file. We have been using this process within the PHA API for some time. To avoid needing to create a bunch of stub config and other misdirections during the application startup, a new startup specifically for Swagger has been added which instantiates just enough for Swagger to be able to generate the document.
- Loading branch information
Showing
14 changed files
with
249 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -352,3 +352,4 @@ fabric.properties | |
|
||
report.csv | ||
Btms.Backend/*.zip | ||
openapi.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
using Microsoft.OpenApi.Models; | ||
using Swashbuckle.AspNetCore.SwaggerGen; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public class DocumentFilter : IDocumentFilter | ||
{ | ||
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) | ||
{ | ||
context.SchemaGenerator.GenerateSchema( | ||
typeof(NotificationResourceResponse), | ||
context.SchemaRepository | ||
); | ||
|
||
swaggerDoc.AddPath( | ||
path: "import-notifications", | ||
pathDescription: "Notification Operations", | ||
operationDescription: "Get Notifications", | ||
referenceId: "NotificationResourceResponse", | ||
tag: "Notifications" | ||
); | ||
|
||
context.SchemaGenerator.GenerateSchema( | ||
typeof(MovementResourceResponse), | ||
context.SchemaRepository | ||
); | ||
|
||
swaggerDoc.AddPath( | ||
path: "movements", | ||
pathDescription: "Movement Operations", | ||
operationDescription: "Get Movements", | ||
referenceId: "MovementResourceResponse", | ||
tag: "Movements" | ||
); | ||
|
||
context.SchemaGenerator.GenerateSchema( | ||
typeof(GoodsMovementResourceResponse), | ||
context.SchemaRepository | ||
); | ||
|
||
swaggerDoc.AddPath( | ||
path: "goods-movements", | ||
pathDescription: "Goods Movement Operations", | ||
operationDescription: "Get Goods Movements", | ||
referenceId: "GoodsMovementResourceResponse", | ||
tag: "GoodsMovements" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using Btms.Model.Gvms; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public class GoodsMovementResourceResponse : ResourceResponse<Gmr>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using Btms.Model; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public class MovementResourceResponse : ResourceResponse<Movement>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
using Btms.Model.Ipaffs; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public class NotificationResourceResponse : ResourceResponse<ImportNotification>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
using Microsoft.OpenApi.Models; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public static class OpenApiDocumentExtensions | ||
{ | ||
public static void AddPath( | ||
this OpenApiDocument swaggerDoc, | ||
string path, | ||
string pathDescription, | ||
string operationDescription, | ||
string referenceId, | ||
string tag | ||
) | ||
{ | ||
swaggerDoc.Paths.Add( | ||
path, | ||
new OpenApiPathItem | ||
{ | ||
Description = pathDescription, | ||
Operations = new Dictionary<OperationType, OpenApiOperation> | ||
{ | ||
{ | ||
OperationType.Get, | ||
new OpenApiOperation | ||
{ | ||
Description = operationDescription, | ||
Responses = new OpenApiResponses | ||
{ | ||
{ | ||
"200", | ||
new OpenApiResponse | ||
{ | ||
Description = "Success", | ||
Content = new Dictionary<string, OpenApiMediaType> | ||
{ | ||
{ | ||
"application/json", | ||
new OpenApiMediaType | ||
{ | ||
Schema = new OpenApiSchema | ||
{ | ||
Reference = new OpenApiReference | ||
{ | ||
Id = referenceId, | ||
Type = ReferenceType.Schema, | ||
}, | ||
}, | ||
} | ||
}, | ||
}, | ||
} | ||
}, | ||
}, | ||
Tags = new List<OpenApiTag> { new() { Name = tag } }, | ||
} | ||
}, | ||
}, | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace Btms.Backend.OpenApi; | ||
|
||
public class ResourceResponse<T> | ||
{ | ||
public T? Data { get; set; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
using System.ComponentModel; | ||
using System.Reflection; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization; | ||
using Microsoft.OpenApi.Any; | ||
using Microsoft.OpenApi.Models; | ||
using MongoDB.Bson.Serialization.Attributes; | ||
using Swashbuckle.AspNetCore.SwaggerGen; | ||
|
||
namespace Btms.Backend.OpenApi; | ||
|
||
public class SchemaFilter : ISchemaFilter | ||
{ | ||
private readonly JsonNamingPolicy _namingPolicy = JsonNamingPolicy.CamelCase; | ||
|
||
public void Apply(OpenApiSchema schema, SchemaFilterContext context) | ||
{ | ||
if (IsBsonIgnoreField(schema, context)) | ||
return; | ||
|
||
foreach (var propertyInfo in context.Type.GetProperties()) | ||
{ | ||
if (HasBsonIgnoreAttribute(propertyInfo)) | ||
schema.Properties.Remove(GetPropertyName(propertyInfo)); | ||
} | ||
|
||
schema.Enum = GetEnums(context); | ||
} | ||
|
||
private static IList<IOpenApiAny> GetEnums(SchemaFilterContext context) | ||
{ | ||
var enumOpenApiStrings = new List<IOpenApiAny>(); | ||
if (!context.Type.IsEnum) return enumOpenApiStrings; | ||
|
||
enumOpenApiStrings.AddRange((from object? enumValue in Enum.GetValues(context.Type) select new OpenApiString(enumValue.ToString())).Cast<IOpenApiAny>()); | ||
|
||
return enumOpenApiStrings; | ||
} | ||
|
||
private string GetPropertyName(PropertyInfo propertyInfo) | ||
{ | ||
var jsonAttr = propertyInfo.GetCustomAttribute<JsonPropertyNameAttribute>(); | ||
return _namingPolicy.ConvertName(jsonAttr != null ? jsonAttr.Name : propertyInfo.Name); | ||
} | ||
private static bool HasBsonIgnoreAttribute(PropertyInfo propertyInfo) | ||
{ | ||
return propertyInfo.GetCustomAttribute(typeof(BsonIgnoreAttribute)) != null; | ||
} | ||
|
||
private static bool IsBsonIgnoreField(OpenApiSchema schema, SchemaFilterContext context) | ||
{ | ||
return schema.Properties == null || context.Type == null; | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using System.Reflection; | ||
using Btms.Backend.OpenApi; | ||
using Microsoft.OpenApi.Models; | ||
|
||
namespace Btms.Backend.Swagger; | ||
|
||
public static class SwaggerGen | ||
{ | ||
public static bool SwaggerGenEntrypoint(string[] args) | ||
{ | ||
if (Assembly.GetEntryAssembly()?.GetName().Name != "dotnet-swagger") return false; | ||
|
||
var builder = WebApplication.CreateBuilder(args); | ||
builder.Services.AddEndpointsApiExplorer(); | ||
builder.Services.AddSwaggerGen(c => | ||
{ | ||
c.SwaggerDoc("public-v0.1", new OpenApiInfo { Title = "BTMS Public API", Version = "v0.1" }); | ||
c.DocumentFilter<DocumentFilter>(); | ||
c.SchemaFilter<SchemaFilter>(); | ||
c.UseAllOfToExtendReferenceSchemas(); | ||
c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); | ||
}); | ||
|
||
var appForGen = builder.Build(); | ||
appForGen.UseSwagger(); | ||
appForGen.UseSwaggerUI(options => | ||
{ | ||
options.SwaggerEndpoint("/swagger/public-v0.1/swagger.json", "public"); | ||
}); | ||
|
||
appForGen.Run(); | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
dependencies: | ||
dotnet tool restore | ||
|
||
generate-openapi-spec: dependencies | ||
dotnet build -c Release --no-restore | ||
dotnet swagger tofile --output openapi.json ./Btms.Backend/bin/Release/net*/Btms.Backend.dll public-v0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"sdk": { | ||
"version": "8.0.405", | ||
"rollForward": "latestMinor" | ||
} | ||
} |