Easily restore your project to a previous version with our new Instant One-click Backup Recovery

Top advantages and disadvantages of GraphQL

Let's explore the advantages and potential pitfalls of GraphQL.
Motunrayo Moronfolu

Motunrayo Moronfolu

Apr 18, 2024
Top advantages and disadvantages of GraphQL

Efficient data fetching isn’t just desirable for developing modern and data-driven applications — it’s essential. GraphQL bridges the gap between applications and data, eliminating the overhead of bulky data exchange and cumbersome API interactions.

We outline the top advantages of GraphQL in this article for developers considering adopting the query language. Meanwhile, we will also discuss GraphQL's disadvantages.

As a summary of this article, the top advantages of GraphQL are:

  • Declarative nature, which improves readability and enhances performance
  • Responses are only the data you need, reducing data under-fetching and over-fetching
  • Strong typing, ensuring type safety and consistency through the development phase
  • Flexible schema evolution, which provides backward compatibility for existing client apps

And, the disadvantages include:

  • Performance issues arising from managing complex data structures
  • Lack of in-built caching mechanism

We will explore this topic by analyzing query examples using Hygraph, a headless content management system (CMS) that leverages GraphQL API for data querying. Continue reading to uncover these benefits and pitfalls as they manifest in real scenarios.

#Advantages of GraphQL

To illustrate GraphQL's practical applications, we will use SKNCRE, an eCommerce starter powered by Hygraph.

Setting up an example application

Let’s set up Hypgraph’s SKNCRE project.

To begin, let’s navigate to the SKNCRE project starter:

undefined

Next, click "Clone the Hygraph project," redirecting us to a view where we’ll set the name and region for our SKNCRE project clone.

If you don’t yet have an account, you’ll be prompted to a free sign up.

undefined

After filling in the necessary fields, click "Clone now" to finalize the process. This action leads us to the project statistics page.

undefined

Now, checking your Hygraph account shows the SKNCRE project clone in the dashboard — it’s ready for use!

GraphQL’s declarative nature

GraphQL simplifies data querying by allowing developers to specify what data they need in a single query via a single GraphQL endpoint.

Unlike traditional REST APIs, where developers write intricate requests, GraphQL queries are concise and use a single API endpoint. This approach enhances readability and reduces the complexity of multiple REST requests for different data elements.

Let's use Hygraph’s API playground to see GraphQL’s declarative nature in action.

First, navigate to Content > Product Focus; here, you’ll see some information in the form fields of the “Product Focus” view:

undefined

After carefully inspecting the information in the fields above, navigate to the "API Playground" to craft a GraphQL query, given below the image, to fetch the data we saw in the “Product Focus” view.

undefined

Here‘s the query you’ll enter into the playground:

query MyQuery {
page(where: {slug: "home"}) {
components {
... on ProductHighlight {
id
productFocus {
cta
description
id
product {
id
ingredients
name
price
}
title
}
}
}
slug
}
}

In this query, we achieved the following:

  • We specified the page with the slug "home" using page(where: { slug: "home" })
  • We requested all components associated with that page using components
  • The ... on ProductHighlight fragment ensured we only focus on components of that type
  • Within each ProductHighlight, we fetched specific fields like id, title, and productFocus
  • The nested productFocus and product sections retrieved detailed product information
  • Finally, we also grabbed the page's slug

We can see that the query is structured clearly and concisely, specifying the exact data requirements, such as page components and specific GraphQL fields (id, title, etc.), without worrying about how the data is fetched or combined.

Responses are only the data you need

This is a key advantage of GraphQL: the server returns only the data explicitly requested in a query, including persistent queries.

This contrasts with traditional RESTful APIs, where responses often include a fixed set of data fields for a particular endpoint, potentially including more data than the client requires.

This approach offers several benefits:

1. Reduced overfetching: Frontend developers receive only the data they explicitly request, eliminating unnecessary data transfer and reducing response sizes compared to typical REST responses. This particularly benefits mobile applications or low-bandwidth environments where minimizing data transfer is crucial.

2. Eliminating underfetching: Clients can retrieve all required data in a single request, not making multiple round trips to the server for related data. This streamlines the development process and improves performance by reducing latency.

3. Improved performance: By minimizing the amount of data transferred over the network, GraphQL can enhance the performance of all applications, leading to faster response times and a smoother user experience.

4. Flexible query structure: Clients have control over the structure and content of the data they receive, allowing them to tailor queries to their specific requirements. This flexibility enables more efficient and precise data retrieval, reducing the need for additional requests to fetch missing or related data.

Let’s consider an example by querying the assets found in the SKNCRE project. In the playground shown below, we fetch the essential details for all assets, including their IDs, filenames, URLs, MIME types, sizes, widths, and heights.

undefined

Here is the query in the above playground:

query GetAllAssets {
assetsConnection {
edges {
node {
id
fileName
url
mimeType
size
width
height
}
}
}
}

Now, let’s try a minimized query where we only fetch the id and fileName for the assets in the project:

undefined

query GetAllAssets {
assetsConnection {
edges {
node {
id
fileName
}
}
}
}

As observed in the view above, GraphQL facilitates effortless modification of queries to retrieve specific fields or components based on our requirements without affecting the overall structure.

We can utilize our browser's built-in developer tools to assess the impact of this precise response return. By navigating to the network tab and filtering requests by type (e.g., XHR for GraphQL requests), we can examine the size of each response alongside the request details.

Upon inspection using my browser, the extensive query for all assets returned a size of 1.1 KB, whereas the lighter query showed 570 bytes. To determine the efficiency gained by the minimized query over the extensive query, we can employ the following formula:

Efficiency % = ((Extensive query size - Minimized query size) / Extensive query size) * 100

Substituting the values:

Efficiency % = ((1.1 - 0.57)/1.1) * 100
Efficiency % = (0.53/1.1) * 100
Efficiency % = 0.4818 * 100
Efficiency % = 48.18%

Therefore, the efficiency gained by the minimized query over the extensive query is approximately 48.18%.

Strong typing

GraphQL embraces strong typing principles at its core.

GraphQL's strong typing system is reflected in its Schema Definition Language (SDL) and enforced by GraphQL servers. The GraphQL schema field explicitly defines strict data types like String, Int, and Boolean for every field we query or mutate, guaranteeing that we only perform valid GraphQL operations.

GraphQL clients and tools leverage this schema, especially in complex systems, to provide type safety and inference, facilitate good error management, ensure consistency between client and server, and enable end-to-end typing.

Let’s look at the following query, which retrieves the assets in our SKNCRE project, and how it demonstrates GraphQL’s strong typing.

query GetAssests($first: Int, $skip: Int, $stage: Stage!, $where: AssetWhereInput, $orderBy: AssetOrderByInput, $locales: [Locale!]!) {
page: assetsConnection(
first: $first
skip: $skip
stage: $stage
where: $where
orderBy: $orderBy
locales: $locales
) {
edges {
node {
id
stage
updatedAt
createdAt
fileName
handle
height
id
mimeType
size
updatedAt
width
url
createdBy {
entryId: id
name
picture
kind
isActive
}
updatedBy {
entryId: id
name
picture
kind
isActive
}
localizations(includeCurrent: true) {
locale
updatedAt(variation: LOCALIZATION)
}
documentInStages(includeCurrent: true) {
id
stage
updatedAt
publishedAt
localizations(includeCurrent: true) {
locale
updatedAt(variation: LOCALIZATION)
}
}
}
}
aggregate {
count
}
}
}

From the query above, we saw the following on display:

1. Variable declarations

The query declares several variables ($first, $skip, $stage, $where, $orderBy, and $locales), each with specific data types (Int, Stage!, [Locale!]!, etc.). This enforces strong typing by specifying the expected data types for each variable.

2. Argument usage

These variables are used as arguments in the assetsConnection field. The types of these arguments must adhere to the schema's definition. For example, $stage is marked as non-nullable (Stage!), indicating that it must be provided and be of type Stage.

3. Field selection:

The query requests specific fields for assets (id, stage, updatedAt, etc.). These fields are predefined in the GraphQL schema, and their types are strictly defined.

The query achieves type safety and client-side code alignment with the schema through the above.

Similarly, on the server side, the GraphQL server enforces the types defined in the schema for these variables, guaranteeing that only valid operations are executed. This approach ensures that the server-side code operates with well-defined types, thus maintaining consistency and type safety within the server-side logic.

Both ends adhere to the same schema and utilize identical types for variables and fields between client and server, resulting in comprehensive end-to-end typing.

Simplification of complex queries

By crafting concise GraphQL queries tailored to specific requirements, developers can minimize network overhead and reduce the complexity of data fetching logic. This enhances performance by minimizing round trips to the server and improves developer productivity by providing a more intuitive and streamlined approach to querying data.

Let’s look at some examples demonstrating how GraphQL simplifies complex queries.

Filtering

query MyQuery {
pages(first: 10, where: {title_not_contains: "test"}) {
title
slug
description
createdAt
}
}

The query above retrieves pages with specific filtering criteria: it fetches the first 10 pages (if available) where the title does not contain the substring "test". It will return the available pages if we have below ten pages.

Sorting

query MyQuery {
pages(first: 10, orderBy: createdAt_ASC) {
title
slug
description
createdAt
}
}

