Reputation: 8461
I'm using Graphql and I want to use the idiomatic way of handing bad input from the client side with Graphql mutations. Currently if a user tries to submit data that doesn't meet the server requirements my server will still send back a 200 response.
mutation do
field :create_team, :team do
arg(:name, non_null(:string))
arg(:league_id, non_null(:id))
resolve(&TeamResolver.create_team/3)
end
end
def create_team(_root, args, info) do
Teams.create_team(args, info)
end
def create_team(attrs, info) do
user_id = Auth.current_user_id(info)
changeset = Team.changeset(%Team{user_id: user_id}, attrs)
case Repo.insert(changeset) do
{:ok, team} ->
{:ok, team}
{:error, changeset} ->
{:error, "error"}
end
end
The problem is in the context, we don't use the conn
so I can't put_status(:unproccesable_entity)
or something like that. If the client side sends bad data how do I send back a 4xx
status code?
Upvotes: 1
Views: 124
Reputation: 1364
When using Graphql, it's important to remember it is not bound to the HTTP Protocol. It operates on query documents, which can be delivered by clients in any kind of way (HTTP, Files, Strings ...) and it responds with result documents.
Also, imagine the following query document:
mutation {
first: firstMutation,
second: secondMutation,
}
If the first mutation errors, but the second was successful, a status code of 400 would be irritating.
Instead, GraphQL uses the result document to deliver possible errors, for example:
{
"data": {
"first": true,
"second": null
},
"errors": [
{
"locations": [
{
"column": 0,
"line": 2
}
],
"message": "some error",
"path": [
"first"
]
}
]
}
where you can see that the first delivered a result and the second had an error. It's up to the GraphQL client to handle such errors, not the transport protocol.
Upvotes: 1