Mutations: GraphQL vs Dgraph format

Hi guys,

While researching type/schema validation system in GraphqL, found out that our mutations format (RDF nquads) is different from how GraphQL spec describes mutations.

Dgraph:

mutation{
    set{
        <jedi> <stars> "5" .
        <jedi> <commentary> "This is a great movie!" .
    }
}

GraphQL:

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}
{
  "ep": "JEDI",
  "review": {
    "stars": 5,
    "commentary": "This is a great movie!"
  }
}

Major difference is Graphql takes in separate arguments for data changes while we conform to the RDF format.
Prime reason for having same format for query and mutations I think are (among other reasons GraphQL team might have):

  1. It’s convenient. :stuck_out_tongue:
  2. It encourages use of single parser/validation mechanism for queries and mutations.

Had this discussion earlier about whether it will be beneficial for us to change Dgraph’s format to GraphQL’s mutation format, so making this post to take it further.

I think that our current system works good and we can introduce the minimal type/schema system without changing it. GraphQL spec tightly couples the query language with internal implementation which we do not really want or need.

Keeping the implementation as it is:

  • Will probably make supporting few GraphQL features like introspection a bit tricky but it shouldn’t be a blocker.
  • For users trying out dgraph through GraphiQL (for mutations), it might be an issue.

What do you guys think? Please post your thoughts here.

PS: We already had some kind of pin in roadmap for supporting multiple mutations here but trello link is gone now.

Where would this be defined?

createReview will be defined inside Mutation definition, as one of the mutation fields.
According to GraphQL spec, it will have an associated resolve function that will take in input arguments and modify data.

For e.g., the mentioned mutation’s response will be:

{
  "data": {
    "createReview": {
      "stars": 5,
      "commentary": "This is a great movie!"
    }
  }
}

Another example:
With schema defined something as (in graphql-js format ):

const MovieType = new GraphQLObjectType({
  fields: {
    title: { type: GraphQLString },
  },
  name: 'movie',
});

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    fields: {
      movie: { type: MovieType },
    },
    name: 'Query',
  }),
  mutation: new GraphQLObjectType({
    fields: {
      changeMovieName: {
        type: MovieType,
        args: { newName: { type: GraphQLString } },
        resolve: (function (obj, { newName }) {
         ...<function to change movie name for this node>...
        })
      }
    },
    name: 'Mutation',
  })
});

Following mutation can now be done:

mutation DoMutation {
  changeMovieName(newName: "Wreck-it Ralph") {
    title
  }
}

This will return:

{
      "data": {
        "changeMovieName": {
          "title": "Wreck-it Ralph"
        }
}

Notice the similarity between query and mutation definition.
Also, notice that the function changeMovieName could be renamed to movie. In that case, the same attribute/field name -> movie could be used in both query and mutation with different actions.
I think the attribute/field name is kept as a verb to make it more intuitive.

So, the user will provide these functions to us? In what language? Can you fill in all the blanks here. Or, take the example of the quiz system that @Rahul-Sagore is working on, and explain how he might communicate with Dgraph.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.