Skip to content

Support custom Spring type converters #1534

Closed
@florensie

Description

@florensie

Is your feature request related to a problem? Please describe.
Custom Spring type converters can be added as such:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new UserConverter());
    }
}
public class UserConverter implements Converter<String, User> {

    @Override
    public User convert(String userId) {
        // Fetch from repository
        User user = new User();
        user.setId(userId);
        return user;
    }
}

With the above configuration, and the following controller:

@Log4j2
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/{userId}")
    public ResponseEntity<Void> doSomething(@PathVariable("userId") User user) {
        LOGGER.info("user = " + user);
        return ResponseEntity.ok().build();
    }
}

We get this openapi output:

{
  "openapi": "3.0.1",
  "info": {
    "title": "OpenAPI definition",
    "version": "v0"
  },
  "servers": [
    {
      "url": "http://localhost:8080",
      "description": "Generated server url"
    }
  ],
  "paths": {
    "/user/{userId}": {
      "get": {
        "tags": [
          "user-controller"
        ],
        "operationId": "doSomething",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/User"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          }
        }
      }
    }
  }
}

As you can see, the userId parameter is a ref to User, while in reality, we expect a string in this API.

Describe the solution you'd like
Springdoc could get the list for all active type converters, and base the schema off of the source type instead of the resulting type.

This is the expected openapi definition:

{
  "openapi": "3.0.1",
  "info": {
    "title": "OpenAPI definition",
    "version": "v0"
  },
  "servers": [
    {
      "url": "http://localhost:8080",
      "description": "Generated server url"
    }
  ],
  "paths": {
    "/user/{userId}": {
      "get": {
        "tags": [
          "user-controller"
        ],
        "operationId": "doSomething",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {}
}

Describe alternatives you've considered
I haven't looked into it much but I think a custom ModelConverter might be able to provide a temporary workaround.

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions