I am doing some experimentation and I want to try something with GraphQL on a React project. I already know something about GraphQL but I never really used it by myself.
I begin searching for a good GraphQL backend and I settle with Graphcool which seems the best out there at this moment: has a lot of guides and tutorials, it integrates with other services, it is very flexible and it’s free for developers. Bright green lights!
Graphcool has quickstart guides for both Apollo and Relay but I already decided what to use so I begin yarn-ing what it needs on my React project:
"apollo-client": "^0.8.1","graphql-tag": "^1.2.3","react-apollo": "^0.9.0",
I think about something not so original but always fun to work with: music bands and albums and songs and stuff.. always more exciting than Northwind Traders or Contoso Ltd. :)
So I just want to read/write data from/to Graphcool.
In GraphQL when you want to read you need Queries, when you want to write you need Mutations.
I am not writing about queries because the focus of this story is about nested mutations and because queries are well explained and I got no problems during the implementation.
LET THE PARTY BEGINS
With the Graphcool “Console” (an awesome interface for db modelling) I created a rough-and-ready structure.
type Band {name: String!country: Stringwebsite: Stringmembers: [Person]contact: Personalbums: [Album]}
type Person {firstName: String!lastName: String!}
type Album {name: String!year: Int!songs: [Song]}
type Song {trkNr: Inttitle: String!duration: String}
As you can see we nested two arrays on two different levels starting from the albums field of the Band model.
So, to be clear, I want to store all this info using some data about STORMO music band, and I want to do it with a single mutation!
The party suddenly crashes (and STORMO stop playing!) when I realize I don’t know how to create nested mutations, nor the (anyway very good) Apollo documentation can help me out.
Moreover I was brave enough to use arrays and now my eyes are lost in the window… the physical one!!
After a few not-worth-mentioning tries i decide to use the salvific Graphcool slack support where I begin stalking in the general channel.
Nilan Marktanner, from Graphcool staff begins to help me in no time and when i finally explain in a comprehensible way my situation, he hands me…
Thanks to Nilan I relaize three things:
and that was exactly what i needed.
The mutation I have to build
mutation {createBand(name: "Stormo"country: "Italy"website: "https://stormo.bandcamp.com/"members: [{firstName: "Luca"lastName: "Rocco"}, {firstName: "Federico"lastName: "Trimeri"}, {firstName: "Giacomo"lastName: "Rento"}, {firstName: "Gabriele"lastName: "Coldepin"}]contact: {firstName: "Giacomo"lastName: "Rento"}albums: [{name: "SOSPESI NEL VUOTO BRUCEREMO IN UN ATTIMO E IL CERCHIO SARÀ CHIUSO"year: 2014songs: [{trkNr: 1title: "In Volo"duration: "02:50"}, {trkNr: 2title: "Supernova"duration: "02:10"}, {trkNr: 3title: "Fuga"duration: "01:24"}, {trkNr: 4title: "Perchè La Bambina Cade"duration: "02:46"}]}, {name: "7"year: 2009songs: [{trkNr: 1title: "Incosiderata Putrefazione"duration: "03:18"}, {trkNr: 2title: "Abbandono La Mia Volontà"duration: "03:20"}]}, {name: "Self-Titled EP"year: 2007songs: [{trkNr: 4title: "Quando Non Ci Sei"duration: "02:08"}, {trkNr: 5title: "Al Punto Di Non Ritorno"duration: "04:36"}]}]) {idmembers {id}contact {id}albums {idsongs {id}}}}
Using Apollo Client, I specify input arguments with GraphQL variables, so let’s see how it looks in this case:
import gql from 'graphql-tag';
const BandMutation = gql`mutation ($name: String!$country: String$website: String$Members: [Person]$Contact: Person$Albums: [Albums]) {createBand(name: $nameCountry: $CountryMembers: $MembersContact: $ContactAlbums: $Albums) {idmembers {id}contact {id}albums {idsongs {id}}}}`;
Using a form I compose the data like this: (but pay attention, apollo wants this object called ‘variables’ and nothing else!)
const variables = {name: "Stormo",country: "Italy",website: "https://stormo.bandcamp.com/"members: [{firstName: "Luca",lastName: "Rocco",}, {firstName: "Federico",lastName: "Trimeri",}, {firstName: "Giacomo",lastName: "Rento",}, {firstName: "Gabriele",lastName: "Coldepin",}],contact: {firstName: "Giacomo",lastName: "Rento",},albums: [{name: "SOSPESI NEL VUOTO BRUCEREMO IN UN ATTIMO E IL CERCHIO SARÀ CHIUSO",year: 2014,songs: [{trkNr: 1,title: "In Volo",duration: "02:50" ,}, {trkNr: 2,title: "Supernova",duration: "02:10" ,}, {trkNr: 3,title: "Fuga",duration: "01:24" ,}, {trkNr: 4,title: "Perchè La Bambina Cade",duration: "02:46",}]}, {name: "7",year: 2009,songs: [{trkNr: 1,title: "Incosiderata Putrefazione",duration: "03:18",}, {trkNr: 2,title: "Abbandono La Mia Volontà",duration: "03:20",}]}, {name: "Self-Titled EP",year: 2007,songs: [{trkNr: 4,title: "Quando Non Ci Sei",duration: "02:08",}, {trkNr: 5,title: "Al Punto Di Non Ritorno",duration: "04:36",}]}]}
Finally, inside my React component I can use all of this to send my data to Graphcool
import React, { Component } from 'react';import { graphql, compose } from 'react-apollo';import BandMutation from './../graphql/BandMutation';
class CompanySettings extends Component {constructor(props) {super(props);this.sendData = this.sendData.bind(this);}
sendData(variables) {this.props.CreateBand({ variables }).then((response) => {window.alert('You submitted data about a new band');}).catch((e) => {console.error(e);});}
render() {return <FormCreateBand onSubmit={this.sendData} />;}}
export default compose(// with this I can use the mutation with this.props.CreateBandgraphql(BandMutation, { name: 'CreateBand' }),// I can write here other mutations or queries)(CompanySettings);
P.S. The party now is going crazy, thanks to Storm{O}!!
Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising &sponsorship opportunities.
To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.
If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!