Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a method for generating JSON Schema from Ajv #1956

Open
OnkelTem opened this issue Apr 9, 2022 · 5 comments
Open

Add a method for generating JSON Schema from Ajv #1956

OnkelTem opened this issue Apr 9, 2022 · 5 comments

Comments

@OnkelTem
Copy link

OnkelTem commented Apr 9, 2022

While developing validation procedures for our data using Ajv we operate with the following things:

  • Schemas, created as either JSON Schema or as JSON Type Definition.
  • TypeScript types.

In an ideal world, only one of those should be the source of truth. Otherwise, we would have to maintain the same structure in two different formats. Yet that's exactly the case with JSON Schema schemas.

DRY is broken with JSON Schemas

In case of using JSON Schemas what we do is:

  1. First, we manually create a TypeScript type: type MyType = {...}
  2. Then we manually create the same declaration, but now as a JSON Schema: const myJSONSchema= {...}
  3. And only then we bind those two to get the input for Ajv: const mySchema: JSONSchemaType<MyData> = myJSONSchema;

Now we can use it with Ajv as:
const validate = ajv.compile(mySchema)

NOTE that this approach works only if myJSONSchema is getting initialized right in your JavaScript code. Be it a separate file, like my.schema.json, and we loose the grace of the Ajv's TypeScript integration.

Thus, using JSON Schemas is not the right way, as it basically doubles our work and makes us to support two things instead of just one.

DRY is OK with JTD

But luckily there is a second way, namely: creating schema as a JSON Type Definition (JTD). In this case:

  1. First, we manually create our schema as JTD (myJTDSchema) which becomes our single source of truth.
  2. And then we get our TypeScript type automatically: type MyType = JTDDataType<typeof myJTDSchema>

As we were importing Ajv from "ajv/dist/jtd", we can now use our JTD schema directly with Ajv as:
const validate = ajv.compile<MyType>(myJTDSchema);

...but no JSON Schema

Now that we have decided on the method, we're missing the JSON Schemas themselves. Yet we might really need them for sharing with other parts of our project or with tools like input validators (e.g. vscode-yaml VS Code extension).

I read the documentation and checked out other Ajv-related projects, but I haven't found a use case with JSON Schema being generated.

It is my understanding that once a Ajv-schema was created and compiled, there must be a way to export it into JSON Schema, as it seems to be a superset over JTD (but this may not be accurate).

Proposition

I propose to add a method for exporting JSON Schema out of compiled schema. Without this final stroke, the whole picture is falling apart, at least from my perspective. But I can be wrong, sorry for spending your time folks then.

What version of Ajv you are you using?

8.11.0

What problem do you want to solve?

Generate JSON Schemas from AJV compiled schema for example.

What do you think is the correct solution to problem?

Generate JSON Schema.

Will you be able to implement it?

No

@GabenGar
Copy link

The typescript types don't do anything at runtime and the fate of ESM JSON modules in typescript is uncertain as of now.
Typescript types are way too constrained to be the source of truth to everything, let alone describing schemas. The whole point of JSON schema is to be able to validate objects across even different languages. If anything the typescript types should be derivatives off the json schemas so you have to introduce codegen in your workflow for the typescript types.
This package, despite having some issues, allows to do just that.
Quicktype allows to get json schema out of several jsons, I wouldn't recommend using its codegen beyond that though, since it looks like it wasn't updated for a while. And not use it in CI, since schemas generated by it can be far from human-readable.

@Uzlopak
Copy link

Uzlopak commented Apr 13, 2022

Sounds more like you want a JTD to JSONSchema converter

@OnkelTem
Copy link
Author

Typescript types are way too constrained to be the source of truth to everything, let alone describing schemas. The whole point of JSON schema is to be able to validate objects across even different languages. If anything the typescript types should be derivatives off the json schemas so you have to introduce codegen in your workflow for the typescript types.

I'm not sure I follow. It is my understanding that JTD is a subset of what JSON Schema can provide in terms of validation. Isn't it possible to export it as JSON Schema?

This package, despite having some issues, allows to do just that.

I use precisely it right now. And with that I loose all Ajv power and have to use as assertions. And it's also rather out of date and it has issues as you say. For example, it doesn't support allOf so any object extensions just don't work.

@OnkelTem
Copy link
Author

Sounds more like you want a JTD to JSONSchema converter

Brilliant! You did it with just one sentence :)

@epoberezkin
Copy link
Member

JTD is a subset of what JSON Schema can provide in terms of validation.

It's not a subset, strictly speaking.

JTD to JSONSchema converter

It's out of scope for Ajv - it could be a separate package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants