Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Generate unions from oneOf return type#330

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
ftatzky wants to merge1 commit intoIBM:master
base:master
Choose a base branch
Loading
fromftatzky:master

Conversation

@ftatzky
Copy link

According toSwagger: Inheritance and Polymorphism polymorphism can be described with the oneOf keyword in responses. Right now openapi-to-graphql doesn't support that.

This change enables the generation of unions foroneOf return types in responses.

SimpleTest.yaml

openapi:3.0.2info:version:1.0.0title:Test polymorphismservers:  -url:/poly-apipaths:'/document/{id}':get:description:Reads a document.operationId:readDocumentparameters:        -name:idin:pathdescription:Document IDrequired:trueschema:type:stringresponses:'200':description:Successfulcontent:application/json:schema:oneOf:                  -$ref:'#/components/schemas/Article'                  -$ref:'#/components/schemas/Video'discriminator:propertyName:documentTypemapping:article:'#/components/schemas/Article'video:'#/components/schemas/Video'components:schemas:Document:type:objectproperties:id:type:stringdescription:Document IDdocumentType:type:stringenum:            -article            -videodescription:Document typeArticle:description:ArticleallOf:        -$ref:'#/components/schemas/Document'        -type:objectproperties:author:type:stringdescription:Article authorheadline:$ref:'#/components/schemas/RichText'Video:description:VideoallOf:        -$ref:'#/components/schemas/Document'        -type:objectproperties:videoUrl:type:stringdescription:Video source URLRichText:type:objectdescription:Richtext typeproperties:data:type:objectdescription:Raw (JSON)

Generated output before the change

"""The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)."""scalarJSONtypeQuery {"""  Reads a document.  Equivalent to GET /document/{id}  """document("""Document ID"""id:String!  ):JSON}

Generated output after the change

"""Article"""typeArticle {"""Article author"""author:String"""Document type"""documentType:DocumentType"""Richtext type"""headline:RichText"""Document ID"""id:String}"""No description available."""unionDocument =Article |VideoenumDocumentType {  ARTICLE  VIDEO}"""The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf)."""scalarJSONtypeQuery {"""  Reads a document.  Equivalent to GET /document/{id}  """document("""Document ID"""id:String!  ):Document}"""Richtext type"""typeRichText {"""Raw (JSON)"""data:JSON}"""Video"""typeVideo {"""Document type"""documentType:DocumentType"""Document ID"""id:String"""Video source URL"""videoUrl:String}

Signed-off-by: Florian Tatzky <florian.tatzky@bild.de>
schema:SchemaObject,
data:PreprocessingData<TSource,TContext,TArgs>
):string|null{
if(schema.oneOf){
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Unfortunately, I don't think we can do this asoneOf andallOf does not necessitate union or object.

For example, this is anexample provided byjson-schema:

{   "type": "number",   "oneOf": [     { "multipleOf": 5 },     { "multipleOf": 3 }   ] }

Additionally, even ifoneOf contains a number of schemas, we still need to make a number of checks to see if we can still create a union as JSON schemaoneOf is a lot more flexible than GraphQLunion type.

For example, according to thespecification, GraphQL unions cannot be composed of other unions

The member types of a Union type must all be Object base types; Scalar, Interface and Union types must not be member types of a Union. Similarly, wrapping types must not be member types of a Union.

That is why we have thischeck, to see if we have cases of nestedoneOf/allOf.

@Alan-Cha
Copy link
Collaborator

This is for sure a bug that needs to be fixed. However, I think we need to approach it differently.

I think the problem actually has to do with the fact that we do not properly identify the type ofArticle orVideo and as a result, we fall back onto thejson type forDocument.

We're failing thisif statement which ensures that all the member types (Article andVideo) are object types.

The type data is coming fromhere and the definition for that ishere.

We identify the types of the schemahere and unfortunately,Article andVideo are determined to benull instead ofobject because we do not deference the schemas inside.


I think what we need to do is to makegetSchemaTargetGraphQLType() more robust by consideringoneOf/allOf and dereferencing member schemas.

In essence, I think we should move some of the logic from processing theoneOf/allOf intogetSchemaTargetGraphQLType().


Let me know if this all makes sense to you!

@ftatzky
Copy link
Author

@Alan-Cha yeah that makes total sense. As I said, I somehow knew that my changes were probably just to naive and a bandaid and has some major flaws I just couldn't see by myself. I talked to my team an my PO, and it's a story in our current sprint now and I can dedicate actual work time to dive deeper into this problem (which helps a lot). Thanks so far, and I will get back to you as soon as I have something. Btw is there a chat or some plattform you use for this community? Something where interaction is more immediate? If not that's ok, just asking. Best regards

@Alan-Cha
Copy link
Collaborator

@ftatzky If you would like to take another look at this problem, that would be super cool! Otherwise, I will have to take a look at this in the upcoming weeks as I'm juggling some other tasks right now. I'm happy to answer whatever questions you have though!

I think it should be easy to medium difficulty, leaning more towards easy. I think you are on the right track. We should havegetSchemaTargetGraphQLType() returnunion. Checking fornull andobjecthere when we are trying to create aunion is confusing. We just need to follow move the existing logic for determining whether or not to create a union and put it intogetSchemaTargetGraphQLType().

Yes! We have aGitter chat room! Again, would be happy to answer any questions that you may have.

@Alan-Cha
Copy link
Collaborator

Alan-Cha commentedJun 25, 2020
edited
Loading

There is one consideration we should make.

Currently, the plan is to move the existing logic intogetSchemaTargetGraphQLType(), we should still consolidateallOf andoneOfhere, and basically check if thetargetGraphQLType (fromgetSchemaTargetGraphQLType()) isunionhere, and only if this is true, will we use theoneOf tocreate the union.


basically check if thetargetGraphQLType (fromgetSchemaTargetGraphQLType()) isunionhere

Actually on second thought, we should probably just utilize theswitch statement


My one concern is that we might want to useoneOf to do other things besides creating a union and this kind of logic flow may impede that.

An example of how we can useoneOf for other things is, given the following schema

{"type":"number","oneOf": [     {"multipleOf":5 },     {"multipleOf":3 }   ] }

We could create a new type that would actively check if it fits themultipleOf requirement.

However, for now, I think we only useoneOf to create unions. I'm just saying it would be nice to refactor in such a way that we can still useoneOf for other purposes without making the logic too complicated. For now, we don't necessarily need to do that.

Edit: Actually, I think everything will be fine if we just utilize the switch statement. Don't worry about what I said.

@Alan-Cha
Copy link
Collaborator

Let me know if this makes any sense! I might just be rambling 😅

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

Reviewers

@Alan-ChaAlan-ChaAlan-Cha left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@ftatzky@Alan-Cha

[8]ページ先頭

©2009-2025 Movatter.jp