victools / jsonschema-generator

Java JSON Schema Generator – creating JSON Schema (Draft 6, Draft 7, Draft 2019-09, or Draft 2020-12) from Java classes
https://victools.github.io/jsonschema-generator
Apache License 2.0
393 stars 57 forks source link

Javax validations support list elements #6

Closed hleb-albau closed 5 years ago

hleb-albau commented 5 years ago

Hi, test below do not return constraint description for ListElement values.

    @Test
    public void test() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaxValidationModule module = new JavaxValidationModule();
        SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(objectMapper, OptionPreset.PLAIN_JSON)
                .with(module);
        SchemaGeneratorConfig config = configBuilder.build();
        SchemaGenerator generator = new SchemaGenerator(config);
        JsonNode jsonSchema = generator.generateSchema(RootForm.class);

        System.out.println(jsonSchema.toString());
    }

    private static class RootForm {
        @NotEmpty
        private String name;
        @Valid
        private ChildForm childForm;
    }

    private static class ChildForm {
        @Valid
        private List<ListElement> elements;
        @Min(2)
        private Integer count;
    }

    private static class ListElement {
        @NotNull
        private String value;
    }
CarstenWickner commented 5 years ago

Hi @hleb-albau,

the validations are picked up correctly. You don't see because the OptionPreset.PLAIN_JSON does not include the Option.NULLABLE_FIELDS_BY_DEFAULT, i.e. all fields are assumed to be not-nullable.

If you simply add this call: configBuilder.with(Option.NULLABLE_FIELDS_BY_DEFAULT) you will see the difference between the @NotNull private String value on the ListElement and the nullable childForm field on the RootForm. To make it a bit more obvious you can use another kind of validation on the ListElement's value, e.g. with the following adjusted example:

public class ListElementTest {

    @Test
    public void test() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaxValidationModule module = new JavaxValidationModule();
        SchemaGeneratorConfigBuilder configBuilder = new SchemaGeneratorConfigBuilder(objectMapper, OptionPreset.PLAIN_JSON)
                .with(module)
                .with(Option.NULLABLE_FIELDS_BY_DEFAULT);
        SchemaGeneratorConfig config = configBuilder.build();
        SchemaGenerator generator = new SchemaGenerator(config);
        JsonNode jsonSchema = generator.generateSchema(RootForm.class);

        System.out.println(jsonSchema.toString());
    }

    private static class RootForm {
        @NotEmpty
        private String name;
        @Valid
        private ChildForm childForm;
    }

    private static class ChildForm {
        @Valid
        private List<ListElement> elements;
        @Min(2)
        private Integer count;
    }

    private static class ListElement {
        @NotNull
        @Size(max = 100)
        private String value;
    }
}

You get this JSON Schema:

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "childForm": {
            "type": ["object", "null"],
            "properties": {
                "count": {
                    "type": ["integer", "null"],
                    "minimum": 2
                },
                "elements": {
                    "type": ["array", "null"],
                    "items": {
                        "type": "object",
                        "properties": {
                            "value": {
                                "type": "string",
                                "maxLength": 100
                            }
                        }
                    }
                }
            }
        },
        "name": {
            "type": "string",
            "minLength": 1
        }
    }
}

Looks correct to me.

hleb-albau commented 5 years ago

@CarstenWickner Oh, I see. Thanks for fast response!