From 96580afc242a5ee323e35d0a73c5e603a209b7de Mon Sep 17 00:00:00 2001 From: heqianwang <158102624+heqianwang@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:28:44 -0400 Subject: [PATCH] [IDP-1587] Use same Response code descriptions as Swashbuckle library (#21) --- .../HttpResultsStatusCodeTypeHelpers.cs | 70 ++++++++++++------- .../ExtractSchemaTypeResultFilter.cs | 9 ++- .../WebApi.OpenAPI.SystemTest/openapi-v1.yaml | 62 ++++++++-------- src/tests/expected-openapi-document.yaml | 62 ++++++++-------- 4 files changed, 113 insertions(+), 90 deletions(-) diff --git a/src/Shared/HttpResultsStatusCodeTypeHelpers.cs b/src/Shared/HttpResultsStatusCodeTypeHelpers.cs index debc7ba..63e8e75 100644 --- a/src/Shared/HttpResultsStatusCodeTypeHelpers.cs +++ b/src/Shared/HttpResultsStatusCodeTypeHelpers.cs @@ -2,33 +2,49 @@ internal static class HttpResultsStatusCodeTypeHelpers { public static Dictionary HttpResultTypeToStatusCodes { get; } = new() { - {"Microsoft.AspNetCore.Http.HttpResults.Ok", 200}, - {"Microsoft.AspNetCore.Http.HttpResults.Ok`1", 200}, - {"Microsoft.AspNetCore.Http.HttpResults.Created", 201}, - {"Microsoft.AspNetCore.Http.HttpResults.Created`1", 201}, - {"Microsoft.AspNetCore.Http.HttpResults.CreatedAtRoute", 201}, - {"Microsoft.AspNetCore.Http.HttpResults.CreatedAtRoute`1", 201}, - {"Microsoft.AspNetCore.Http.HttpResults.Accepted", 202}, - {"Microsoft.AspNetCore.Http.HttpResults.Accepted`1", 202}, - {"Microsoft.AspNetCore.Http.HttpResults.AcceptedAtRoute", 202}, - {"Microsoft.AspNetCore.Http.HttpResults.AcceptedAtRoute`1", 202}, - {"Microsoft.AspNetCore.Http.HttpResults.NoContent", 204}, - {"Microsoft.AspNetCore.Http.HttpResults.BadRequest", 400}, - {"Microsoft.AspNetCore.Http.HttpResults.BadRequest`1", 400}, - {"Microsoft.AspNetCore.Http.HttpResults.UnauthorizedHttpResult", 401}, - {"Workleap.Extensions.OpenAPI.TypedResult.Forbidden", 403}, - {"Workleap.Extensions.OpenAPI.TypedResult.Forbidden`1", 403}, - {"Microsoft.AspNetCore.Http.HttpResults.NotFound", 404}, - {"Microsoft.AspNetCore.Http.HttpResults.NotFound`1", 404}, - {"Microsoft.AspNetCore.Http.HttpResults.Conflict", 409}, - {"Microsoft.AspNetCore.Http.HttpResults.Conflict`1", 409}, - {"Microsoft.AspNetCore.Http.HttpResults.UnprocessableEntity", 422}, - {"Microsoft.AspNetCore.Http.HttpResults.UnprocessableEntity`1", 422}, + { "Microsoft.AspNetCore.Http.HttpResults.Ok", 200 }, + { "Microsoft.AspNetCore.Http.HttpResults.Ok`1", 200 }, + { "Microsoft.AspNetCore.Http.HttpResults.Created", 201 }, + { "Microsoft.AspNetCore.Http.HttpResults.Created`1", 201 }, + { "Microsoft.AspNetCore.Http.HttpResults.CreatedAtRoute", 201 }, + { "Microsoft.AspNetCore.Http.HttpResults.CreatedAtRoute`1", 201 }, + { "Microsoft.AspNetCore.Http.HttpResults.Accepted", 202 }, + { "Microsoft.AspNetCore.Http.HttpResults.Accepted`1", 202 }, + { "Microsoft.AspNetCore.Http.HttpResults.AcceptedAtRoute", 202 }, + { "Microsoft.AspNetCore.Http.HttpResults.AcceptedAtRoute`1", 202 }, + { "Microsoft.AspNetCore.Http.HttpResults.NoContent", 204 }, + { "Microsoft.AspNetCore.Http.HttpResults.BadRequest", 400 }, + { "Microsoft.AspNetCore.Http.HttpResults.BadRequest`1", 400 }, + { "Microsoft.AspNetCore.Http.HttpResults.UnauthorizedHttpResult", 401 }, + { "Workleap.Extensions.OpenAPI.TypedResult.Forbidden", 403 }, + { "Workleap.Extensions.OpenAPI.TypedResult.Forbidden`1", 403 }, + { "Microsoft.AspNetCore.Http.HttpResults.NotFound", 404 }, + { "Microsoft.AspNetCore.Http.HttpResults.NotFound`1", 404 }, + { "Microsoft.AspNetCore.Http.HttpResults.Conflict", 409 }, + { "Microsoft.AspNetCore.Http.HttpResults.Conflict`1", 409 }, + { "Microsoft.AspNetCore.Http.HttpResults.UnprocessableEntity", 422 }, + { "Microsoft.AspNetCore.Http.HttpResults.UnprocessableEntity`1", 422 }, // Will be Supported in .NET 9 - {"Microsoft.AspNetCore.Http.HttpResults.InternalServerError", 500}, - {"Microsoft.AspNetCore.Http.HttpResults.InternalServerError`1", 500}, + { "Microsoft.AspNetCore.Http.HttpResults.InternalServerError", 500 }, + { "Microsoft.AspNetCore.Http.HttpResults.InternalServerError`1", 500 }, // Workleap's definition of the InternalServerError type result for other .NET versions - {"Workleap.Extensions.OpenAPI.TypedResult.InternalServerError", 500}, - {"Workleap.Extensions.OpenAPI.TypedResult.InternalServerError`1", 500}, + { "Workleap.Extensions.OpenAPI.TypedResult.InternalServerError", 500 }, + { "Workleap.Extensions.OpenAPI.TypedResult.InternalServerError`1", 500 }, }; -} \ No newline at end of file + + // Using the same descriptions from the Swashbuckle library: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs + public static Dictionary StatusCodesToDescription { get; } = new() + { + { 200, "OK"}, + { 201, "Created" }, + { 202, "OK" }, + { 204, "Accepted" }, + { 400, "Bad Request" }, + { 401, "Unauthorized" }, + { 403, "Forbidden" }, + { 404, "Not Found" }, + { 409, "Conflict" }, + { 422, "Unprocessable Content" }, + { 500, "Internal Server Error" }, + }; +} diff --git a/src/Workleap.Extensions.OpenAPI/TypedResult/ExtractSchemaTypeResultFilter.cs b/src/Workleap.Extensions.OpenAPI/TypedResult/ExtractSchemaTypeResultFilter.cs index ff14d5c..5c639b9 100644 --- a/src/Workleap.Extensions.OpenAPI/TypedResult/ExtractSchemaTypeResultFilter.cs +++ b/src/Workleap.Extensions.OpenAPI/TypedResult/ExtractSchemaTypeResultFilter.cs @@ -34,7 +34,14 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) usesTypedResultsReturnType = true; var response = new OpenApiResponse(); - response.Description = responseMetadata.HttpCode.ToString(); + if (HttpResultsStatusCodeTypeHelpers.StatusCodesToDescription.TryGetValue(responseMetadata.HttpCode, out var description)) + { + response.Description = description; + } + else + { + response.Description = responseMetadata.HttpCode.ToString(); + } if (responseMetadata.SchemaType != null) { diff --git a/src/tests/WebApi.OpenAPI.SystemTest/openapi-v1.yaml b/src/tests/WebApi.OpenAPI.SystemTest/openapi-v1.yaml index 3cb94d3..c702a4a 100644 --- a/src/tests/WebApi.OpenAPI.SystemTest/openapi-v1.yaml +++ b/src/tests/WebApi.OpenAPI.SystemTest/openapi-v1.yaml @@ -136,7 +136,7 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: @@ -186,19 +186,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '400': - description: '400' + description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ProblemDetails' '404': - description: '404' + description: Not Found /withNoAnnotationForAcceptedAndUnprocessableResponseNoType: get: tags: @@ -213,15 +213,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '202': - description: '202' + description: OK '422': - description: '422' + description: Unprocessable Content /withNoAnnotationForAcceptedAndUnprocessableResponseWithType: get: tags: @@ -236,19 +236,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '202': - description: '202' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '422': - description: '422' + description: Unprocessable Content content: application/json: schema: @@ -267,15 +267,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '201': - description: '201' + description: Created '409': - description: '409' + description: Conflict /withNoAnnotationForCreatedAndConflictWithType: get: tags: @@ -290,19 +290,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '201': - description: '201' + description: Created content: application/json: schema: type: string '409': - description: '409' + description: Conflict content: application/json: schema: @@ -321,9 +321,9 @@ paths: format: int32 responses: '204': - description: '204' + description: Accepted '401': - description: '401' + description: Unauthorized /voidOk: get: tags: @@ -365,15 +365,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden '500': - description: '500' + description: Internal Server Error /withExceptionsWithType: get: tags: @@ -388,19 +388,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -419,19 +419,19 @@ paths: format: int32 responses: '201': - description: '201' + description: Created content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -464,19 +464,19 @@ paths: schema: type: string '201': - description: '201' + description: Created content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -487,7 +487,7 @@ paths: - TypedResultNoProduces responses: '200': - description: '200' + description: OK content: application/json: schema: diff --git a/src/tests/expected-openapi-document.yaml b/src/tests/expected-openapi-document.yaml index 3cb94d3..c702a4a 100644 --- a/src/tests/expected-openapi-document.yaml +++ b/src/tests/expected-openapi-document.yaml @@ -136,7 +136,7 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: @@ -186,19 +186,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '400': - description: '400' + description: Bad Request content: application/json: schema: $ref: '#/components/schemas/ProblemDetails' '404': - description: '404' + description: Not Found /withNoAnnotationForAcceptedAndUnprocessableResponseNoType: get: tags: @@ -213,15 +213,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '202': - description: '202' + description: OK '422': - description: '422' + description: Unprocessable Content /withNoAnnotationForAcceptedAndUnprocessableResponseWithType: get: tags: @@ -236,19 +236,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '202': - description: '202' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '422': - description: '422' + description: Unprocessable Content content: application/json: schema: @@ -267,15 +267,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '201': - description: '201' + description: Created '409': - description: '409' + description: Conflict /withNoAnnotationForCreatedAndConflictWithType: get: tags: @@ -290,19 +290,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '201': - description: '201' + description: Created content: application/json: schema: type: string '409': - description: '409' + description: Conflict content: application/json: schema: @@ -321,9 +321,9 @@ paths: format: int32 responses: '204': - description: '204' + description: Accepted '401': - description: '401' + description: Unauthorized /voidOk: get: tags: @@ -365,15 +365,15 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden '500': - description: '500' + description: Internal Server Error /withExceptionsWithType: get: tags: @@ -388,19 +388,19 @@ paths: format: int32 responses: '200': - description: '200' + description: OK content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -419,19 +419,19 @@ paths: format: int32 responses: '201': - description: '201' + description: Created content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -464,19 +464,19 @@ paths: schema: type: string '201': - description: '201' + description: Created content: application/json: schema: $ref: '#/components/schemas/TypedResultExample' '403': - description: '403' + description: Forbidden content: application/json: schema: type: string '500': - description: '500' + description: Internal Server Error content: application/json: schema: @@ -487,7 +487,7 @@ paths: - TypedResultNoProduces responses: '200': - description: '200' + description: OK content: application/json: schema: