smallrye-open-api icon indicating copy to clipboard operation
smallrye-open-api copied to clipboard

Take BeanValidation groups into account

Open t1 opened this issue 2 months ago • 1 comments

We want to use the BeanValidation Groups feature to validate the same parameter with different validators. E.g.:

@Path("/names")
public class Names {

    @POST
    public Name createName(@Valid @NotNull @ConvertGroup(to = CREATE.class) Name name) {return name;}

    @PATCH
    public Name updateName(@Valid @NotNull @ConvertGroup(to = UPDATE.class) Name name) {return name;}

    public record Name(
            @NotNull String first,
            @NotNull(groups = CREATE.class) @Null(groups = UPDATE.class) String last
    ) {}

    public interface UPDATE {}

    public interface CREATE {}
}

When creating a new Name, both first and last are required. But when updating, first is required, but last is not allowed (say, you are only allowed to change your first but not your last name). This works fine by using the @ConvertGroup annotation.

But in the generated OpenAPI document, only first turns up as required; validations with groups are simply ignored:

components:
  schemas:
    Name:
      type: object
      required:
      - first
      properties:
        first:
          type: string
        last:
          type: string

It would be nice to have two Name components instead: one suffixed with UPDATE, and one with CREATE:

components:
  schemas:
    Name-CREATE:
      type: object
      required:
      - first
      - last
      properties:
        first:
          type: string
        last:
          type: string
    Name-UPDATE:
      type: object
      required:
      - first
      properties:
        first:
          type: string
        last:
          type: string

Note: there could also be one without a suffix, but as that is never used, it could be removed.

If I'm not mistaken, there is no way in OpenAPI to specify the fact that last must be null on UPDATE, but that's an unrelated topic.

The only alternative I can see is to write those type variants by hand in Java, which I would do if things get much more complicated, but in many cases, this would be sufficient.

What do you think?

t1 avatar Oct 31 '25 14:10 t1