This is the repository that accompanies my GraphQL Workshop.
Try out your first GraphQL query. Follow this link to open up the Github GraphQL API. Click the button at the top right to authenticate and start writing a query. Find out how many repositories are in your account! (ca. 5 minutes)
Hint: Hit ctrl+space to get field autocomplete suggestions.
Make a list of data types that can be serialised in the JSON format. Create an example JSON document that contains all different data types. Which types are primitive types and which types are complex types? (ca. 10 minutes)
To get started with the next exercises, fork this repository to your account using the Github website. Now clone the repository to your machine and follow the instructions of
backendandfrontend.
Create a Mongoose model for our pet shelter inhabitants. The model should be names pet and have the following fields:
- name which is a
Stringand required - type which is either
DOG,CATorRABBITand required - adopted is a
Booleanand required - picture which is a
String(the url of the image) - breed which is a
String - height which is a
Numberand will contain the height of the animal in centimeters
Start the Mongo DB on your computer and create a .env file in backend that contains the environment variable MONGODB_URL. (ca. 10 minutes)
Create your first query: Add a field to the root query type in src/graphql/types.js.
The field should be named hello and should return the string "Hello world!".
Declare the type as GraphQLString and the resolver should be a trivial function that takes no arguments and always returns our hello world string.
If you want you can add a description as well!
Start the server as described in the README of backend and open your browser http://localhost:8080/graphql.
Your server should now be able to respond to the query:
{
hello
}(ca. 5 minutes)
Bonus: Make the return value of the query non-nullable.
Open up the Github API again. Find out how many repositories are on my (hendrikniemann) account!
Now add an argument to the hello query called name of type String.
If the argument is supplied return a string that contains the name instead e.g. "Hello Hendrik!". (ca. 3 minutes)
Create an enum type for PetType with the values DOG, CAT or RABBIT.
For this exercises we put all the types into the types.js file.
In a larger project you might want to create one file for every type. (ca. 10 minutes)
Create a GraphQL object type for our pets.
The object type should have all the fields of the Mongoose model.
Make sure to define required fields as non-nullable using GraphQLNonNull.
Now add a field to the Query object type to create a query: pet.
The pet query takes one required argument id and returns a single pet with the supplied ID.
If there is no pet with the given ID, return null.
Add another query field pets.
pets should return the list of all pets.
For this return a new GraphQLList of Pet. (ca. 30 minutes)
Create a new Mongoose model EmployeeModel and a corresponding GraphQL object type with firstName, and lastName of the employee.
Now create a field responsibleEmployee in the pet model and object type that references an employee.
Here you will have to write a custom resolver that loads the employee from the database if the field is requested. (ca. 15 minutes)
Bonus: Create a query field for employees similar to pets.
Create a new object type Mutation and add it to your schema (in the mutation property next to query).
Create a field in this object type adopt that takes one argument id.
If a pet with the provided ID is found, udpate the field adopted for the given pet in the Mongo DB.
Which return type would you use for this mutation field? (ca. 15 minutes)
We are now switching to the frontend part.
Send a GraphQL query using window.fetch.
The request should query the pets field and return the name and type of the pet.
Create a state object that saves the result of our GraphQL query and an effect that runs when the component gets rendered:
const [result, setResult] = React.useState(null);
React.useEffect(() => {
// remember: No async/await in useEffect!
fetch(/* ... */).then(() => {
// ...
});
}, []);The query returns a data property with the result and potentially errors.
If the query returns an error inform the user about this situation and log the message to the console.
If the query returns data, render a list of pets in the frontend. (ca. 20 minutes)
Configure the Apollo GraphQL client as described here in App.js.
Don't forget to wrap your app with the ApolloProvider!
Replace your previous code with the useQuery hook from @apollo/client as described further down in the getting started tutorial. (ca. 10 minutes)
For each input row, if the pet is not adopted show a button adopt that runs the adopt mutation for this particular pet. (ca. 15 minutes)
Bonus: Disable the button while the mutation is fetching!
Install the graphql-scalars package from NPM.
Add a field to the pet model guestSince that saves the time of when the pet has been brought to the shelter. (ca. 5 minutes)
Bonus: Add an optional argument to the pets query: orderBy that takes an enum type GUEST_SINCE_ASC and GUEST_SINCE_DESC and return a sorted list from the pets field.
Add an optional argument to the pets query filter that takes an input object type with various filter options: (ca. 30 minutes)
input PetFilter {
type: PetType
adopted: Boolean
...
}Get creative! You made it till the end of this workshop. You now have all the tools you need to add more and more features to the pet shelter app.
The following resources are for you do recap the things discussed in the workshop.
- Introduction blog post from Lee Byron
- GraphQL the documentary by Honeypot
- Benefits of GraphQL - learning article by Apollo
- GraphQL over HTTP learning chapter and specification