{"action":"created","issue":{"url":"https://api.github.com/repos/apollostack/apollo-client/issues/29","repository_url":"https://api.github.com/repos/apollostack/apollo-client","labels_url":"https://api.github.com/repos/apollostack/apollo-client/issues/29/labels{/name}","comments_url":"https://api.github.com/repos/apollostack/apollo-client/issues/29/comments","events_url":"https://api.github.com/repos/apollostack/apollo-client/issues/29/events","html_url":"https://github.com/apollostack/apollo-client/issues/29","id":143369018,"number":29,"title":"Mutations","user":{"login":"stubailo","id":448783,"avatar_url":"https://avatars.githubusercontent.com/u/448783?v=3","gravatar_id":"","url":"https://api.github.com/users/stubailo","html_url":"https://github.com/stubailo","followers_url":"https://api.github.com/users/stubailo/followers","following_url":"https://api.github.com/users/stubailo/following{/other_user}","gists_url":"https://api.github.com/users/stubailo/gists{/gist_id}","starred_url":"https://api.github.com/users/stubailo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stubailo/subscriptions","organizations_url":"https://api.github.com/users/stubailo/orgs","repos_url":"https://api.github.com/users/stubailo/repos","events_url":"https://api.github.com/users/stubailo/events{/privacy}","received_events_url":"https://api.github.com/users/stubailo/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/apollostack/apollo-client/labels/idea","name":"idea","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2016-03-24T21:47:51Z","updated_at":"2016-03-24T23:15:11Z","closed_at":null,"body":"The ability to do mutations is one of the primary features of a GraphQL client. A mutation looks like this:\r\n\r\n```\r\nmutation {\r\n  createAuthor(\r\n    _id: \"john\",\r\n    name: \"John Carter\",\r\n    twitterHandle: \"@john\"\r\n  ) {\r\n    _id\r\n    name\r\n  }\r\n}\r\n```\r\n\r\nYou can pass multiple mutations in the same query, as well. If you want to pass the arguments as variables, you have to specify them after the `mutation` keyword, and then also indicate where those variables should be used:\r\n\r\n```\r\nmutation createAuthor($_id: String, $name: String, $twitterHandle: String) {\r\n  createAuthor(\r\n    _id: $_id,\r\n    name: $name,\r\n    twitterHandle: $twitterHandle\r\n  ) {\r\n    _id\r\n    name\r\n  }\r\n}\r\n\r\n// Need to send these variables\r\n{\r\n  _id: \"john\",\r\n  name: \"John Carter\",\r\n  twitterHandle: \"@john\" \r\n}\r\n```\r\n\r\nAs you can see, this is quite verbose, with the names of the variables repeated roughly four times. There are a couple ways to solve this:\r\n\r\n### 1. Relay adopts a mutation spec\r\n\r\nhttps://facebook.github.io/relay/graphql/mutations.htm\r\n\r\n```\r\nmutation createAuthor {\r\n  createAuthor(input: $input) {\r\n    clientMutationId,\r\n    status {\r\n      _id\r\n      name\r\n    }\r\n  }\r\n}\r\n\r\n// Need to send these variables\r\n{\r\n  input: {\r\n    _id: \"john\",\r\n    name: \"John Carter\",\r\n    twitterHandle: \"@john\"\r\n  }\r\n}\r\n```\r\n\r\nThis is simpler because the names of the arguments are only listed once. However, you need a specific input type for every mutation.\r\n\r\nBut the spec is another restriction on your GraphQL server.\r\n\r\n### 2. Lokka has a mutation wrapper that adds the boilerplate for you\r\n\r\n```\r\nclient.mutate(`\r\n    newFilm: createMovie(\r\n        title: \"Star Wars: The Force Awakens\",\r\n        director: \"J.J. Abrams\",\r\n        producers: [\r\n            \"J.J. Abrams\", \"Bryan Burk\", \"Kathleen Kennedy\"\r\n        ],\r\n        releaseDate: \"December 14, 2015\"\r\n    ) {\r\n        ...${filmInfo}\r\n    }\r\n`).then(response => {\r\n    console.log(response.newFilm);\r\n});\r\n```\r\n\r\nThey save you from writing the `mutation X` thing. It works with any GraphQL server. The downside is, you can't actually pass variables because you would need to know the types.\r\n\r\n## Proposed API\r\n\r\nI don't think we need to impose a spec on the server for mutations. For a low-level API, let's just implement the standard mutation API from GraphQL itself, with all of the boilerplate. To eliminate it, we probably need to know the types of the variables, which is not optimal. \r\n\r\nThis is exactly what Jonas ended up with in his example todos app:\r\n\r\n```js\r\nclient.mutation( {\r\n  mutation: `mutation makeListPrivate($listId: ID!){\r\n    makeListPrivate(id: $listId)\r\n  }`,\r\n  args: { 'listId': listId }\r\n});\r\n```\r\n\r\nLet's explore additional features for this in the future, there's probably some nice stuff we can do to reduce boilerplate. And maybe we want a switch to support the Relay mutation spec."},"comment":{"url":"https://api.github.com/repos/apollostack/apollo-client/issues/comments/201068936","html_url":"https://github.com/apollostack/apollo-client/issues/29#issuecomment-201068936","issue_url":"https://api.github.com/repos/apollostack/apollo-client/issues/29","id":201068936,"user":{"login":"stubailo","id":448783,"avatar_url":"https://avatars.githubusercontent.com/u/448783?v=3","gravatar_id":"","url":"https://api.github.com/users/stubailo","html_url":"https://github.com/stubailo","followers_url":"https://api.github.com/users/stubailo/followers","following_url":"https://api.github.com/users/stubailo/following{/other_user}","gists_url":"https://api.github.com/users/stubailo/gists{/gist_id}","starred_url":"https://api.github.com/users/stubailo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stubailo/subscriptions","organizations_url":"https://api.github.com/users/stubailo/orgs","repos_url":"https://api.github.com/users/stubailo/repos","events_url":"https://api.github.com/users/stubailo/events{/privacy}","received_events_url":"https://api.github.com/users/stubailo/received_events","type":"User","site_admin":false},"created_at":"2016-03-24T23:15:11Z","updated_at":"2016-03-24T23:15:11Z","body":"I think we should first support all normal GraphQL servers, and then extend it to avoid having to manually refetch data. But I agree having to list the fields to be refetched is a drag.\r\n\r\nIf this client only works with special GraphQL servers that will be a really big damper on adoption, and kind of defeats the purpose of using a standard like GraphQL."}}