This query retrieves the first 10 pages sorted by their creation date in ascending order (createdAt_ASC).

Combining filtering and sorting

query MyQuery {
pages(first: 10, where: {title_not_contains: "test"}, orderBy: createdAt_ASC) {
title
slug
description
createdAt
}
}
  • This query combines filtering and sorting logic to fetch pages.
  • It retrieves the first 10 pages where the title does not contain "test", sorted by creation date in ascending order.

In the examples provided above, we witnessed how GraphQL streamlines the complexity of queries by offering an intuitive syntax. This syntax seamlessly integrates filtering, sorting, and combining multiple logic within a single query and eliminates the need for additional endpoints or sorting logic on the client side. As a result, developers can craft queries with precision, specifying the exact response format expected by the client.

Flexible schema evolution

In contrast to traditional REST architecture, where changes often require versioning and can disrupt existing clients, GraphQL's schema flexibility enables developers to seamlessly modify and enhance the schema without disrupting existing client apps.

To see this in action, let’s retrieve all pages within the SKNCRE project. We begin by crafting a query within the Hygraph API playground like so:

query GetPages {
pages {
description
createdAt
title
slug
}
}

This initial query fetches page data, including descriptions, creation dates, titles, and slugs.

What about a scenario where the client requests additional information about page publication and updates? With GraphQL's flexibility, we can seamlessly integrate these new requirements into the existing query:

query GetPages {
pages {
description
createdAt
title
slug
publishedAt
updatedAt
}
}

By adding the additional fields publishedAt and updatedAt clients can access the updated data without disruption. Moreover, thanks to GraphQL's backward compatibility, clients that don't require these new fields can continue to make queries without modification. This ensures uninterrupted functionality for existing queries using the GetPages initial schema structure.

Data introspection

GraphQL empowers developers with immediate access to schema information, leading to several rapid developer experience upgrades, such as:

1. Streamlined exploration:

Powerful tools like GraphiQL and Hygraph's built-in API playground act as interactive sandboxes for developers to instantly query the schema and explore available types, fields, and relationships without relying on external documentation. This intuitive discovery process reduces exploration time and fosters a deeper understanding of the data landscape.

2. Error prevention at warp speed:

Introspection enables early error detection. Instead of waiting for runtime errors, the GraphQL server, equipped with schema knowledge, can flag the issue immediately, saving precious debugging time and frustration.

3. Efficient documentation generation:

Manually documenting extensive APIs can be tedious. But with introspection, tools can automatically generate interactive, up-to-date documentation based on the live schema. This ensures that documentation always reflects the latest data structure, saving developers the burden of manual maintenance.

4. Seamless collaboration:

Introspection promotes a shared understanding of the data model. Team members can easily explore the schema, discuss data structures, and share queries through interactive tools, fostering efficient collaboration and knowledge sharing.

#Disadvantages of GraphQL

GraphQL offers numerous advantages, but like almost every technology, its pitfalls must be acknowledged to avoid unintended consequences.

Performance issue

One challenge with GraphQL as stated in the 2024 GraphQL Report is managing potential performance issues caused by complex data structures, relationships, and nested field selections. This leads to excessive data processing overhead and performance bottlenecks for frontend applications.

By using the "x-inspect-complexity": true header in the API playground, Hygraph analyzes the query complexity weighting regarding the computational resource consumption and optimization prompts to improve performance.

Inefficient requests

Another potential challenge is related to accidental over-fetching and under-fetching of data. GraphQL allows precise querying, but inexperienced developers might request more data than necessary, causing inefficient requests. However, with Hygraph’s schema builder, developers of all skill levels can eliminate these potential “accidents” and create efficient queries.

Lack of in-built caching mechanism

The lack of built-in caching methods in GraphQL can lead to suboptimal performance, especially in scenarios with frequent requests and updates. Hygraph mitigates this issue by providing a caching mechanism through its Content APIs delivered globally via distributed edge caches.

#Conclusion

By closely examining its practical applications using Hygraph’s SKNCRE project, we gained valuable insights into GraphQL’s strengths and weaknesses.

GraphQL is a robust query language liked by developers for its structured data, ease of use, type-checking, and many other strengths. If you are considering using GraphQL in production, check out our GraphQL Report 2024, where we learn how the community solves obstacles and best practices from GraphQL experts.

The GraphQL Report 2024

Statistics and best practices from prominent GraphQL users.

Check out the report

#References

Here are a few additional resources that could prove helpful:

Blog Author

Motunrayo Moronfolu

Motunrayo Moronfolu

Technical writer

Motunrayo Moronfolu is a Senior Frontend Engineer and Technical writer passionate about building and writing about great user experiences.