I'm using the Swashbuckle.AspNetCore.Filters.SwaggerResponseExampleAttribute
attribute to generate Swagger documentation that includes a single response example for a given HTTP status code, for a (.NET 6) ASP.NET Web API controller method, like so:
[SwaggerOperation(summary: "Delete all items in a cart.", description: "<p>BLAH BLAH BLAH.</p>")]
[SwaggerResponse(statusCode: 200, description: "<p>The API request was successfully processed; an object describing the empty shopping cart is returned.</p>", type: typeof(GetCartSummaryResponse)), SwaggerResponseExample(statusCode: 200, examplesProviderType: typeof(CartApi_DeleteAllItemsInCart_Http200ResponseExampleProvider))]
[SwaggerResponse(statusCode: 422, description: "The API request was unsuccessfully processed; one or more business requirements failed to be met as the request was processed.", type: typeof(ProblemDetails))]
[SwaggerResponseExample(statusCode: 422, examplesProviderType: typeof(CartApi_DeleteAllItemsInCart_Http422ResponseExampleProvider))]
[HttpPost("/cart/clear")]
[Consumes("application/json")]
[Produces("application/json")]
public ActionResult<GetCartSummaryResponse> DeleteAllItemsInCart()
{
throw new NotImplementedException();
}
Now I'd like to provide multiple examples of HTTP 422 response bodies that might be returned in the API response body, under specific conditions.
I'd planned on using my endpoint's examples:
section in the OpenAPI 3.x document to accomplish this, like so:
paths:
'/cart/clear':
post:
tags:
- CartApi
summary: Delete all items in a cart.
description: <p><i>BLAH BLAH BLAH.</i></p>
operationId: CartApi_DeleteAllItemsInCart
responses:
'200':
description: <p>The API request was successfully processed; an object describing the empty shopping cart is returned.</p>
content:
application/json:
schema:
$ref: '#/components/schemas/GetCartSummaryResponse'
example:
cartGuid: 0fa1ef5f-5395-4679-901d-fd6c941f3460
cartItems: []
'422':
description: The API request was unsuccessfully processed; some other problem happened.
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetails'
examples:
Shopping cart ID is null or whitespace:
value:
type: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422'
title: Shopping cart was not found.
status: 422
detail: Shopping cart ID is null, empty, blank, or whitespace.
Shopping cart ID not found:
value:
type: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422'
title: Shopping cart was not found.
status: 422
detail: Shopping cart ID was not found.
cartGuid: 0fa1ef5f-5395-4679-901d-fd6c941f3460
I've fairly certain the OpenAPI 3.x spec supports this feature -- see the "Multiple examples in response bodies:" section on the "Adding Examples" page. However, I can't figure out if Swashbuckle supports rendering the examples:
section in an OpenAPI 3.x document yet. And if it does already support it, I've had no luck figuring out what attributes to use / what the code to do this looks like.
Any help would be greatly appreciated -- thanks in advance!
@CodingMytra
commented on my OP & pointed me at an article that mentions how to use the Swashbuckle.AspNetCore.Filters
package's IMultipleExamplesProvider<T>
interface to generate the OpenAPI examples:
section for a given API endpoint & HTTP response code.
For the sake of completeness, here's my class that implements IMultipleExamplesProvider<T>
:
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Filters;
namespace api.Models.Responses.Examples._4xx;
public class CartApi_DeleteAllItemsInCart_Http422ResponseExamplesProvider : IMultipleExamplesProvider<ProblemDetails>
{
public IEnumerable<SwaggerExample<ProblemDetails>> GetExamples()
{
yield return SwaggerExample.Create(
name: "Shopping cart ID is invalid.",
value: new ProblemDetails {
Type = $@"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422",
Status = 422,
Title = "Shopping cart ID is invalid.",
Detail = "Shopping cart ID is null, empty, or whitespace, & cannot be used to access a shopping cart.",
Extensions = {{ "cartGuid", "BLAH_BLAH_BLAH" }}
}
);
yield return SwaggerExample.Create(
name: "Unable to access shopping cart.",
value: new ProblemDetails {
Type = $@"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422",
Status = 422,
Title = "Unable to access shopping cart.",
Detail = "Shopping cart ID is valid, but could not be used to access the shopping cart."
}
);
}
}
After that, I used the new pluralized CartApi_DeleteAllItemsInCart_Http422ResponseExamplesProvider
class in my [SwaggerResponseExample]
attribute & it generated the OpenAPI 3.x examples:
section the way I'd expected:
'422':
description: The API request was unsuccessfully processed; shopping cart ID was not found.
content:
application/json:
schema:
$ref: '#/components/schemas/ProblemDetails'
examples:
Shopping cart ID is invalid.:
value:
type: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422'
title: Shopping cart ID is invalid.
status: 422
detail: 'Shopping cart ID is null, empty, or whitespace, & cannot be used to access a shopping cart.'
cartGuid: 0fa1ef5f-5395-4679-901d-fd6c941f3460
Unable to access shopping cart.:
value:
type: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422'
title: Unable to access shopping cart.
status: 422
detail: 'Shopping cart ID is valid, but could not be used to access the shopping cart.'