This article was originally posted on Hackmamba.
An application programming interface (API) is a software interface that allows applications to talk to each other. With APIs, we can log in to our favourite platforms, check out Google Maps, and, more commonly, query or interact with a database.
An exciting development in how we collect data via APIs is the GraphQL query language.
Through this article, we will examine why we should use the GraphQL API in our next project with step-by-step implementation.
Prerequisites
To follow through, we need the following:
- A basic understanding of JavaScript and React.js
- Docker Desktop installed on our computer; run the
docker -v
command to verify that we have Docker Desktop installed and if not, install it from the Get Docker documentation - An Appwrite instance running on our computer, check out the Appwrite documentation to learn how to create a local Appwrite instance
- A Next.js application, check out the Next.js documentation to learn how to create a new Next.js application
What is GraphQL?
GraphQL is an open-source data query and manipulation language for APIs and a runtime for fulfilling queries with existing data. Developed by Meta (formerly named Facebook), GraphQL allows clients to define the structure of the data they need from the database and this structure is returned from the server.
With GraphQL becoming increasingly popular, this article aims to discuss its benefits, the need for Appwrite's GraphQL protocol, and finally, how to implement Appwrite's GraphQL protocol in our next project.
The benefits of using GraphQL APIs
With more developers opting to use GraphQL APIs instead of the very popular REST APIs, we must understand the advantages that GraphQL gives us over the traditional REST APIs.
- GraphQL is faster
GraphQL allows us to query the specific data we want from our database. With GraphQL cutting down our query requests, querying data with GraphQL APIs becomes faster than other communication APIs, improving the overall developer experience.
- Fetch Data in a single API call
Fetching data and manipulating data with REST APIs sometimes require us to write different API calls to different endpoints. GraphQL focuses on the tasks and uses one endpoint, the graphql
endpoint. GraphQL can fetch all the data we need with one API call.
- No over- and under-fetching information
REST APIs are notorious for containing too much or insufficient information in their responses. This over- and under-fetching problem results from data scattered across different endpoints. GraphQL solves this problem by allowing us to fetch the exact data we need in a single request.
- Validation and type checking out-of-the-box
With GraphQL, we can ensure that the application only queries the data we have in our database in its appropriate format.
GraphQL also validates the data format for us.
- API evolution without versioning
REST and GraphQL APIs deal with evolving APIs differently. REST APIs commonly offer new versions to deal with evolving APIs. GraphQL, however, deprecates APIs on a field level, thereby removing the need for different versions.
We can remove aging fields from the schema without affecting the existing fields or queries.
Common Challenges With GraphQL
As with any good development in technology, challenges might arise when using GraphQL and these challenges are discussed in the paragraphs below:
- Performance issues with complex queries.
GraphQL allows us to query for the exact data we need, but performance issues arise when we query for too many nested fields and resources.
- Web caching complexity.
Compared to GraphQL, REST APIs have multiple endpoints, allowing them to leverage native HTTP caching to avoid re-fetching resources or data whenever a client requests them.
As GraphQL uses only one endpoint, /graphql
, caching becomes difficult, as we would need to set up our caching support, possibly with an external library.
- It takes a while to understand.
GraphQL is a lot more complex to understand than the traditional REST APIs. Implementing GraphQL usually requires some prior knowledge like understanding the Schema Definition Language, etc. While GraphQL offers amazing benefits, as explained in the section above, learning and implementing simple GraphQL queries can take some time.
The Need for Appwrite's GraphQL Protocol
Now that we have discussed the challenges of implementing GraphQL in a production environment, this section tells us how Appwrite's GraphQL protocol addresses these challenges.
- Security
GraphQL exposes a single endpoint for all queries and mutations, making it more difficult to implement traditional security measures such as rate limiting and access control.
Appwrite addresses security concerns by using secure cookies and API keys to restrict data to specific identities, as well as rate limiting, a maximum amount of queries allowed to execute per request, a maximum query complexity, and a maximum query depth to mitigate abuse.
- Caching
As discussed under "Common Challenges with GraphQL", GraphQL lacks built-in caching support because it uses one endpoint,/graphql
.
Appwrite, on the other hand, handles caching at a few different levels, first with HTTP headers and later with some data stores and memory caching for specific resources.
- Error Handling
Appwrite has explicit and descriptive error messages, making it easy to understand a problem regardless of the status code.
- Reduce the learning Curve
GraphQL is easier to write with Appwrite as we do not need to worry about creating our GraphQL server or schema.
Implementing GraphQL in your Next.js Project (with Appwrite)
Understanding the importance of Appwrite's GraphQL protocol, we need to know how to implement them in our Next.js project.
Creating a new Appwrite project
When we created an Appwrite instance during the prerequisites section, we specified what hostname and port our console would live in. The default value is localhost:80.
Go to localhost:80 and create a new account to see the console.
On our console, there is a "Getting Started Guide" page. We choose the "Web App" option under "Add a Platform".
Next, we register our Web app.
We add the Appwrite SDK to our project by running this terminal command in our root directory.
cd <our project name>
npm install appwrite
In our project's root directory, we create a .env.local
file to store our project ID.
NEXT_PUBLIC_PROJECT_ID= *******
In our index.jsx
file, we initialize our Appwrtite web SDK.
import { Client, Graphql } from "appwrite";
const client = new Client()
client
.setEndpoint('http://localhost/v1')
.setProject(process.env.NEXT_PUBLIC_PROJECT_ID);
const graphql = new Graphql(client)
Connecting to the Appwrite Locale API with GraphQL
This section discusses how to query continent names from the Appwrite Locale API using Appwrite's GraphQL protocol.
Creating the continent select button
Through the Appwrite Locale API, GraphQL can query only the continent names without additional information. We paste this code in our index.jsx
file to query this data.
import Head from 'next/head'
import styles from '@/styles/Home.module.css'
import { Client, Graphql } from "appwrite";
import { useEffect, useState } from 'react';
const client = new Client()
client
.setEndpoint('http://localhost/v1')
.setProject(process.env.NEXT_PUBLIC_PROJECT_ID);
const graphql = new Graphql(client)
const Home = () => {
const [continents, setContinents] = useState([])
const getContinents = async() => {
try{
const q = (await graphql.query({
query: `query {
localeListContinents {
total
continents{
code
name
}
}
}`,
}))
setContinents(q.data.localeListContinents.continents);
}catch(error){
const appwriteError = error
throw new Error(appwriteError.message);
}
}
useEffect(()=> {
getContinents()
}, [])
return (
<div>hello world</div>
)
}
export default Home;
In the code block above, we do the following:
- Create state variables to store the response from our GraphQL query
- Get all the names of the continents in the world using Appwrite's Locale API. We specify that we want only the continent names and the code to know if the query is successful or not
- Save the GraphQL response in our state variables
- Throw any error we encounter while querying the information
- Use the
useEffect
hook to call thegetContinents()
function once the page mounts
Rendering the GraphQL response
In this section, we will loop through the GraphQL response and render options in the select
dropdown.
return (
<div>
{
continents ? (
<select name="continents" id="continents">
{
continents.map((continent) => (
<option value={continent.name}>{continent.name}</option>
))
}
</select>
) : null
}
</div>
)
In the code block above, we:
- Make sure the
continents
state variable is not empty before rendering its values - Loop through the continents and render them as options in the
select
dropdown
After this section, here is how our application looks.
Conclusion
GraphQL is a fascinating development in the software space. With its strength in specialised queries, we can make quick and impactful API calls to our database. This article discusses GraphQL, its advantages and disadvantages, the need for Appwrite’s GraphQL protocol, and how to implement the query language in our next project.
Resources
The following resources are helpful: