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
398 stars 58 forks source link

If the class object is not annotated with @valid, I think no constraints should be generated. #471

Open hhtqaq opened 2 months ago

hhtqaq commented 2 months ago
    static class ValidClass {
        @NotNull
        private InlineClass inlineClass;
    }

    static class InlineClass {
        @NotBlank(message = "aaa must not be blank")
        private String aaa;
    }

i think result should be :

  {
  "$schema" : "https://json-schema.org/draft/2019-09/schema",
  "type" : "object",
  "properties" : {
    "inlineClass" : {
      "type" : "object",
      "properties" : {
        "aaa" : {
          "type" : "string"
        }
      }
    }
  },
  "required" : [ "inlineClass" ]
}

however currently it is

{
  "$schema" : "https://json-schema.org/draft/2019-09/schema",
  "type" : "object",
  "properties" : {
    "inlineClass" : {
      "type" : "object",
      "properties" : {
        "aaa" : {
          "type" : "string"
        }
      },
      "required" : [ "aaa" ]
    }
  },
  "required" : [ "inlineClass" ]
}

I think that when I add @Valid to inlineClass, it should be displayed like this, otherwise it will not comply with the constraints of the spring framework.

Or is there any extension I can modify it with?

CarstenWickner commented 2 months ago

Hi @hhtqaq,

The only difference I see in your example is that @NotBlank also results in the aaa property being marked as required. That seems correct to me.

What exactly is it you want to fix then?

For further help (if required), it'd be good to include your schema generator's configuration as reference.

hhtqaq commented 2 months ago

hi! @CarstenWickner ,

I generated automated use cases based on the generated json schema. In this case, it will not work as I expected.

At first I thought it was right, but I found that the spring framework does not do this. If the @valid annotation is not added to the attribute, like the inlineClass in my example, it will not verify the aaa property.

What should I do to solve this problem?

here is my schema generator's configuration

@Test
    public void testIntegration() throws Exception {
        // active all optional modules
        JavaxValidationModule module = new JavaxValidationModule(
                JavaxValidationOption.NOT_NULLABLE_FIELD_IS_REQUIRED,
                JavaxValidationOption.NOT_NULLABLE_METHOD_IS_REQUIRED,
                JavaxValidationOption.INCLUDE_PATTERN_EXPRESSIONS);
        SchemaGeneratorConfig config = new SchemaGeneratorConfigBuilder(SchemaVersion.DRAFT_2019_09, OptionPreset.PLAIN_JSON)
                .with(Option.NULLABLE_ARRAY_ITEMS_ALLOWED)
                .with(module)
                .build();
        SchemaGenerator generator = new SchemaGenerator(config);
        JsonNode result = generator.generateSchema(ValidClass.class);
        System.out.println(result.toPrettyString());
    }
CarstenWickner commented 2 months ago

I would question the reason for the @Valid annotation being skipped while there is still @NotBlank inside. Isn't that possibly confusing? Someone looking at the inner type assumes aaa is always present and not blank, but in reality that validation is not enforced.

If you add @Valid it will be fine. If you remove @NotBlank it will be fine. While technically possible (although not trivial), ignoring the validation annotations while generating the schema if no @Valid is present seems like a fix on the wrong end. Is that really what you want?

hhtqaq commented 2 months ago

@CarstenWickner You are right. But I think there may be a situation where a class needs to be verified as an input parameter, but when it is used as an attribute, it does not need to be verified. At this time, I only need to not add the @valid annotation, and there is no need to write a duplicate class?

CarstenWickner commented 2 months ago

You are correct, that's one way to leverage this feature. But isn't the assumption still that the object is valid even if the validation is skipped?

As I mentioned above: there are roundabout ways to achieve what you're describing, it just gets awkward when the same sub-schema is referenced in multiple places: once with @Valid and once without. It won't be pretty and I don't know when I will get to it. Not before next week I reckon.

hhtqaq commented 2 months ago

okkya! thanks! i need this feature

CarstenWickner commented 1 month ago

I've tried a few things now, but so far, I only found a way that cannot handle circular references.

Unfortunately, a missing @Valid annotation skips the whole subtree, which makes this messy to keep track of, when normally the schema for each type only gets generated once, but here we may need two flavors of each: with and without nested validations.

I have to drop this for the time being, but are open for any suggestions or PR on this topic.