Feedback on GraphQL

Motivation

  • Fetch object graph in one call
  • Only get what your client needs
  • Typing system

Schema

Type Definition + Resolvers

Type

    type Person {
        id: ID!
        nom: String!
        prenom: String!
        job: String
    }

Type Query

    type Query{
        person(id: ID!): Person!
        people: [Person]!
    }

Resolvers

const typeDefs = `
    type Person {
        id: ID!
        nom: String!
        prenom: String!
        job: String
    }

    type Query{
        person(id: ID!): Person!
        people: [Person]!
    }
`;

const people = [
  { id: '1', nom: 'Le Bris', prenom: 'Frederic', job: 'CTO' },
  { id: '2', nom: 'Millet', prenom: 'Frederic', job: 'Devops' },
  { id: '3', nom: 'Lecoq', prenom: 'Mickael', job: 'Developer Freelance' },
  { id: '4', nom: 'Deshayes', prenom: 'Lucie', job: 'Designer' },
  { id: '5', nom: 'Frin', prenom: 'Benjamin' },
  { id: '6', nom: 'Guillemot', prenom: 'Laura' },
];

const resolvers = {
  Query: {
    people: () => people,
    person: (_, { id }) => people.find(p => p.id === id),
  },
};

Call

query {
	people{
		nom
		prenom
	} 
}
{
	"data": {
		"people": [
			{
				"nom": "Le Bris",
				"prenom": "Frederic"
			},
			{
				"nom": "Millet",
				"prenom": "Frederic"
			},
			{
				"nom": "Lecoq",
				"prenom": "Mickael"
			},
			{
				"nom": "Deshayes",
				"prenom": "Lucie"
			},
			{
				"nom": "Frin",
				"prenom": "Benjamin"
			},
			{
				"nom": "Guillemot",
				"prenom": "Laura"
			}
		]
	}
}

POST

Call

query person($id: ID!){
	person(id: $id){
		nom
		prenom
		job
	} 
}



variables {"id": 3}
{
	"data": {
		"person": {
			"nom": "Lecoq",
			"prenom": "Mickael",
			"job": "Developer Freelance"
		}
	}
}

POST

SubTypes

   type Person {
        id: ID!
        nom: String!
        prenom: String!
        job: String
        vehicule: Vehicule
    }

    type Vehicule {
        who: ID!
        type: String
    }
const resolvers = {
  Query: {
    people: () => people,
    person: (_, { id }) => {
      return people.find(p => p.id === id);
    },
  },
  Person: {
    vehicule: person => vehicules.find(v => v.who === person.id),
  },
};

SubTypes

query {
	people{
	   prenom
	    vehicule {
	        type
	    }
        } 
}
{
	"data": {
		"people": [
			{
				"prenom": "Frederic",
				"vehicule": {
					"type": "Voiture"
				}
			},
			{
				"prenom": "Frederic",
				"vehicule": {
					"type": "Voiture"
				}
			},
			{
				"prenom": "Mickael",
				"vehicule": {
					"type": "Velo"
				}
			},
			{
				"prenom": "Lucie",
				"vehicule": {
					"type": "Bus"
				}
			},
			{
				"prenom": "Benjamin",
				"vehicule": {
					"type": "Il faut que je lui demande"
				}
			},
			{
				"prenom": "Laura",
				"vehicule": {
					"type": "Bus"
				}
			}
		]
	}
}

Mutation

  type Mutation{
     addPerson(person: PersonInput): Boolean!
  }

 input PersonInput{
     id: ID!
     nom: String!
     prenom: String!
     job: String
  }

const resolvers = {
   ...
  Mutation: {
    addPerson: (_, { person }) => {
      people.push(person);
      return true;
    },
  },
};
	mutation add($person: PersonInput){
		addPerson(person: $person)
	}



        {
	    "person": {
		"id": 18,
		"nom": "Jankowsky",
		"prenom": "François",
		"job": "Business Dev"
	    }
        }

Client Side - React Apollo

const QUERY_PEOPLE = gql`
    query {
	people{
		nom
		vehicule {
			type
		}
	} 
}`


<Query query={QUERY_PEOPLE}>

    ({loading, error, data}) => ....

</Query>

Mutation - React Apollo

<Mutation query={gql`
	mutation add($person: PersonInput){
		addPerson(person: $person)
	}
        update={this.updateCache}
 `}>

    addPeople => ....

</Mutation>




const updateCache = (cache, {data}) => {
    
   const {people} = cache.readQuery({query: QUERY_PEOPLE})


   cache.writeQuery({query: QUERY_PEOPLE}, {data ....});
} 

Schema

query{
  __type(name: "Query") {
    name
    fields {
      name
      type {
        name
        kind
      }
    }
  }
}
{
	"data": {
		"__type": {
			"name": "Query",
			"fields": [
				{
					"name": "person",
					"type": {
						"name": "Person",
						"kind": "OBJECT"
					}
				},
				{
					"name": "people",
					"type": {
						"name": null,
						"kind": "NON_NULL"
					}
				}
			]
		}
	}
}

One more thing

Subscriptions


//App Sync

type Subscription {
  addedPerson: Customer @aws_subscribe(mutations: ["add"])
}



//Apollo

type Subscription {
  addedPerson(person: Person!): Person
}

Feedback on GraphQL

By Mickael Lecoq

Feedback on GraphQL

  • 1,062