eclipse / microprofile-open-api

Microprofile open api
Apache License 2.0
131 stars 82 forks source link

MicroProfile Open API working with Bean Validation #482

Closed Emily-Jiang closed 2 years ago

Emily-Jiang commented 3 years ago

As part of the program plan 2021, the community would like to see some integration between Open API and Bean Validation. Please comment on this issue on what areas can Bean Validation help with MP Open API. What about schema validation?

MikeEdgar commented 3 years ago

The SmallRye implementation currently supports scanning Bean Validation annotations for schema information. Specifying that behavior in the MP spec would make sense if BV is part of the platform. When you say schema validation, do you mean validation of the final OpenAPI document generated by implementations?

Emily-Jiang commented 3 years ago

The SmallRye implementation currently supports scanning Bean Validation annotations for schema information. Specifying that behavior in the MP spec would make sense if BV is part of the platform.

MP platform is interested in pulling in BV to help with MP OpenAPI.

When you say schema validation, do you mean validation of the final OpenAPI document generated by implementations?

I am thinking about using Bean Validation annotations together with Schema annotation or other annotations. The generated schema can bear some info from Bean Validation such as the allowed value range, not null or something like that.

MikeEdgar commented 3 years ago

I am thinking about using Bean Validation annotations together with Schema annotation or other annotations. The generated schema can bear some info from Bean Validation such as the allowed value range, not null or something like that.

Ok, good. This is more or less what is being done in the SmallRye implementation here. A good starting point would likely be documenting that class's functionality in the spec and adding some relevant annotations to the TCK. What do you think?

Azquelt commented 2 years ago

I think it's reasonable to require support for the following annotations, when applied to an appropriate type:

Smallrye additionally has support for two more which I think we shouldn't require:

MikeEdgar commented 2 years ago
  • @Digits - Smallrye OpenAPI supports this by adding a pattern attribute to the schema, providing a regex which allows the given number of digits. However, JSON Schema Validation only allows pattern to be applied to strings and usually we would want to apply @Digits to number types.

I agree the standard should not require @Digits for numeric or primitive types. It is valid to use that annotation for CharSequences so perhaps the behavior could be specified in that case.

Azquelt commented 2 years ago

I agree the standard should not require @Digits for numeric or primitive types. It is valid to use that annotation for CharSequences so perhaps the behavior could be specified in that case.

This is true, though I would find it a little weird if it only works when you accept a number as a string.

Azquelt commented 2 years ago

Another wrinkle while reading the bean validation spec - although you might annotate an class with bean validation annotations, validation still needs to be enabled with the @Valid annotation at the point the class is used. This means the class might be expected to be valid in some places but not in others. It's also possible to select a different group of constraints to apply at each point the class is used.

For example you could have a user which has different fields populated during creation vs. when it's returned at other times:

public interface User {
    @NotBlank(groups = {Default.class, Creation.class})
    public String getUsername();
    @NotBlank(groups = Creation.class)
    public String getPassword();
    @Size(min = 12, max = 12)
    public String getId();
}

When you use it, you'd select a group:

@Path("/user")
public class Resource {

    @POST
    @Valid
    public User createUser(@Valid @ConvertGroup(to=Creation.class) User newUser) {
        return createUser(newUser);
    }

    @Path({id})
    @GET
    @Valid
    public User getUser(@Size(min = 12, max=12) @PathParam("id") String id) {
        return getUser(id);
    }
}

How should we handle this? Are we happy generating a single schema for User which has some subset of these constraints in it?

At the very least I assume we want to have some way of, at the code level, disabling the generation of schema based on bean validation annotations?

Azquelt commented 2 years ago

We've got the following options for allowing the user not to generate schema from bean validation annotations:

  1. Require that the user defines the schema manually, to override the schema from BV
  2. Have a separate annotation to disable schema generation from BV for a class or field (e.g. @SchemaFromBeanValidation(false)
  3. Don't generate schema from BV by default. Allow user to enable it with an annotation or option @SchemaFromBeanValidation.

Discussion on call 2022-05-09: