AlgoMaster Logo

Why GraphQL?

High Priority10 min readUpdated September 13, 2026
Listen to this chapter
Unlock Audio

Different screens often need different views of the same data. A bookstore's mobile app might need only a book's title and author names, while its website also needs a description and author biographies. Both use the same catalog, but as the products grow, a response that serves one screen can contain unnecessary fields or lack needed fields for another.

GraphQL gives clients a structured way to ask for the fields and relationships they need.

This chapter explains the problem it addresses, how its approach differs from typical REST APIs, and when that flexibility justifies the additional server responsibilities.

1. Different Clients, Different Data Needs

Suppose a bookstore exposes GET /books/{bookId}. This public operation returns the following response for an available book:

The mobile app uses id and title, but it does not display the description, ISBN, or page count. Receiving fields it does not need is over-fetching. A few unused fields may cost little, but long descriptions and large collections can make the difference measurable.

The response also lacks the author's name. The client must request GET /authors/au_27 after learning the author ID. Needing additional requests because the first response lacks required data is under-fetching.

The same response can cause both problems: it contains unnecessary fields while leaving out a necessary relationship.

This flow shows the dependency in this particular API design:

The second request depends on the first response. Faster connection handling does not remove that dependency. On a high-latency connection, the extra round trip can matter more than the unused bytes.

These are consequences of the chosen representation, not requirements that REST imposes. The server could embed author details, support field selection, or provide an aggregate response. GraphQL offers a common language for expressing these needs when they recur across many clients and relationships.

2. Client-Selected Fields Within a Server Contract

GraphQL is a query language for APIs and a specification for validating and executing operations. A schema defines the available types, fields, arguments, and relationships. Clients select from that contract; the server remains responsible for deciding what exists and who can access it.

The bookstore could expose this small schema:

Query supplies the entry point for reads. ID represents an identifier, square brackets describe a list, and ! marks a non-null value. Here, the book lookup may return null, while an existing book promises an author list containing no null entries. The list can still be empty.

The mobile app can request just its display fields:

The fields inside the braces form a selection set. Nesting name under authors requests information about related objects. $bookId is a variable the client supplies separately from the operation text.

A website can select description and authors { name biography } from the same schema. If the server already implements those fields and allows the client to access them, this change needs no new server endpoint. Adding a field that the schema does not expose still requires server work.

The word “graph” refers to connected objects, such as books and authors. GraphQL does not require a graph database. It also does not give clients arbitrary SQL access or let them invent relationships. The schema determines which paths they can follow.

3. A GraphQL Request and Response

Assume the bookstore serves public catalog queries at /graphql and supports the response media type shown below. HTTP is a common transport, and /graphql is a common endpoint convention; the core GraphQL language specification mandates neither.

The same mobile operation can travel in a JSON request body:

This is a read operation even though the HTTP method is POST. The GraphQL operation declares the read intent. The successful response is:

The result under data follows the selected structure. It includes the author's name without returning the biography or requiring a separate client request. no-store is a deliberate policy for this example, not a GraphQL caching requirement.

The envelope also matters when things go wrong. For this bookstore, an unknown or unpublished book produces {"data":{"book":null}}. That is an application choice supported by the nullable book field. A book with no associated authors returns an empty authors list instead.

Selecting an undefined field, such as warehouseCost, fails GraphQL validation before execution. The response contains errors and no data entry. If execution begins and a field fails, a response may contain both data and errors; non-null constraints can cause null to propagate to a containing object. Clients must inspect the response body rather than treating every HTTP 200 as complete success.

These public examples require no credentials. Adding protected fields would require authorization checks in the server's business logic. A syntactically valid query establishes neither permission to access a book nor permission to read every field on it.

4. Server-Side Data Assembly

GraphQL moves responsibility for assembling the requested result toward the server. A resolver is the logic that supplies a field's value. It might read an existing object, query a database, or call another service.

The following is one possible implementation of the bookstore operation:

