Skip to content
Dev Discovers

A Beginner's Guide to GraphQL

graphql8 min read

GraphQL is a query language for APIs developed by Facebook and released as an open-source project. It provides a flexible and efficient way to retrieve data from a server, allowing clients to request exactly what they need and nothing more.

What Exactly Is GraphQL?

GraphQL is a query language for APIs that defines a schema that describes the types of data available and the relationships between them. It enables clients to send queries to the server to request specific data in a structured and efficient way. Clients can request multiple resources in a single request and specify the exact fields they need. The server responds with a JSON object that matches the shape of the query.

How Is GraphQL Different From REST?

REST (Representational State Transfer) is a set of architectural principles for building APIs that uses HTTP methods (GET, POST, PUT, DELETE) to retrieve, create, update, and delete resources. In a RESTful API, clients interact with resources identified by URIs. REST APIs have a fixed structure and typically return the same data for a given endpoint.

In contrast, GraphQL provides a flexible and dynamic approach to retrieving data, allowing clients to request only the data they need and in the exact shape they want. It uses a single endpoint and a schema that describes the types and relationships of the available data.

Benefits of Using GraphQL

GraphQL offers several advantages over traditional REST APIs:

  • Efficient data retrieval: Clients can request exactly what they need and nothing more, reducing the amount of data transferred over the network and improving performance.
  • Flexibility: Clients can specify the exact shape of the response they want, reducing the need for multiple endpoints and reducing overfetching (retrieving more data than necessary).
  • Self-documenting: The schema describes the available data types and relationships, making it easier for clients to understand how to interact with the API.
  • Strongly typed: GraphQL enforces a strict type system that ensures data consistency and provides better error handling.
  • Real-time updates: GraphQL supports subscriptions, allowing clients to receive real-time updates when data changes on the server.

Structure of a GraphQL Query and Schema

A GraphQL query consists of a set of fields that define the data to be retrieved from the server. Each field can have arguments that specify filtering, sorting, and pagination options. The query is sent to the server over a single endpoint, which responds with a JSON object that matches the shape of the query.

Here's an example of a GraphQL query with filtering, sorting, and pagination:

query {
products(
filter: { category: "electronics", price: { gte: 100 } }
sort: { field: price, direction: ASC }
pagination: { first: 10, after: "eyJpZCI6MjB9" }
) {
edges {
node {
id
name
price
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}

In this example, we're querying for products that belong to the "electronics" category and have a price greater than or equal to 100. We're also sorting the results by price in ascending order and requesting the first 10 results after the cursor "eyJpZCI6MjB9".

If this query was stored in a file called query.graphql, here's how you would call a GraphQL endpoint https://example.com/graphql using cURL:

curl -X POST -H "Content-Type: application/json" -d @query.graphql https://example.com/graphql

Here's an example response to that query:

{
"data": {
"products": {
"edges": [
{
"node": {
"id": "5432",
"name": "Samsung Galaxy S21",
"price": 1099.99
},
"cursor": "eyJpZCI6NTQzMn0="
},
{
"node": {
"id": "9876",
"name": "Apple MacBook Pro",
"price": 1500.00
},
"cursor": "eyJpZCI6OTg3Nn0="
}
],
"pageInfo": {
"hasNextPage": true,
"endCursor": "eyJpZCI6NTR8kn0="
}
}
}
}

A GraphQL schema defines the types of data available and their relationships. It consists of type definitions that specify the fields, arguments, and return types of each type. The schema also defines queries, mutations, and subscriptions, which correspond to the operations that can be performed on the data. We'll dive into some examples in the following sections.

Types and Fields in GraphQL

GraphQL supports several built-in scalar types, including Int, Float, String, Boolean, and ID. It also supports custom object types that can be composed of scalar types and other object types. Each object type can have fields that specify the data to be retrieved. Fields can be scalar types or object types, and can have arguments that specify filtering, sorting, and pagination options.

Here's an example of some custom object types that utilizies both built-in scalar types and other custom object types:

type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
comments: [Comment!]!
}
type Comment {
id: ID!
text: String!
author: User!
post: Post!
}

Operations in GraphQL

GraphQL supports three types of operations: queries, mutations, and subscriptions.

Queries

A query is used to retrieve data from the server. It consists of one or more fields that specify the data to be retrieved.

Here's an example of a query that retrieves the name and email of a user:

query {
user(id: "123") {
name
email
}
}

Mutations

A mutation is used to create, update, or delete data on the server. It consists of one or more fields that specify the changes to be made to the data.

Here's an example of a mutation that creates a new user:

mutation {
createUser(input: {
name: "John Doe"
email: "john@example.com"
}) {
id
name
email
}
}

Subscriptions

A subscription is used to receive real-time updates when data changes on the server. It consists of one or more fields that specify the data to be retrieved and a subscription operation that listens for changes.

And here's an example of a subscription that listens for changes to a user's name:

subscription {
userUpdated(id: "123") {
name
}
}

Resolvers and Data Sources in GraphQL

Resolvers are functions that retrieve data for each field in a GraphQL query. They are responsible for fetching data from data sources (such as databases or APIs) and returning the data in the expected shape.

Data sources are the underlying systems that provide the data to the GraphQL server. They can be databases, APIs, or any other system that provides data. GraphQL servers can integrate with multiple data sources and combine the data in a single response.

How to Start Using GraphQL

If you are looking to build a GraphQL API, you'll need to set up a GraphQL server that defines a schema and resolvers. You can use a framework like Apollo Server, which provides a set of tools and conventions for building GraphQL servers. You can also use AWS AppSync if you want a fully managed GraphQL service.

On the client side, if you want to use a GraphQL API, you can send operations to the server using HTTP like you would for a REST API. You can also utilize a client library like Apollo Client, which provides a set of tools and conventions for building GraphQL clients.

Best Practices for Building GraphQL APIs

Here are some best practices for designing and implementing GraphQL APIs:

  • Start with a clear schema: Define the types of data available and their relationships upfront. This will make it easier for clients to understand how to interact with the API.
  • Use descriptive names: Use descriptive names for types, fields, and arguments that reflect their purpose.
  • Be consistent: Use consistent naming conventions and field structures throughout the schema.
  • Use pagination: Use pagination to limit the amount of data returned in a single query and allow clients to retrieve large datasets in smaller chunks.
  • Use caching: Use caching to improve performance and reduce the load on the server.

Common Pitfalls to Avoid When Building GraphQL APIs

  • Overfetching: Be careful not to retrieve more data than necessary. Use field selection and pagination to limit the amount of data returned.
  • N+1 queries: Be careful not to make multiple queries to retrieve related data. Use batched queries or dataloading to reduce the number of queries.
  • Security: Be careful not to expose sensitive data or allow unauthorized access. Use authentication and authorization to restrict access to data.

Final Thoughts

GraphQL is a powerful query language that enables efficient and flexible communication between client applications and server APIs. Unlike traditional REST APIs, which require multiple requests to retrieve data, GraphQL allows clients to specify the exact data they need in a single request. This reduces network traffic and improves performance, especially on mobile devices with limited bandwidth.

GraphQL's type system and schema validation make it easy to maintain and evolve APIs over time, without breaking existing clients. Its modular architecture and tooling ecosystem also make it a popular choice for building modern web and mobile applications.

While GraphQL may require some additional setup and learning curve compared to traditional REST APIs, its benefits in terms of performance, flexibility, and maintainability make it a compelling choice for many developers and organizations. As web and mobile applications continue to grow in complexity, GraphQL is likely to become an increasingly important tool for building scalable and efficient APIs.

© 2023 by Dev Discovers. All rights reserved.
Theme by LekoArts