Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Route constraints don't produce appropriate information in OpenAPI schema #36525

Closed
captainsafia opened this issue Sep 15, 2021 · 1 comment
Closed
Assignees
Labels
feature-openapi old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Priority:0 Work that we can't release without
Milestone

Comments

@captainsafia
Copy link
Member

Routes in ASP.NET Core apps support the following set of constraints on route parameters:

  • Type constraints
  • Range and length constraints
  • Regular expression constraints
  • Requiredness constraints

All of these constraints map to options that can be set in the OpenAPI schema for a particular parameter. For example, the following route template /foo/{bar:int:min(3)} should produce the following OpenAPI schema:

paths:
  /foo/{bar}:
    get:
      parameters:
        - in: path
          name: bar
          schema:
            type: integer
            minimum: 1
          required: true

To determine what constraints should be populated in the schema, Swashbuckle looks for data validation attributes on the parameters associated with each roue parameter as seen below.

https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/95cb4d370e08e54eb04cf14e7e6388ca974a686e/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/OpenApiSchemaExtensions.cs#L10-L32

The attributes that Swashbuckle looks through are derived from the ParameterInfo provided in the ApiParameterDescription object populated by the ApiExplorer.

For minimal APIs, this means that an endpoint like:

app.MapGet("/stringa/{value:minlength(8)}", (Func<string, string>)FromString);

will not produce the correct annotations. The same problem exists for controllers where a controller action like the one below:

[HttpPut("{id:range(5, 10)}", Name = "UpdateProduct")]
public void Update(int id, [FromBody, Required]Product product)
{
  ...
}

will produce an OpenAPI schema like the following:

"parameters": [
  {
    "name": "id",
    "in": "path",
    "description": "",
    "required": true,
    "schema": {
      "type": "integer",
      "format": "int32"
    },
    "example": 222
  }
],

when it should be producing a schema like the following:

"parameters": [
  {
    "name": "id",
    "in": "path",
    "description": "",
    "required": true,
    "schema": {
      "type": "integer",
      "format": "int32",
      "minimum": 5,
      "maximum": 10
    },
    "example": 222
  }
],

There is a workaround for this change which requires applying the matching data validation annotations to the parameters.

[HttpPut("{id:range(5, 10)}", Name = "UpdateProduct")]
public void Update([Range(5, 10)] int id, [FromBody, Required]Product product)
{
}

will produce the correct annotations.

"parameters": [
  {
    "name": "id",
    "in": "path",
    "description": "",
    "required": true,
    "schema": {
      "maximum": 10,
      "minimum": 5,
      "type": "integer",
      "format": "int32"
    },
    "example": 222
  }
],

The same problem exists for OpenAPI schemas generated using NSwag.

TL;DR:

  • Route constraints should be populated as constraints in the OpenAPI schema.
  • We should support methods outside of data validation annotations for setting constraints in the OpenAPI schema.
@captainsafia
Copy link
Member Author

This was already fixed in preview1.

@ghost ghost locked as resolved and limited conversation to collaborators Jun 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-openapi old-area-web-frameworks-do-not-use *DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels Priority:0 Work that we can't release without
Projects
None yet
Development

No branches or pull requests

2 participants