The client makes one request to the GraphQL API, but the API may make several downstream calls. This diagram shows responsibilities, not a guarantee that those calls run in parallel. The server may need the book's author IDs before it can fetch author records.

That distinction prevents a common performance mistake: one client request does not imply one database query, less total work, or lower latency. A resolver can still fetch an entire database row before returning only selected fields. A list of books can trigger repeated author lookups unless the implementation handles them efficiently.

For this bookstore, keeping data assembly near the services may reduce expensive client round trips. Whether it improves the screen's loading time depends on backend execution, caching, and the actual network path. Measure the whole operation.

The GraphQL layer can also sit over existing REST services. An adoption project therefore does not inherently require replacing storage systems or rewriting every backend API.

5. Alternatives and Trade-Offs

Before changing API styles, compare GraphQL with improvements to the current API. For the bookstore, three approaches are plausible:

Scroll
ApproachHow it serves the screenMain design responsibility
REST with field selection and relationship expansionClient requests selected book fields and embedded authorsDefine supported combinations, limits, and what each parameter means
A backend-for-frontendA server tailored to a particular frontend returns its screen dataMaintain an interface shaped around that frontend's needs
GraphQLClient selects book and author fields from a shared schemaMaintain the schema and execute permitted selections efficiently

A backend-for-frontend is a server interface tailored to a specific frontend, such as the mobile app. It can use REST or GraphQL. These choices can overlap rather than forming mutually exclusive architectures.

If two stable screens need the same small aggregate, adding a suitable REST representation may be enough. If several independently released clients repeatedly need different combinations of related data, a shared GraphQL schema becomes more attractive.

Contract and Development Workflow

A typed schema gives tools enough structure to offer field discovery, validate operations, and generate client types. REST APIs that use OpenAPI descriptions also support validation and generation. GraphQL's distinctive benefit here is combining that contract with a standard selection language.

For the mobile team, this means changing a selection of existing fields can stay within a client release. It does not eliminate coordination: removing title, changing its meaning, or restricting its visibility can still break the app.

Caching and Monitoring

REST GET responses often fit existing HTTP caches naturally. Caches can also store GraphQL query responses, including through GET-based query transport where supported, but a shared endpoint alone does not identify the result. The cache key must account for the operation, variables, and relevant user context.

Some GraphQL clients additionally cache objects by identity for reuse across results. This requires suitable identifiers and cache configuration; it does not automatically create a shared CDN cache.

Monitoring also needs more detail than the endpoint path. If every operation appears as POST /graphql, path-level metrics hide which query is slow. Record operation identity, execution cost, and failures without unnecessarily logging sensitive variable values.

Execution Cost and Access Control

Allowing nested selections creates a wider range of request costs. Do not treat reading one title and reading many books with related objects as equivalent work merely because each uses one HTTP request.

The server needs bounded collections, appropriate query limits, and protection against expensive operations. It must enforce object and field access rules throughout the graph. GraphQL supplies structure for requests; the team supplies the business policies and operational controls.

6. Adoption Criteria

For the bookstore, start by observing where the current API hurts. Record dependent client requests, transferred bytes, screen loading times, and how often frontend changes require new response variants. Unused fields alone are weak evidence if their cost is negligible.

A focused trial could serve the book detail screen through GraphQL while keeping existing consumers on REST. Compare equivalent content under the same conditions. Include backend calls, cache behavior, error handling, and maintenance effort alongside client latency.

GraphQL is a stronger fit when different clients frequently compose related data and the team can own schema design and execution behavior. It is less compelling when clients need stable, simple responses, shared HTTP caching already works well, or a small endpoint improvement solves the observed problem.

Adopt it where the flexibility produces a concrete benefit. There is no requirement to expose every operation through the same API style.

Summary

GraphQL lets clients select fields and relationships from a server-defined schema. It can reduce unnecessary response data and dependent client requests, especially when several clients need different views of the same domain.

The server still owns authorization, efficient data access, caching, and compatibility. Compare GraphQL with field selection, aggregate REST responses, and frontend-specific interfaces, then choose based on measured client needs and the cost of operating the API.