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,040