What should be the result of a delete mutation in Graphql? I'm using the graphql-ruby gem. Here's an example of my mutation, but I'm just not sure what I should be returning as the response.
Mutations::Brands::Delete = GraphQL::Relay::Mutation.define do
name "DeleteBrand"
description "Delete a brand"
input_field :id, types.ID
# return_field ??
resolve ->(object, inputs, ctx) {
brand = Brand.find(inputs[:id])
brand.destroy
}
end
You can return deleted_id or message. If it is an associated object you can return updated object like below example.
Destroy = GraphQL::Relay::Mutation.define do
name 'DestroyComment'
description 'Delete a comment and return post and deleted comment ID'
# Define input parameters
input_field :id, !types.ID
# Define return parameters
return_field :deletedId, !types.ID
return_field :article, ArticleType
return_field :errors, types.String
resolve ->(_obj, inputs, ctx) {
comment = Comment.find_by_id(inputs[:id])
return { errors: 'Comment not found' } if comment.nil?
article = comment.article
comment.destroy
{ article: article.reload, deletedId: inputs[:id] }
}
http://tech.eshaiju.in/blog/2017/05/15/graphql-mutation-query-implementation-ruby-on-rails/
I don't think a clear de facto standard exists as of July, 2017, and I see a lot of differences between implementations (GitHub, Yelp, GraphCool, Shopify).
However, if you look at some of recent GraphQL APIs to come out, there seems to be a common trend. Largely, the input type and response type are specific to the mutation. So for instance, for an updateBrand
mutation you might expect an UpdateBrandInput
, and return an UpdateBrandPayload
response. Notice, the input is not BrandInput
, and responding with Brand
. Nor would you respond with a scalar boolean (eg. true
if successful) or the id
of the deleted entity (in the case of a delete mutation). Per this convention, you could have a createBrand
mutation, with a CreateBrandInput
and a CreateBrandPayload
response.
By creating mutation specific input
and payload
types, you have a lot of flexibility in the fields you expect and respond with. Per deletion, you might have a DeleteBrandPayload
response that not only includes shallow (eg. only scalar) fields of the brand, but also other related data (eg. clientMutationId
), etc..
To be honest, I think the GraphQL spec gives just enough rope to hang yourself with, so it's smart to look at how some of the big guys are rolling this out.