-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Proposal to allow defining schema format other than default one (AsyncAPI Schema) #622
Comments
I like it. It is really a pain that you can only use AsyncAPI schema in components. Real pain for people using Avro and other formats.
I didn't really get this, how is this proposal solving this thing? It could be done with the current document structure too, right? Not sure if this is not adding unneeded complexity to the proposal, or I'm not getting something
just keep in mind this is still a spec-breaking change. Cool that on the parser side we won't complicate things |
@derberg Thanks for comment!
At the moment you can only define a custom format in the massage's payload. Instead of the components:
schemas:
schemaWithFormat:
schemaFormat: 'application/vnd.aai.asyncapi;version=2.1.0'
type: object
required:
- name
properties:
name:
type: string So it can only works with schema that can be written with JSON/YAML. The problem is with "string" (with own SDL) formats like GraphQL or Protobuf. You cannot make this (because you concatenate JSON/YAML field with string): components:
schemas:
schemaWithFormat: |
schemaFormat: ...protobuf
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
} I originally described this problem here -> #528 (comment) So as you can see, adding possibility to define schema with two ways, with and without
Yeah, it's a spec-breaking change but in
sentence I had in mind breaking-change on the parser side. |
Sorry but I still don't get how enabling support for GraphQL and Protobuf is better: payload:
schemaFormat: ...protobuf
schema: |
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
} vs schemaFormat: ...protobuf
payload:
schema: |
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
} just want to make sure it relates really to this proposal as the only way or it is actually doable already, and just a side effect, for clarity of the proposal |
Maybe I misspoke in my previous comments, but what I meant (in the GraphQL and Protobuf support) was that without separating the schema into components:
schemas:
schemaWithFormat: |
schemaFormat: ...protobuf # how to support it?
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
} In addition, for the current version we have the ability to use Protobuf and GraphQL, but only for the message's payload. My proposal allows you to use schemas where you want, of course in easier way. I will update relevant line about supporting string schemas to avoid misunderstandings. |
@magicmatatjahu now I got it, thanks for your patience. You were referring only explicitly again to schemas from Great proposal! I think this approach could also be suggested in question asked by Fran, on how to use |
@derberg No worries :) You had patience for me at previous job, I have patience for you now I updated description for Protobuf example.
Yeah, it's one of the solution, but I also gave another (as comment) to solve that problem in different way, probably easier :) |
@derberg I extended proposal to use references to nested non-JSON schema objects - please see |
@magicmatatjahu one question: In the example you wrote about retrieving a schema from avro using schemaRef: "com.intergral.example.avro.Toy" Wouldn't be: schemaRef: "com.intergral.example.avro.toys.Toy" Note the If it isnt, would you mind clarifying to me, please. Thank you! |
@smoya Thanks for your comment! I'll be honest, I don't know avro at all (I even gave a comment about it in proposal), but I found an example I used and it's there - https://www.nerd.vision/post/reusing-schema-definitions-in-avro Maybe your example is actually correct 🤷 We would need someone who knows avro :) Whether my example or yours is correct, doesn't matter, it seems to me that the idea with |
Yeah the idea is totally understood, but since I have no idea about avro neither I wanted to understand how the |
@magicmatatjahu , for clarity, could you walk through how this proposal would address the 4 XSD use cases in my comment in #624 |
@jessemenning Thanks for comment!
components:
messages:
UserSignedUp:
payload:
schemaParse: false
schema:
$ref: ./some_xsd.xsd
contentType: "application/xml" Here we can add a
Here we can use extension - as we talked about on the slack - or use the components:
messages:
UserSignedUp:
payload:
x-remote-ref: "https://example.com/myschema.xsd"
contentType: "application/xml" components:
messages:
UserSignedUp:
payload:
$remoteRef: "https://example.com/myschema.xsd"
contentType: "application/xml" I remember I wrote you on slack that using components:
messages:
UserSignedUp:
payload:
schemaParse: false
schema:
$remoteRef: "https://example.com/myschema.xsd"
# or
x-remote-ref: "https://example.com/myschema.xsd"
contentType: "application/xml" I hope you understand :)
components:
messages:
UserSignedUp:
payload:
schemaParse: false
schemaRef: "/PurchaseOrder"
schema:
$remoteRef: "https://example.com/myschema.xsd"
# or
x-remote-ref: "https://example.com/myschema.xsd"
contentType: "application/xml"
components:
messages:
UserSignedUp:
payload:
schemaRef: "/PurchaseOrder"
schema:
$ref: ./some_xsd.xsd
contentType: "application/xml" I remember I proposed If you have questions, please ask! :) |
I think it's a great proposal, and it also considered various scenarios. I am looking forward to see this proposal be adopted in next version of asyncapi. |
this proposal would also allow the definition of mixed schemas, such as the one for the components:
schemas:
UserSchema:
$ref: user.raml
TimestampSchema:
type: object
properties:
timestamp:
type: string
format: date-time
messages:
SignupUser:
contentType: application/json
schemaFormat: application/raml+yaml;version=1.0
payload:
$ref: "#/components/schemas/UserSchema"
UserSignedUp:
contentType: application/json
schemaFormat: ??? no unique value possible here ???
payload:
allOf:
- $ref: "#/components/schemas/TimestampSchema"
- $ref: "#/components/schemas/UserSchema" |
Based on this discussion, I am a bit "scared" that tooling will have a hard time implementing an expected behavior, created a separate issue as it is only partly related to this: #656 |
@GeraldLoeffler By my proposal we should be able to do: components:
schemas:
UserSchema:
schemaFormat: application/raml+yaml;version=1.0
schema:
$ref: 'user.raml'
TimestampSchema:
type: object
properties:
timestamp:
type: string
format: date-time
messages:
SignupUser:
contentType: application/json
payload:
$ref: "#/components/schemas/UserSchema"
UserSignedUp:
contentType: application/json
payload:
allOf:
- $ref: "#/components/schemas/TimestampSchema"
- $ref: "#/components/schemas/UserSchema" Thanks for great example, because while writing this proposal I didn't look at nested custom schemas at all, but you can see it would be possible to support it 😅 |
Sorry guys. Now I don't have a time for champion it. Feel free to pick it up. |
I was thinking twice about "AsyncApi Schema object"
And the complexity will grow:
Do we really want that? |
Is it a problem with headers? is there no use case for using avro? In the case of parameters, we discussed that on one call and conclusion what that it is not a problem because we anyway need to change parameters and not allow JSON Schema there but we should go server variables direction |
I see no use case for avro based header. Headers are always (i know none products where it would be different) serialized by the messaging solution. Having support for avro schema is that the message payload is avro serialized and you dont want a schema mapping. I would vote for having custom schema only for payload.
|
Hard for me to clarify really as before only AsyncAPI Schema was used anyway @dalelane can you have a look, Avro schema for headers? @fmvilas on last 3.0 meeting https://youtu.be/O4TQWBEaXy0?t=92 mentioned he knows people doing it last resort, we can still reuse new Schema object for payload and headers, but in |
I created a Draft PR with the initial changes on the JSON Schema files asyncapi/spec-json-schemas#370 cc @GreenRover |
Changes in Parser-JS and Parser-API will be also added |
Recap of discussion from Slack:
|
@GreenRover @derberg I can't find any other further discussion about allowing other schema formats into the headers finally. Did we drop that finally? |
tbh I do not remember, but definitely it got in -> https://github.com/asyncapi/spec/pull/910/files so new multi format is in the headers too |
Ouch, for some reason I skipped when reading the messageObject spec doc 😮💨 . Thanks for pointing that out! |
I created a new issue to discuss about the headers shape now that we allow multi format schemas #948 |
This one is only missing the JS parser implementation. Anyone volunteering? |
This issue has been automatically marked as stale because it has not had recent activity 😴 It will be closed in 120 days if no further activity occurs. To unstale this issue, add a comment with a detailed explanation. There can be many reasons why some specific issue has no activity. The most probable cause is lack of time, not lack of interest. AsyncAPI Initiative is a Linux Foundation project not owned by a single for-profit company. It is a community-driven initiative ruled under open governance model. Let us figure out together how to push this issue forward. Connect with us through one of many communication channels we established here. Thank you for your patience ❤️ |
Introduction
Currently we can define a scheme in a different format than the default (AsyncAPI Schema) only in the message's
payload
field (#528). E.g. defining the scheme in a different format for the message'sheaders
field, or for the fields in bindings (see issue -> asyncapi/avro-schema-parser#67), or in extensions the user cannot define.Proposal
My proposal is mainly based on extending Scheme Object to union type:
schema
andschemaFormat
fields so the following examples will be compatible with each other:In addition, we should define a field on the root of the document
defaultSchemaFormat
- similar todefaultContentType
. Any schema that does not have theschemaFormat
field defined will be treated as with the format indicated bydefaultSchemaFormat
.This solution also allows us to define in easier way schemas that have a string format (GraphQL types, Protobuf or XSD):
How will this work with references? Very simply, imagine two files - the main one and the one with models - e.g with protobuf
Additionally, the use of custom formats in binding and extension will also be possible (used example from the asyncapi/avro-schema-parser#67 issue):
Parser implementation
Are we facing a breaking change in the parser and the corresponding Schema model? And this is surprising because no. Why? Every function in a Schema instance, first will check if we are dealing with a schema with
schema
andschemaFormat
fields or not and do the appropriate fallback. I know this is an implementation detail, but there is a simple example:Obviously this will need to be optimized :)
Notes
schemaFormat
field at message level will be deprecated.defaultSchemaFormat
.schemaFormat
andschema
as keywords - then we can use$schemaFormat
, but I don't think it's necessary.Update
Avro example
To retrieving
Toy
record using JSON references we should do something like this:when using new
schemaRef
field we will make this:Protobuf example
with using new
schemaRef
field:Remarks:
$ref
works as it did for JSON/YAML schemasOften people don't know, but
$ref
can have reference to files that are not JSON/YAML. Then it treats these values (files) as a regular string (which is also a JSON derivative).the responsibility of resolving references/pointer is moved to the custom parsers (Please note that currently we can define schemas other than JOSN only in messages, but in my proposal we can define them everywhere) - custom parser after parsing the schema should also extract the given reference pointed by
schemaRef
field (follows with syntax for given schema format) and "inject" it to theschema
object, so (based on avro example) the resolved schema will be:Any feedback are more than welcome :)
The text was updated successfully, but these errors were encountered: