Apollo GraphQL
On this page
Queries Jump to heading
import gql from 'graphql-tag'
const GET_DOGS = gql`
{
dogs {
id
breed
}
}
`
useQuery hook Jump to heading
import { useQuery } from '@apollo/react-hooks'
const { data, loading, error } = useQuery(GET_DOGS)
// useQuery with a `variable`
const { data, loading, error } = useQuery(GET_DOG_PHOTO, {
variables: { breed },
})
Example component Jump to heading
const Dogs = ({ onDogSelected }) => {
const { data, loading, error } = useQuery(GET_DOGS)
if (loading) {
return <Loader />
}
if (error) {
return <p>Error {JSON.stringify(error, null, 2)}</p>
}
return (
<select name="dog" onChange={onDogSelected}>
{data.dogs.map((dog) => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
</select>
)
}
Mutations Jump to heading
Queries enable clients to fetch data, but not to modify data. To enable clients to modify data, our schema needs to define some mutations.
useMutation hook Jump to heading
import { useMutation } from '@apollo/react-hooks'
const [addTodo, { data, loading, error }] = useMutation(ADD_TODO)
// usage
addTodo({ variables: { type: 'some value' } })
Example component Jump to heading
import gql from 'graphql-tag'
import { useMutation } from '@apollo/react-hooks'
const ADD_TODO = gql`
mutation AddTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`
const AddTodo = () => {
let input
const [addTodo, { data }] = useMutation(ADD_TODO)
return (
<div>
<form
onSubmit={(e) => {
e.preventDefault()
addTodo({ variables: { type: input.value } })
input.value = ''
}}
>
<input
ref={(node) => {
input = node
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
)
}
Updating the cache Jump to heading
If a mutation modifies multiple entities, or if it creates or deletes entities, the Apollo Client cache is not automatically updated to reflect the result of the mutation. To resolve this, your call to useMutation
can include an update function.
The purpose of an update function is to modify your cached data to match the modifications that a mutation makes to your back-end data. In the example in Executing a mutation, the update function for the ADD_TODO
mutation should add the same item to our cached version of the to-do list.
const GET_TODOS = gql`
query GetTodos {
todos
}
`
const AddTodo = () => {
let input
const [addTodo] = useMutation(ADD_TODO, {
update(cache, { data: { addTodo } }) {
const { todos } = cache.readQuery({ query: GET_TODOS })
cache.writeQuery({
query: GET_TODOS,
data: { todos: todos.concat([addTodo]) },
})
},
})
return (
<div>
<form
onSubmit={(e) => {
e.preventDefault()
addTodo({ variables: { type: input.value } })
input.value = ''
}}
>
<input
ref={(node) => {
input = node
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
)
}
Fragments Jump to heading
fragment NameParts on Person {
firstName
lastName
}
query GetPerson {
people(id: "7") {
...NameParts
avatar(size: LARGE)
}
}
Resolvers Jump to heading
Resolvers provide the instructions for turning a GraphQL operation (a query, mutation, or subscription) into data. They either return the same type of data we specify in our schema or a promise for that data.
Before we can start writing resolvers, we need to learn more about what a resolver function looks like. Resolver functions accept four arguments:
fieldName: (parent, args, context, info) => data
parent
: An object that contains the result returned from the resolver on the parent typeargs
: An object that contains the arguments passed to the fieldcontext
: An object shared by all resolvers in a GraphQL operation. We use the context to contain per-request state such as authentication information and access our data sources.info
: Information about the execution state of the operation which should only be used in advanced cases
← Back home