Dynamic GraphQL schema?

此生再无相见时 提交于 2020-12-13 04:28:11

问题


I have a mutation that is going to submit a form data, this data can vary depending by the form you are filling out.

The forms are going to be a lot, and they will share the same "steps" (each form is composed by 1 or more pages/steps).

So, we may have these reusable steps:

  • Fav fruit
  • Date of birth
  • Name and surname

And these two forms:

  • Generic info (genericInfo): Name and surname + Date of birth
  • What do you eat? (whatYouEat): Name and surname + Fav fruit

I'd need a way to have a single mutation, that allows to define the form name, and takes a data object that needs to be validated based on such form name.

For instance, if I call this mutation:

submitForm(formName: $formName, formData: $formData) {
  resultMessage
}

with formName set to genericInfo and formData set to { nameAndSurname: 'Foo Bar', favFruit: 'apple' }, it should throw an error because genericInfo doesn't expect favFruit, but dateOfBirth.

Can this be achieved with GraphQL? Are there better ways to get here maybe?


回答1:


GraphQL doesn’t directly allow this. Input object types have fixed structure, and there’s no conditional validation (built-in; your resolver function could produce errors based on its own checks that are richer than what’s in the schema).

The most common pattern I’ve seen adopts the Relay GraphQL mutation conventions (even if you don’t expect your clients to be using Relay). This has one mutation per possible action (in your case, one mutation per submitted form) and a distinct input object type per mutation.

Also note that the input object types can be nested, so in your example, you could write

input Name {
  givenName: String!
  surname: String!
}

input Fruit {
  name: String!
}

input WhatYouEatInput {
  name: Name!
  fruit: Fruit!
}

mutation {
  whatYouEat(input: WhatYouEatInput!): WhatYouEatPayload!
}

which would allow reusing the common parts of the schema across different mutation types.




回答2:


It would be possible to do this if GraphQL provided a Union type that could be used as input. This has been suggested before, but there seems to be no plans to implement it in the near future.

So, since you will have dozens of possible combinations on the form data, I think your best option would be to just send a string in JSON format with the data, and do the validation yourself, using some structure that defines all possible formName and its allowed fields.

But this way you would not be taking advantage of GraphQL typing system.



来源:https://stackoverflow.com/questions/51251065/dynamic-graphql-schema

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!