问题
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