corvus-dotnet / Corvus.JsonSchema

Support for Json Schema validation and entity generation
Apache License 2.0
111 stars 8 forks source link

How to specify root path for JSON Schema without "$defs" #436

Closed Sidonivs closed 1 month ago

Sidonivs commented 1 month ago

Hello, I like this generator and want to use it in my project, but I have trouble with specifying the root path option.

I created my JSON Schema according to the official guide so now it looks like this (shortened):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "/configurations/schemas/SchedulerConfigurationSchema-sample.json",
  "title": "SchedulerConfiguration",
  "description": "The configuration for the scheduler.",
  "type": "object",
  "properties": {
    "Algorithms": {
      "description": "The definitions of the algorithms.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "Id": {
            "description": "The unique identifier for the algorithm.",
            "type": "integer"
          },
          "Name": {
            "description": "The name of the algorithm.",
            "type": "string"
          }
        },
        "required": [ "Id", "Name" ]
      }
    },
    "Tasks": {
      "description": "The definitions of the first tasks.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "AlgorithmId": {
            "description": "ID of the algorithm to execute with the task.",
            "type": "integer"
          }
        },
        "required": ["AlgorithmId" ]
      }
    },
    "required": [ "Algorithms" ]
  }
}

I couldn't find what to set the --rootPath when I want to generate a C# file called SchedulerConfiguration containing the arrays of Algorithms and Tasks. If I just leave --rootPath empty I get this error:

Expected to find a valid schema island at C:/Users/.../schema.json
Sidonivs commented 1 month ago

UPDATE:

So I tried changing my schema like this:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "/configurations/schemas/SchedulerConfigurationSchema-sample.json",
  "$defs": {
    "SchedulerConfiguration": {
      "description": "The configuration for the scheduler.",
      "type": "object",
      "properties": {
        "Algorithms": {

(rest is the same) Now calling with --rootPath '#/$defs/SchedulerConfiguration', but getting the exact same error:

Expected to find a valid schema island at C:/Users/.../schema.json
dalyIsaac commented 1 month ago

I was able to generate code using the following schema without specifying the --rootPath:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "/configurations/schemas/SchedulerConfigurationSchema-sample.json",
  "title": "SchedulerConfiguration",
  "description": "The configuration for the scheduler.",
  "type": "object",
  "properties": {
    "Algorithms": {
      "description": "The definitions of the algorithms.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "Id": {
            "description": "The unique identifier for the algorithm.",
            "type": "integer"
          },
          "Name": {
            "description": "The name of the algorithm.",
            "type": "string"
          }
        },
        "required": [ "Id", "Name" ]
      }
    },
    "Tasks": {
      "description": "The definitions of the first tasks.",
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "AlgorithmId": {
            "description": "ID of the algorithm to execute with the task.",
            "type": "integer"
          }
        },
        "required": ["AlgorithmId" ]
      }
-    },
-    "required": [ "Algorithms" ]
-  }
+  },
+  "required": [ "Algorithms" ]
}

It looks like to me that the last required field should belong to the root object, not the properties object.

(I'm not associated with this project - I just came across this issue).

Sidonivs commented 1 month ago

@dalyIsaac Thank you, you are right! I don't know why the validator in VS didn't find this error, I mistakenly expected it to be a valid JSON Schema. I am still getting an error when I try to generate without using $defs (but it's a different one now):

Unable to find the schema at C:/Users/.../schema.json#/properties/Algorithms

But if I use $defs in my schema like in my previous comment, it works. However, a weird thing for me is, that it generates different C# files when I add the --rootPath '#/$defs/SchedulerConfiguration' option and when I don't add it.

mwadams commented 1 month ago

In the case where you explicitly generate individual types, they are generated in the root namespace. If you generate them because they come along as sub-schema of the actual root schema, they are generated as subtypes of the parent schema (our standard approach to safely scoping/naming inline subschema).

According to the JSON Schema spec, the behaviour of tooling when pointing at schema islands like that (rather than root) is undefined. We do support it, as you can see, but it is "buyer beware". 😀

mwadams commented 1 month ago

BTW: @Sidonivs - which version of the TypeGenerator tool are you using?