Skip to content

Validation annotation of ParameterObject property applied to PathVariable with the same name, even in unrelated endpoints #3270

Description

@cschierle

Describe the bug

When the name of a property in a class used as @ParameterObject and the name of a @PathVariable collide (e.g. both named name), the @Pattern validation annotation of the parameter object's property name is applied to the name @PathVariable instead. This even spreads across unrelated controller classes also defining a path variable name.

To Reproduce
Steps to reproduce the behavior:
Created a fresh project with Spring initializer using

  • Kotlin version 2.3.20
  • SpringBoot version 4.0.5
  • Gradle version 9.4.1
  • springdoc-openapi-gradle-plugin version 1.9.0

SomeController defines two endpoints:

  • GET /somethings without any parameters
  • GET /somethings/{name}/names with a path variable name and a @ParameterObject that contains a property name with some regex validation declared via @Pattern

OtherController defines three endpoints:

  • GET /others without any parameters
  • GET /others/{name} with only the path variable name
  • GET /others/{name}/names with only the path variable name

Erroneous Result (shortened):

The regex pattern validation is applied to ALL name path variables in the generated OpenApi specification:

{
  "/somethings/{name}/names": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9]+$"
          }
        }
      ]
    }
  },
  "/others/{name}": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9]+$"
          }
        }
      ]
    }
  },
  "/others/{name}/members": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9]+$"
          }
        }
      ]
    }
  }
}

Sample Code

I provided the setup described above in this repository: https://github.com/cschierle/pattern-validation-demo

Expected behavior

ONLY the request parameter name of the endpoint GET /somethings/{name}/names should be validated with the regex pattern declared via @Pattern in the @ParameterObject. Endpoints from other controllers should be unaffected.

{
  "/somethings/{name}/names": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "query",
          "required": false,
          "schema": {
            "type": "string",
            "pattern": "^[a-zA-Z0-9]+$"
          }
        }
      ]
    }
  },
  "/others/{name}": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    }
  },
  "/others/{name}/members": {
    "get": {
      "parameters": [
        {
          "name": "name",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    }
  }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions