✔️ Learn GraphQL API concept
✔️ Interact with a GraphQL API
✔️ Define your own GraphQL schema
✔️ Build a basic GraphQL API
✔️ Use GraphQL in a React application
All the required information to start this workshop can be found in SETUP.md.
Last week, your best friend told you about a great technology that allows you to create an API in just a few lines without going through the traditional architecture: GraphQL APIs.
Thanks to this technology, he had fun on the public API of the World Map to make a small site about the different continents and countries.
Curious by nature and looking for something new, you decide to set up your little online store project with this new technology.
Your first reflex is to try the World Map API to play with GraphQL and understand its concepts.
- Go to World Map API: https://countries.trevorblades.com
Let's do some queries to retrieve data:
- Retrieve all continents' code, name and all their countries' code, name and capital.
- Retrieve the code, name, currency and its states' code and name of the country with
FR
code.
It's time to try GraphQL, the simplest and most popular library is Apollo server.
Create a folder named backend
to develop your API.
Download the source and extract it in the backend
folder.
Your directory should have the following structure:
├── prisma
│ └── schema.prisma # Database
├── src
│ ├── context.ts # Integrate database to API Context
│ ├── feeds
│ │ └── feed.ts # Feed database
│ ├── helpers
│ │ └── Errors.ts # Apollo custom errors
│ ├── resolver # All resolvers (queries and mutations)
│ │ ├── Categories
│ │ │ ├── index.ts
│ │ │ ├── mutations.ts
│ │ │ └── queries.ts
│ │ ├── Hello
│ │ │ ├── index.ts
│ │ │ ├── mutations.ts
│ │ │ └── queries.ts
│ │ ├── index.ts
│ │ └── Products
│ │ ├── index.ts
│ │ ├── mutations.ts
│ │ └── queries.ts
│ ├── schema
│ │ └── schema.graphql # GraphQL schema
│ ├── schema.ts # Compute schema and resolver
│ └── server.ts # Apollo Server
├── .gitignore # Tells git which files (or patterns) it should ignored
├── package.json # Package manager
├── tsconfig.json # Typescript configuration
└── yarn.lock # Dependencies file
To start the project, execute the following commands:
With yarn
yarn # Install dependencies
yarn migrate # Init database and prisma client
yarn dev # Start server in developer mode
With npm
npm install # Install dependencies
npm run migrate # Init database and prisma client
npm run dev # Start server in developer mode
Go to http://localhost:5000 to reach the local playground of your API.
We will start with some basic function to warm up, let's write:
- a query named
hello
that returns thestring
"Hello World" - a query named
personalHello
that takes astring
as parameter and returns: "Hello " + the parameter - a mutation named
add
that takes two numbers as parameters and returns the additive
First, you must modify the schema in src/schema/schema.graphql
to define your query and mutation.
Then you can define your queries and mutation in src/resolver/Hello/
folder.
💡 You can auto feed your database through the
yarn feed
.
Warm up is finished. It's time to create the schema that define our API.
The database schema is already defined in prisma/schema.prisma
.
First, you must modify src/schema/schema.graphql
to implement two new types:
Category
that has the same fields as modelCategory
inschema.prisma
.Product
that has the same fields as modelProduct
inschema.prisma
.
Then, create resolvers that can read of Category
and Product
:
- a query
categories
that return all categories - a query
category
takes anid
as parameter and returns the category. - a query
products
that return all products - a query
product
takes anid
as parameter and returns the product.
💡 You can add comments that will be displayed in the playground with
"
.
You can now write resolvers
in src/resolver/Categories
and src/resolver/Products
.
Now that you have queries to read data, it's time to modify our products and categories.
In src/schema/schema.graphql
:
Create two input
that defines arguments for mutation:
CategoryInput
: input fields for a new categoryProductInput
: input fields for a new product
💡 Don't forget to add fields from relation to allow connection between entities.
Add the following Mutation
in src/schema/schema.graphql
:
createProduct
that takes aninput
of typeProductInput
as parameter and returns the product created in the database.updateProduct
that takes anid
and aninput
of typeProductInput
as parameters and returns the product updated in the database.deleteProduct
that takes anid
as parameter and returns the product deleted from the database.createCategory
that takes aninput
of typeCategoryInput
as parameter and returns the category created in the database.updateCategory
that takes anid
and aninput
of typeCategoryInput
as parameters and returns the category updated in the database.deleteCategory
that takes anid
as parameter and returns the category deleted from the database.
💡 Don't forget to write documentation for your mutation and queries with commentaries
Your schema is defined, you can now write resolvers
in src/resolver/Categories
and src/resolver/Products
.
In case of errors (e.g: a negative product price): you should use custom Apollo errors defined in src/helpers/Errors.ts
.
Now that you have finished your API, it's time to develop your web application.
Go back to the root of the workshop's folder and create a new folder fronted
.
Download the source and extract it in the frontend
folder.
Your directory should have the following structure:
├── public # Public directory with not important stuff
├── src
│ ├── api # API connection and types definition
│ │ ├── client.ts
│ │ └── Entities.ts
| ├── app
│ │ ├── App.css
│ │ └── App.tsx # App root
| ├── components
│ │ └── AppBar.tsx # Top Bar
│ ├── index.css
│ ├── index.tsx # Index
│ └── react-app-env.d.ts
├── .gitignore # Tells git which files (or patterns) it should ignored
├── package.json # Package manager
├── README.md # Default README.md when creating a React App
├── tsconfig.json # Typescript config
└── yarn.lock # Dependencies lock
To start the project, execute the following commands:
yarn # Install dependencies
yarn start # Start server in developer mode
The objective is to have a simple front with a menu that shows the list of all products. Here is an example made with the material UI library:
Create a new component ProductsList
that lists all products existing in the database.
To do it, you must use useQuery Apollo hook and React.
If you are not familiar to react, take a loot at this documentation.
You know how to create a GraphQL and interact with it from frontend through the apolloClient
.
You should now implement more functionalities like:
- User management
- Button and forms to add products
- Page Routing
- A button to delete and update products
- A button to sell and add products
- Auto generate your schema with Nexus
- Mix GraphQL with Graph database though DGraph
- Integrate GraphQL with Relay
- Understand GraphQL security problems to avoid it
Tom Chauveau |
---|
🚀 Don't hesitate to follow us on our different networks, and put a star 🌟 on
PoC's
repositories.