Skip to content

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

Closed
@captainsafia

Description

@captainsafia

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.

Metadata

Metadata

Assignees

Labels

Priority:0Work that we can't release withoutfeature-openapiold-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions