Difference between swaggers (Controllers vs Minimal API)
felipementel opened this issue · 18 comments
Summary
I did a .NET 8 WebAPI to study and to publish on my Youtube Channel. During the development, I wish to go beyond of default development and create 2 API at the same project. One using Controllers and other using MinimalAPI and I can note that exists big differences on swagger about this two development approach
Motivation and goals
Do not exists compatibility between swagger generate by WebAPI using controllers and Minimal API. Beyond this, the function to JsonStringEnumConverter inside JsonSerializerOptions.Converters (you can verify this at "components/schemas/PELAGEM" on both swaggers
The implement at DEPLOY.Cachorro.Api
builder.Services.AddControllers()
.AddJsonOptions(opt =>
{
opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
opt.JsonSerializerOptions.WriteIndented = true;
opt.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
opt.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
The implement at DEPLOY.Cachorro.MinimalApi
builder.Services.ConfigureHttpJsonOptions(opt =>
{
opt.SerializerOptions.Converters.Add(new JsonStringEnumConverter());
opt.SerializerOptions.WriteIndented = true;
opt.SerializerOptions.PropertyNameCaseInsensitive = true;
opt.SerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
});
In scope
Do not exists compatibility between swagger generate by WebAPI using controllers and Minimal API.
Function to JsonStringEnumConverter inside JsonSerializerOptions.Converters.
Out of scope
..
Risks / unknowns
Compatibility
Examples
Repo project: https://github.com/felipementel/DEPLOY.Cachorro.Api
Simple exemple of 2 projects:
search about the text "<--HERE" to verify points that I´m talking about.
Project: DEPLOY.Cachorro.Api
"/api/v1/adocoes/cachorro/{cachorroid}/tutor/{tutorid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Adotar um Cachorro",
"description": "Operação para um tutor adotar um cachorro",
"operationId": "adotar-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "tutorid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error" <--Here
},
"500": {
"description": "Server Error" <--Here
}
}
}
},
Project: DEPLOY.Cachorro.MinimalApi
"/api/v1/adocoes/cachorro/{cachorroid}/tutor/{tutorid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Adotar um Cachorro",
"description": "Operação para um tutor adotar um cachorro",
"operationId": "adotar-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "tutorid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity" <--Here
},
"500": {
"description": "Internal Server Error" <--Here
}
}
}
}
Bellow, the full swagger of:
Swagger from DEPLOY.Cachorro.Api Project
{
"openapi": "3.0.1",
"info": {
"title": "Cachorro WebAPI .NET 8",
"description": "API de Cachorro do Canal DEPLOY com OpenAPI, Swashbuckle, e API versioning.",
"contact": {
"name": "Felipe Augusto",
"email": "admin@felipementel.dev.br"
},
"version": "1.0"
},
"paths": {
"/api/v1/adocoes/cachorro/{cachorroid}/tutor/{tutorid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Adotar um Cachorro",
"description": "Operação para um tutor adotar um cachorro",
"operationId": "adotar-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "tutorid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/adocoes/cachorro/{cachorroid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Devolver um cachorro que estava adotado",
"description": "Operação para um tutor devolver um cachorro",
"operationId": "devolver-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/cachorros": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Listar Cachorros",
"description": "Operação para listar de cachorros",
"operationId": "listall-cachorros-get",
"responses": {
"200": {
"description": "Success"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Server Error"
}
}
},
"post": {
"tags": [
"Cachorros"
],
"summary": "Cadastrar Cachorro",
"description": "Operação para cadastrar cachorro",
"operationId": "create-cachorros-post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CachorroCreateDto"
}
}
}
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/cachorros/{id}": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Obter Cachorro",
"description": "Operação para obter cachorro por id",
"operationId": "getbyid-cachorros-get",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"200": {
"description": "Success"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Server Error"
}
}
},
"put": {
"tags": [
"Cachorros"
],
"summary": "Atualizar Cachorro",
"description": "Operação para atualizar de cachorro",
"operationId": "update-cachorros-put",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CachorroDto"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error"
},
"500": {
"description": "Server Error"
}
}
},
"delete": {
"tags": [
"Cachorros"
],
"summary": "Excluir Cachorro",
"description": "Operação para excluir cachorro",
"operationId": "delete-cachorros-delete",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/cachorros/adotados": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Lista de cachorro adotados",
"description": "Operação para listar de cachorros adotados",
"operationId": "listallcachorrosadotados-cachorros-get",
"responses": {
"200": {
"description": "Success"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/cachorros/para-adotar": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Lista de cachorro disponíveis para adoção",
"description": "Operação para listar de cachorros disponíveis para adoção",
"operationId": "listallcachorrosparaadocao-cachorros-get",
"responses": {
"200": {
"description": "Success"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Server Error"
}
}
}
},
"/ping": {
"get": {
"tags": [
"Ping"
],
"operationId": "get-ping-get",
"parameters": [
{
"name": "x-api-version",
"in": "header",
"description": "The requested API version",
"style": "simple",
"schema": {
"type": "string",
"default": "1.0"
}
}
],
"responses": {
"200": {
"description": "Success"
}
}
}
},
"/api/v1/tutores": {
"get": {
"tags": [
"Tutores"
],
"summary": "Listar Tutores",
"description": "Operação para listar tutores",
"operationId": "listall-tutores-get",
"responses": {
"200": {
"description": "Success"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Server Error"
}
}
},
"post": {
"tags": [
"Tutores"
],
"summary": "Cadastrar Tutor",
"description": "Operação para cadastrar tutor",
"operationId": "create-tutores-post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
}
}
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Client Error"
},
"500": {
"description": "Server Error"
}
}
}
},
"/api/v1/tutores/{id}": {
"get": {
"tags": [
"Tutores"
],
"summary": "Obter Tutor",
"description": "Operação para obter tutor por id",
"operationId": "getbyid-tutores-get",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"200": {
"description": "Success"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Server Error"
}
}
},
"put": {
"tags": [
"Tutores"
],
"summary": "Atualizar Tutor",
"description": "Operação para atualizar tutor",
"operationId": "update-tutores-put",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {
"application/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
},
"text/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
},
"application/*+json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
}
}
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized",
"content": {
"text/plain; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
},
"application/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
},
"text/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"422": {
"description": "Client Error",
"content": {
"text/plain; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
},
"application/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
},
"text/json; x-api-version=1.0": {
"schema": {
"$ref": "#/components/schemas/ProblemDetails"
}
}
}
},
"500": {
"description": "Server Error"
}
}
},
"delete": {
"tags": [
"Tutores"
],
"summary": "Delete Tutor",
"description": "Operação para deletar tutor por id",
"operationId": "delete-tutores-delete",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Server Error"
}
}
}
}
},
"components": {
"schemas": {
"CachorroCreateDto": {
"type": "object",
"properties": {
"nome": {
"type": "string",
"nullable": true
},
"nascimento": {
"type": "string",
"format": "date-time"
},
"pelagem": {
"$ref": "#/components/schemas/PELAGEM"
},
"peso": {
"type": "number",
"format": "float"
}
},
"additionalProperties": false
},
"CachorroDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"nome": {
"type": "string",
"nullable": true
},
"cadastro": {
"type": "string",
"format": "date-time"
},
"atualizacao": {
"type": "string",
"format": "date-time",
"nullable": true
},
"nascimento": {
"type": "string",
"format": "date-time"
},
"adotado": {
"type": "boolean"
},
"pelagem": {
"$ref": "#/components/schemas/PELAGEM"
},
"peso": {
"type": "number",
"format": "float"
},
"tutor": {
"$ref": "#/components/schemas/TutorDto"
}
},
"additionalProperties": false
},
"PELAGEM": { <--HERE
"enum": [
"None",
"Curto",
"Medio",
"Longo"
],
"type": "string"
},
"ProblemDetails": {
"type": "object",
"properties": {
"type": {
"type": "string",
"nullable": true
},
"title": {
"type": "string",
"nullable": true
},
"status": {
"type": "integer",
"format": "int32",
"nullable": true
},
"detail": {
"type": "string",
"nullable": true
},
"instance": {
"type": "string",
"nullable": true
}
},
"additionalProperties": {}
},
"TutorDto": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"nome": {
"type": "string",
"nullable": true
},
"cadastro": {
"type": "string",
"format": "date-time"
},
"atualizacao": {
"type": "string",
"format": "date-time",
"nullable": true
},
"cpf": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
}
},
"securitySchemes": {
"Bearer": {
"type": "apiKey",
"description": "Informe o token JWT com Bearer no formato: Bearer {token}",
"name": "Authorization",
"in": "header"
}
}
},
"security": [
{
"Bearer": []
}
]
}
Swagger from DEPLOY.Cachorro.MinimalApi Project
{
"openapi": "3.0.1",
"info": {
"title": "Cachorro WebAPI .NET 8",
"description": "MinimalAPI de Cachorro do Canal DEPLOY com OpenAPI, Swashbuckle, e API versioning.",
"contact": {
"name": "Felipe Augusto",
"email": "admin@felipementel.dev.br"
},
"version": "1.0"
},
"paths": {
"/api/v1/adocoes/cachorro/{cachorroid}/tutor/{tutorid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Adotar um Cachorro",
"description": "Operação para um tutor adotar um cachorro",
"operationId": "adotar-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "tutorid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/adocoes/cachorro/{cachorroid}": {
"post": {
"tags": [
"Adocoes"
],
"summary": "Devolver um cachorro que estava adotado",
"description": "Operação para um tutor devolver um cachorro",
"operationId": "devolver-adocoes-post",
"parameters": [
{
"name": "cachorroid",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/cachorros": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Listar Cachorros",
"description": "Operação para listar de cachorros",
"operationId": "listall-cachorros-get",
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"post": {
"tags": [
"Cachorros"
],
"summary": "Cadastrar Cachorro",
"description": "Operação para cadastrar cachorro",
"operationId": "create-cachorros-post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CachorroCreateDto"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/cachorros/{id}": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Obter Cachorro",
"description": "Operação para obter cachorro por id",
"operationId": "getbyid-cachorros-get",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"put": {
"tags": [
"Cachorros"
],
"summary": "Atualizar Cachorro",
"description": "Operação para atualizar de cachorro",
"operationId": "update-cachorros-put",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CachorroDto"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
},
"delete": {
"tags": [
"Cachorros"
],
"summary": "Excluir Cachorro",
"description": "Operação para excluir cachorro",
"operationId": "delete-cachorros-delete",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/cachorros/adotados": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Lista de cachorro adotados",
"description": "Operação para listar de cachorros adotados",
"operationId": "listallcachorrosadotados-cachorros-get",
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/cachorros/para-adotar": {
"get": {
"tags": [
"Cachorros"
],
"summary": "Lista de cachorro disponíveis para adoção",
"description": "Operação para listar de cachorros disponíveis para adoção",
"operationId": "listallcachorrosparaadocao-cachorros-get",
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/ping": {
"get": {
"tags": [
"Ping"
],
"operationId": "get-ping-get",
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/api/v1/tutores": {
"get": {
"tags": [
"Tutores"
],
"summary": "Listar Tutores",
"description": "Operação para listar de tutores",
"operationId": "listall-tutores-get",
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"500": {
"description": "Internal Server Error"
}
}
},
"post": {
"tags": [
"Tutores"
],
"summary": "Cadastrar Tutor",
"description": "Operação para cadastrar tutor",
"operationId": "create-tutores-post",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Created"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
}
},
"/api/v1/tutores/{id}": {
"get": {
"tags": [
"Tutores"
],
"summary": "Obter Tutor",
"description": "Operação para obter tutor por id",
"operationId": "getbyid-tutores-get",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
},
"put": {
"tags": [
"Tutores"
],
"summary": "Atualizar Tutor",
"description": "Operação para atualizar tutor",
"operationId": "update-tutores-put",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TutorDto"
}
}
},
"required": true
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"422": {
"description": "Unprocessable Entity"
},
"500": {
"description": "Internal Server Error"
}
}
},
"delete": {
"tags": [
"Tutores"
],
"summary": "Delete Tutor",
"description": "Operação para deletar tutor por id",
"operationId": "delete-tutores-delete",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"style": "simple",
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"requestBody": {
"content": {}
},
"responses": {
"204": {
"description": "No Content"
},
"401": {
"description": "Unauthorized"
},
"404": {
"description": "Not Found"
},
"500": {
"description": "Internal Server Error"
}
}
}
}
},
"components": {
"schemas": {
"CachorroCreateDto": {
"type": "object",
"properties": {
"nome": {
"type": "string",
"nullable": true
},
"nascimento": {
"type": "string",
"format": "date-time"
},
"pelagem": {
"$ref": "#/components/schemas/PELAGEM"
},
"peso": {
"type": "number",
"format": "float"
}
},
"additionalProperties": false
},
"CachorroDto": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"nome": {
"type": "string",
"nullable": true
},
"cadastro": {
"type": "string",
"format": "date-time"
},
"atualizacao": {
"type": "string",
"format": "date-time",
"nullable": true
},
"nascimento": {
"type": "string",
"format": "date-time"
},
"adotado": {
"type": "boolean"
},
"pelagem": {
"$ref": "#/components/schemas/PELAGEM"
},
"peso": {
"type": "number",
"format": "float"
},
"tutor": {
"$ref": "#/components/schemas/TutorDto"
}
},
"additionalProperties": false
},
"PELAGEM": { <--HERE
"enum": [
0,
1,
2,
3
],
"type": "integer",
"format": "int32"
},
"TutorDto": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"nome": {
"type": "string",
"nullable": true
},
"cadastro": {
"type": "string",
"format": "date-time"
},
"atualizacao": {
"type": "string",
"format": "date-time",
"nullable": true
},
"cpf": {
"type": "string",
"nullable": true
}
},
"additionalProperties": false
}
},
"securitySchemes": {
"Bearer": {
"type": "apiKey",
"description": "Informe o token JWT com Bearer no formato: Bearer {token}",
"name": "Authorization",
"in": "header"
}
}
},
"security": [
{
"Bearer": []
}
]
}
I made a comparison of the 2 swaggers using the website https://string.is/diff-compare to obtain the differences and create this issue.
To run the application, some components need to be configured (the dependencies are in the documentation on github in pt-br, but you can analyze the appsettings.json)
@felipementel Thanks for reporting this issue!
I took a look at the diff between the generated OpenAPI files and there's different explanations for each of the differences. Explanations where possible are below:
Differences in status code descriptions as seen below:
- "description": "Server Error"
+ "description": "Internal Server Error"
Can be explained by the fact that when you generate an OpenAPI operation for minimal APIs using WithOpenApi
we generate the response description by calling into the ReasonPhrase
API as seen below.
aspnetcore/src/OpenApi/src/Services/OpenApiGenerator.cs
Lines 219 to 220 in 8198eeb
For MVC, the codepath that gets invoked is in Swashbuckle's explicit mapping for reason phrases.
The additional requestBody
payloads you see in the minimal API issue is a known bug with Microsoft.OpenApi.
+ "requestBody": {
+ "content": {}
+ },
Adding an explicit package reference to the latest version of Microsoft.OpenApi
should fix this.
<PackageReference Include="Microsoft.OpenApi" Version="1.6.14" />
You'll see required: true
set on certain parameters because minimal APIs takes into account the lack of nullability annotations on an input as an indicator of requiredness.
FYI, the latest release of Swashbuckle.AspNetCore (6.6.1) depends on the latest release of Microsoft.OpenApi, and also recently changed the built-in status descriptions (the changes was made on Monday as it happens), so if you upgrade those two differences should disappear.
before update packages the problem is
"200": {
"description": "OK" (MinimalApi)
"description": "Success" (Controllers)
"422": {
"description": "Unprocessable Entity" (MinimalApi)
"description": "Client Error" (Controllers)
},
"500": {
"description": "Internal Server Error" (MinimalApi)
"description": "Server Error" (Controllers)
}
now the problem is:
"422": {
"description": "Unprocessable Entity" (MinimalApi)
"description": "Unprocessable Content" (Controllers)
},
So, how can we have the same description about the this http status?
====
your point: The additional requestBody payloads you see in the minimal API issue is a known bug with Microsoft.OpenApi.
Me: Ok! I will follow the next updates and verify it after update in my project.
====
your point: You'll see required: true set on certain parameters because minimal APIs takes into account the lack of nullability annotations on an input as an indicator of requiredness.
Me: OK!
How can we adjust this?
FYI @martincostello
To make 422 match, you'll need to explicitly override the description of one or the other to match the other one.
In Swashbuckle we used the names from RFC 9110.