Closed m-wild closed 3 years ago
Wow, Saunter is now using NJS?
Wow, Saunter is now using NJS?
Yep, all the custom JSON schema generation code had been deleted and we are using NJsonSchema for all of the "Schema" types in the AsyncAPI document :)
@tehmantra I think the current schema generation config uses JSON Schema rules but actually AsyncAPI uses OpenApi3... (eg JSON Schema has different null handling than Open API ("type" array with "null" vs "nullable").
Do we need to introduce SchemaType = AsyncApi in NJsonSchema or can we just use OpenApi3 - assuming it is "always" in sync?
From https://www.asyncapi.com/docs/getting-started/coming-from-openapi
AsyncAPI is compatible with OpenAPI schemas.
@RicoSuter I'm not 100% sure... The specification indicates its a superset of JSON schema (https://www.asyncapi.com/docs/specifications/v2.1.0#schemaObject)
This object is a superset of the JSON Schema Specification Draft 07.
But it also says
Definition of the message payload. It can be of any type but defaults to Schema object. It must match the schema format, including encoding type - e.g Avro should be inlined as either a YAML or JSON object NOT a string to be parsed as YAML or JSON.
Message payload in AsyncAPI can be any value, not just an AsyncAPI/OpenAPI schema. For instance, it could be an Avro schema.
Perhaps I should ask the core team which is preferable between JSON Schema or OpenAPI Schema.
@darrelmiller can you answer this one? I thought that AsyncAPI schema is in sync with the OpenAPI one?
@RicoSuter I've also discovered an issue with using the SchemaType
and JsonReferenceConverter
together.
I was trying to do the following:
[JsonConverter(typeof(JsonReferenceConverter))]
public class AsyncApiDocument : ICloneable
{
// etc..
}
public string Serialize(AsyncApiDocument document)
{
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = JsonSchema.CreateJsonSerializerContractResolver(SchemaType.OpenApi3),
};
return JsonConvert.SerializeObject(document, serializerSettings);
}
But was always getting the properties as x-nullable
and x-example
!
Looks like the JsonReferenceConverter
does not fully respect the current JsonSerializerSettings
, only the Formatting
.
So we may need to change this line to something like
var json = JsonConvert.SerializeObject(value, new JsonSerializerSettings
{
ContractResolver = serializer.ContractResolver,
Formatting = serializer.Formatting,
// Maybe copy other properties here too?
});
Hi folks. AsyncAPI schema is a superset of JSON Schema Specification Draft 07, prior 3.1 OpenAPI was not actually in sync with JSON Schemas, in 3.1 I think they introduced an option to specify different JSON Schema dialect that you can use to provide payload schema.
In AsyncAPI the default schema is AsyncAPI Schema, so yeah, JSON Schema. But AsyncAPI also allows you to provide schemas in totally different formats, like OpenAPI Schema, RAML Data Types, Avro - you name it. So for example our parser is able to grab these custom schemas and parse them into JSON Schema (example https://github.com/asyncapi/avro-schema-parser). User needs to specify custom schema with schemaFormat
property.
I hope that helps. Lemme know if you need more help.
@derberg all this stuff makes me probably mentally ill :-) - I already have a big fight with all the edge cases, schema differences etc. over at OpenAPI...
General question: In AsyncAPI should we use a) { "type": ["null", "string"] }
or b) { "type": "string", "nullable": true }
to describe a nullable string?
@tehmantra created a PR with some suggestions: https://github.com/tehmantra/saunter/pull/113
@RicoSuter default AsyncAPI schema is superset of JSON Schema so { "type": ["null", "string"] }
is correct. Afaik { "type": "string", "nullable": true }
is what you do with OpenAPI 3.0, but with OpenAPI 3.1 you can do { "type": ["null", "string"] }
as since 3.1 they are compatible with JSON Schema.
now, what I wrote above is default 😉
as I mentioned, user can also share schemas in different formats, like for example user can have AsyncAPI file and OpenAPI 3.0 file and they can share common payload schemas following OpenAPI 3.0 schema. Example with nullable: true
asyncapi: 2.0.0
info:
title: Example with OpenAPI
version: 0.1.0
channels:
example:
publish:
message:
schemaFormat: 'application/vnd.oai.openapi;version=3.0.0'
payload: # The following is an OpenAPI schema
type: object
properties:
title:
type: string
nullable: true
author:
type: string
example: Jack Johnson
So while parsing such document you need to check the schemaFormat
and best convert OpenAPI 3.0 schema to pure JSON Schema. This is our JS parser for this use case -> https://github.com/asyncapi/openapi-schema-parser/
all this stuff makes me probably mentally ill :-)
how is your mental health now after my answer 😆
Fixes #60
Wow, this one has been a long time coming!
Thanks @JanEggers for all your help implementing this change 🙂 Also thanks to @RicoSuter for building and maintaing NJsonSchema, and for reaching out to suggest the idea.