GraphQL Cheat Sheet =================== ### GraphQL Overview * An alternative approach to RESTful APIs * Clients issue queries/mutations to read and update data * Clients can fetch only the entity fields that are required * GraphQL query syntax can express complex entity relations => nested objects * Mitigates the explosion of RESTful endpoints in scenarios where many different representations of an entity are needed * Graphiql is a query execution UI, also provides good documentation ### GraphQL Server Express Integration ```javascript const express = require('express'); const expressGraphQL = require('express-graphql'); const schema = require('./schema/schema'); // create express app const app = express(); app.use('/graphql', expressGraphQL({ schema, graphiql: true })); // register app to listen on a port app.listen(4000, () => { console.log('Server started!'); }); ``` ### GraphQL Server Schema Types * GraphQL Schema types define the data contract between the client and the server ```javascript const GraphQL = require('graphql'); const { GraphQLObjectType, GraphQLString, GraphQLInt, GraphQLList, GraphQLSchema, GraphQLNonNull } = GraphQL; // define the company schema type const CompanyType = new GraphQLObjectType({ name: 'Company', // use a closure to work around cyclical references fields: () => ({ id: { type: GraphQLString }, name: { type: GraphQLString }, description: { type: GraphQLString }, users: { type: new GraphQLList(UserType), resolve(parentValue, args){ return axios.get(`http://localhost:3000/companies/${parentValue.id}/users`) .then(resp => resp.data); } } }) }); // define the user schema type const UserType = new GraphQLObjectType({ name: 'User', // use a closure to work around cyclical references fields: () => ({ id: { type: GraphQLString }, firstName: { type: GraphQLString }, age: { type: GraphQLInt }, company: { type: CompanyType, resolve(parentValue, args) { return axios.get(`http://localhost:3000/companies/${parentValue.companyId}`) .then(resp => resp.data); } } }) }); ``` ### GraphQL Server Queries ```javascript const RootQuery = new GraphQLObjectType({ name: 'RootQueryType', fields: { user: { type: UserType, args: { id: { type: GraphQLString }}, resolve(parentValue, args) { return []; } }, company: { type: CompanyType, args: { id: { type: GraphQLString }}, resolve(parentValue, args) { // async promise return axios.get(`http://localhost:3000/companies/${args.id}`) .then(resp => resp.data); } } } }); ``` ### GraphQL Server Mutations ```javascript const Mutation = new GraphQLObjectType({ name: 'Mutation', fields: { addUser: { type: UserType, args: { firstName: { type: new GraphQLNonNull(GraphQLString) }, age: { type: new GraphQLNonNull(GraphQLInt) }, companyId: { type: GraphQLString } }, resolve(parentValue, { firstName, age }) { return axios.post(`http://localhost:3000/users`, { firstName, age }).then(res => res.data); } }, editUser: { type: UserType, args: { id: { type: new GraphQLNonNull(GraphQLString) }, firstName: { type: GraphQLString }, age: { type: GraphQLInt }, companyId: { type: GraphQLString } }, resolve(parentValue, { id, firstName, age, companyId }) { var updatedUser = { firstName, age, companyId }; return axios.patch(`http://localhost:3000/users/${id}`, updatedUser) .then(res => res.data); } } } }); ``` ### GraphQL Query Syntax Simple Query: ``` query { user(id: "40"){ id firstName age } } ``` Query With Relations: ``` query { user(id: "40"){ id firstName age company { id, name, description } } } ``` Query Fragments: ``` query findCompanyUsers { apple: company(id:"1"){ ...companyDetails } google: company(id:"2"){ ...companyDetails } } fragment companyDetails on Company { id name description users { id firstName age } } ``` Parameterized Queries: ``` query UserQuery($id: ID!){ song(id: $id){ id firstName email } } ``` Parameter Values: ``` { "id": 12345 } ``` Mutation: ``` mutation { addUser(firstName: "Jeff", age: 34){ id firstName age } } ``` ### GraphQL Clients * Lokka - Simple implementation: basic queries, mutations, and simple caching * Apollo Client - Good balance between features and complexity * Relay - Amazing performance on mobile, but the most complex.