Skip to content

Mapping to a custom domain object produces uncompilable code when combined with bean validations generated from openapi spec #290

@tedberg

Description

@tedberg

Given openapi.yaml:

  /movies/{movieId}:
    parameters:
      - $ref: '#/components/parameters/movieId'
 
...

components:
  parameters:
    movieId:
      name: movieId
      in: path
      description: Identifier of a movie
      required: true
      schema:
        type: string
        minLength: 5
        maxLength: 15
        pattern: someRegex expression

Generating normally works, producing an API with @Size, @Pattern and the String movieId parameter. Then add the mapping.yaml config to use a preexisting MovieId record from our domain that already contains validation:

openapi-processor-mapping: v13

...

map:
    paths:
        /movies/{movieId}:
          parameters:
            - name: movieId => com.example.domain.MovieId

Now the generated code swaps out the String movieId for a MovieId reference, but we cannot compile because @Pattern and @Size are not compatible with any class other than String (or CharacterSequence). If I go back to openapi.yaml and remove:

        minLength: 5
        maxLength: 15
        pattern: someRegex expression

Then it will generate and compile successfully. This is not great though as then I have worsened my contract, generated documentation and generated clients.

Proposed solutions:

  1. Add mapping options to remove annotations. Using syntax of:
map:
    paths:
        /movies/{movieId}:
          parameters:
            - name: movieId => com.example.domain.MovieId
            - drop: movieId @ Jakarta.validation.constraints.Size
            - drop: movieId @ Jakarta.validation.constraints.Pattern

We could tell the generator to build out an annotation removal list, which it could then use to omit these annotation instances.

  1. Store the bean validator annotation to type compatibility matrix in memory, consult this after resolving type mappings, before rendering out the code. When the type replacements produce an incompatible pairing, as with movieId, use this intelligence to omit generation of these bean validation annotations. Ideally, the mapping logs will detect this omission and log a warning that by contract, we are obligated to perform these validations and to be sure that our manual code achieves this.

  2. Best solution, add each of the above enhancements. The second one to automatically resolve generating invalid code and the first to allow for resolving any other edge case scenarios that occur.

For a test case, I'd refer to your medium article about mapping an integer to a year. If after type integer you simply add:

    type: integer
    format: year
    minimum: 1970
    maximum: 2099

This will fail with the same problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions