Jump To Section
Need a better query language for APIs? If you’re a developer or a professional associated with the field, chances are you’ve heard of these terms “API” “Rest” “GraphQL”.
And while it’s one of the most frequently used words in the world of development these days, most individuals, despite coming across it or using it, won’t be familiar with exactly what an API is.
What is an API?
API stands for Application Programming Interface. As the name implies, it is an interface via which developers, users, and consumers can interact with data.
To understand how an API works, try comparing it to a bartender: You order a drink from the bartender, they locate the right liquor, ice, and other ingredients, and prepare it for you. No big deal about that, right?
Building an API hasn’t been as difficult as it sounds since the dawn of the contemporary web. However, learning and comprehending APIs, on the other hand, has always been a challenge.
Developers form the majority of individuals who will use your API to build something or merely consume data. Therefore, your API should be as simple and straightforward as possible, if you want them to remain feasible.
A well-designed API is simple to use and understand. It is also user-friendly, which is something to keep in mind when you get started with creating your API.
REST Vs. GraphQL APIs
For a long time, REST has been used to create APIs.
But with using REST APIs – and the reason that has ignited the REST vs. GraphQL APIs comparisons – comes the slew of issues that come with it.
While using the REST design to create an API, you’re very likely to run into hurdles like:
- Too many endpoints
- Information repeatedly being over and under-fetched
- Increased difficulty for developers to learn and understand your API
To address these issues, Facebook designed GraphQL, which, in my opinion, is the greatest method to design APIs these days.
In this article, you’ll not only learn what a GraphQL API is and why you should begin learning GraphQL right away, but also how to use GraphQL to develop a well-designed, efficient, and powerful API.
What is GraphQL?
Is GraphQL a programming language?
GraphQL, or “Graph Query Language,” is a query language for APIs, as the name implies. It allows the client (frontend) to request data from an API.
Since GraphQL is open-source, it has garnered a large community of users and is being adopted quickly by people and businesses.
In fact, that’s probably why you’ve heard of it as well – due to the open-source GraphQL APIs. The earlier you learn how GraphQL works, the sooner you’ll be able to experience the beauty of practicing it.
Getting Started: How GraphQL Works
Our first goal with this GraphQL starter guide is not to teach you how to set up a GraphQL server but to learn GraphQL in practice.
So for that, we’ll use GraphPack, a zero-configuration GraphQL server.
- To begin our project, we’ll make a new folder, which you can name whatever you wish. For the sake of this guide, let’s name it “Graphql-server”.
Type the following into your terminal:
mkdir graphql-server
Your system should now have npm or yarn installed. If you’re unfamiliar with these, npm and yarn are package managers for the JavaScript programming language. The default package manager for Node.js is npm.
- Next, type the following command within your newly created folder:
npm init -y
or you can use yarn:
yarn init
Npm will generate a package.json file for you, containing all of the dependencies you installed as well as your commands.
- Now, we’ll install the one and only dependency that we’ll be using.
Graphpack allows you to quickly set up a GraphQL server with no setup required. Since we’re just getting started with GraphQL, this will make it much easier for us to continue learning how GraphQL works without having to worry about server configuration.
Install it like this in your console, within your root folder:
npm install --save-dev graphpack
- After you’ve installed Graphpack, browse to the package.json file and add the following code to the scripts section:
"scripts": {
"start:dev": "graphpack",
"start:build": "graphpack build"
}
We’re going to make a folder called src, which will be the sole folder on our entire server.
Create a folder called src, and then create only three files within that folder.
- Make a file called schema.graphql in the src folder, and put the following code into the first file:
type Query {
hello: String
}
Our full GraphQL schema will now be stored in this schema.graphql file, and I’ll explain what that is later.
- Create a second file in the src folder now. Create a new file called resolvers.js and paste the following code into it:
import { users } from "./db";
const resolvers = {
Query: {
hello: () => "Hello World!"
}
};
export default resolvers;
The instructions for converting a GraphQL operation into data will be provided in this resolvers.js file.
- Finally, make a third file inside your src folder. Name this db.js and paste the following code into the third file:
export let users = [
{ id: 1, name: "Adil Sikandar", email: "adil@gmail.com", age: 28 },
{ id: 2, name: "Shahid ullah khan", email: "shahid@gmail.com", age: 29 }
];
Since, in this tutorial, we’re not using a real-world database, this db.js file will simulate a database we can use for the purpose of learning GraphQL.
Now our src folder should look like this:
src
|--db.js
|--resolvers.js
|--schema.graphql
You should be able to see this output in your terminal if you run the command npm run start:dev or, if you’re using yarn, yarn start:dev.
Now, you can access localhost:4000 – this means we’re ready to begin creating our first GraphQL queries and mutations, but before jumping into those, let’s quickly address some commonly used terms associated with GraphQL.
GraphQL Schema
GraphQL has its own set of languages for writing schemas. The Schema Definition Language is a human-readable schema syntax (SDL). No matter what technology you use, the SDL will remain the same, and you can use it with whatever language or framework you wish.
This schema language is quite useful since it makes it very clear what types of APIs will be offered, which you can figure out by simply looking at it.
Types: Learning How to Use GraphQL
One of the most vital characteristics of GraphQL is types.
Types are unique objects that represent the look and feel of your API. If you’re creating a social media app, your API should have types like Posts, Users, Likes, and Groups.
There are fields that exist in these types, and each field returns a certain type of data. For example, if we’re going to make a User type, we’ll need fields for name, email, and age.
Type fields can be anything, but they must always return a data type such as Int, Float, String, Boolean, ID, a List of Object Types, or Custom Object Types.
Let’s construct our first Type. Open your schema.graphql file and replace the existing type Query with the following:
type User {
id: ID!
name: String!
email: String!
age: Int
}
This is where the primary principles in GraphQL will kick in, and you’ll learn about them next.
Queries & Mutations
The way you acquire data from the server is through queries.
And the method through which you’ll be able to modify data on the server and receive updated data (create, update, delete) is known as mutations.
Queries
To put it another way, queries in GraphQL are the means through which you can obtain data.
One of the most appealing qualities of GraphQL queries is that you will only receive the data you require – not more, not less.
This has a big impact on our API in terms of avoiding the issue of over-fetching or under-fetching data like what would happen with REST APIs.
In GraphQL APIs, we define our first type Query. This is where all of our questions will end up.
To begin with this, we’ll create a new type called Query in our schema.graphql file.
type Query {
users: [User!]!
}
Understanding this is fairly straightforward: the users query returns an array of one or more Users. Because we used the “!”, it will not return null, indicating that it is a non-nullable query, and meaning it should always provide a response.
We might, however, retrieve a specific user.
To do so, we’ll construct a new query called user. Put the following code within the Query type:
user(id: ID!): User!
type Query {
users: [User!]!
user(id: ID!): User!
}
As you can see, we can pass arguments with GraphQL requests. In this scenario, we’ll use the ID to search for a specific user.
By this point, you might be questioning how GraphQL knows where to acquire the data. This is why we need a resolvers.js file, which instructs GraphQL on how and where to obtain data.
To get started with that, open the resolvers.js file and import the db.js file that we just built. Your resolvers.js file should look like the following:
import { users } from "./db";
const resolvers = {
Query: {
hello: () => "Hello World!"
}
};
export default resolvers;
Now, we’re going to make our first query.
import { users } from "./db";
const resolvers = {
Query: {
user: (parent, { id }, context, info) => {
return users.find(user => user.id === id);
},
users: (parent, args, context, info) => {
return users;
}
}
};
export default resolvers;
To see if the queries are working properly, go to localhost:4000, type in your address, and paste the following code into it:
query {
users {
id
name
email
age
}
}
All of the users should be returned to you.
Alternatively, if you wish to return a specific user, type:
query {
user(id: 1) {
id
name
email
age
}
}
Mutations
Once you’ve got a good understanding of GraphQL queries, mutations come as the next step.
Mutations are the technique used to edit data on the server and update data back in GraphQL.
In GraphQL, we’ll make our initial type mutation, and all subsequent alterations will be contained within this type.
To begin, open the schema.graphql file and add a new type called mutation:
type Mutation {
createUser(id: ID!, name: String!, email: String!, age: Int): User!
updateUser(id: ID!, name: String, email: String, age: Int): User!
deleteUser(id: ID!): User!
}
Create a new mutation object like this in the resolvers.js file, below the Query object:
Mutation: {
createUser: (parent, { id, name, email, age }, context, info) => {
const newUser = { id, name, email, age };
users.push(newUser);
return newUser;
},
updateUser: (parent, { id, name, email, age }, context, info) => {
let newUser = users.find(user => user.id === id);
newUser.name = name;
newUser.email = email;
newUser.age = age;
return newUser;
},
deleteUser: (parent, { id }, context, info) => {
const userIndex = users.findIndex(user => user.id === id);
if (userIndex === -1) throw new Error("User not found.");
const deletedUsers = users.splice(userIndex, 1);
return deletedUsers[0];
}
}
Our resolvers.js file should now look something like this:
import { users } from "./db";
const resolvers = {
Query: {
user: (parent, { id }, context, info) => {
return users.find(user => user.id === id);
},
users: (parent, args, context, info) => {
return users;
}
},
Mutation: {
createUser: (parent, { id, name, email, age }, context, info) => {
const newUser = { id, name, email, age };
users.push(newUser);
return newUser;
},
updateUser: (parent, { id, name, email, age }, context, info) => {
let newUser = users.find(user => user.id === id);
newUser.name = name;
newUser.email = email;
newUser.age = age;
return newUser;
},
deleteUser: (parent, { id }, context, info) => {
const userIndex = users.findIndex(user => user.id === id);
if (userIndex === -1) throw new Error("User not found.");
const deletedUsers = users.splice(userIndex, 1);
return deletedUsers[0];
}
}
};
export default resolvers;
Next we’ll see if our mutations are operating properly. Go to localhost:4000 and type in your address, then paste the following code into it:
mutation {
createUser(id: 3, name: "Adil", email: "adil.sikandar@mobilelive.ca", age: 28) {
id
name
email
age
}
}
With that, it should give you a new user. If you wish to experiment with novel mutations, I recommend that you do so! To see if it’s still working, try deleting the same user you created.
Takeaway
As you’ve probably learned by now, GraphQL is a relatively new yet extremely powerful technology.
Exceeding far beyond the traditional REST API model, and offers the ability to create better and more well-designed APIs, disrupting the existing API economy and changing the game for developers at large while giving rise to GraphQL developers.
With a landscape as volatile as what we’ve been witnessing with the progress in development and technology, learning QL and how it works is the only way to prepare ourselves for when, eventually, REST APIs are replaced by GraphQL.