API Design

GraphQL Queries and Requests Explained

GraphQL queries and requests, explained. See how the language and the HTTP layer differ, plus when to use graphql-request or fetch.

SA
Samer Alsayegh
Founder
Published
5 min read

A GraphQL query is a request that asks for exactly the fields you name, nothing more. A GraphQL request is the HTTP call that carries that query to a server, almost always a single POST to one endpoint. The two terms get used interchangeably, but they name different layers: one is the language, the other is the transport.

Draftbase's delivery API speaks GraphQL alongside REST, so understanding both layers matters if you're fetching content for a React or Next.js app.

What Is a GraphQL Query?

A query is a string written in GraphQL's query language. It names an operation type (query, mutation, or subscription), then a tree of fields you want back.

query GetPost($slug: String!) {
  entry(slug: $slug) {
    title
    content
    author {
      name
    }
  }
}

That query returns exactly title, content, and the author's name, nothing else. A REST endpoint typically returns a fixed shape. GraphQL shifts that decision to the caller, field by field.

Queries vs mutations vs subscriptions

A query reads data and never changes server state. A mutation writes data, creating or updating something, and by convention returns the changed object so the client doesn't need a second round trip. A subscription opens a long-lived connection and pushes updates as they happen, typically over WebSockets, which most REST APIs have no equivalent for.

What Is a GraphQL Request?

A request is the actual HTTP call. Almost every GraphQL server accepts one method, POST, to one URL, with the query and any variables in the JSON body.

{
  "query": "query GetPost($slug: String!) { entry(slug: $slug) { title } }",
  "variables": { "slug": "my-post" }
}

That single-endpoint shape is a real departure from REST. There, the URL itself carries meaning (/posts/123 vs /posts/123/comments). In GraphQL, the URL is usually just /graphql, and the query body decides what comes back.

graphql-request: The Library, Not the Concept

graphql-request is also the name of a specific npm package, a minimal GraphQL client. It's worth naming directly since the keyword search overlaps with the general concept.

The package ships at roughly 2.8KB gzipped, against Apollo Client's 338.2KB (PkgPulse). It also pulls more weekly downloads than Apollo Client, 7.7M against 489.2K. It fits scripts and small frontends that don't need Apollo's normalized cache or React provider pattern.

import { request, gql } from 'graphql-request';

const query = gql`
  query GetPost($slug: String!) {
    entry(slug: $slug) { title content }
  }
`;

const data = await request('https://api.draftbase.co/delivery/graphql', query, { slug: 'my-post' });

When to reach for graphql-request instead of Apollo

Pick graphql-request for a Node.js script, a static site generator's build step, or any place you need one query and nothing else. Pick Apollo Client when you need a normalized cache shared across components, optimistic UI updates, or real-time subscriptions in a React app.

How Do Variables Work in a GraphQL Query?

Variables let a query stay static while its inputs change per call, the same reason parameterized SQL exists. Declare a variable's type in the operation signature, then pass its value separately from the query string.

query GetEntries($limit: Int!, $templateId: String) {
  entries(limit: $limit, templateId: $templateId) {
    title
    slug
  }
}

Skipping variables and string-interpolating values directly into the query works. It defeats query caching on both client and server, though, and reopens the door to injection-style bugs that typed variables close.

What Breaks When a Query Gets Too Deep?

A query without limits can nest fields arbitrarily deep: an entry's author, that author's other entries, each of those entries' authors, and so on. Each level of nesting can multiply the number of resolver calls the server has to make. That's why most production GraphQL servers cap query depth and query complexity.

That cap is invisible until a client hits it. A frontend developer testing against a small dataset won't notice a deeply nested query is slow. The same query against production data can time out, or get rejected outright. See the fuller GraphQL vs REST comparison for how a delivery API scopes this in practice, with cursor pagination and per-request rate limits instead of unlimited nesting.

Can I Send a GraphQL Request Without a Client Library?

Yes. Since a GraphQL request is just a POST with a JSON body, fetch works fine for a one-off call.

const res = await fetch('https://api.draftbase.co/delivery/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.DRAFTBASE_KEY}`,
  },
  body: JSON.stringify({ query, variables }),
});

A client library earns its place once you need query caching, request batching, or generated TypeScript types from the schema. For a single build-time fetch, plain fetch is often the leaner choice, one dependency you don't have to install or upgrade.

The Underused Angle

Most GraphQL explainers stop at "ask for only the fields you need." They skip the actual cost of that flexibility: overfetching moves from the network to the resolver. A REST endpoint's response shape is fixed at write time, so the backend knows exactly what to compute. A GraphQL query's shape is decided by the caller at request time. A poorly designed resolver can end up running N+1 database queries to satisfy one client-chosen field tree.

That's not a reason to avoid GraphQL. It's a reason to treat resolver design as part of the API's real cost, not an afterthought. Batching, dataloaders, and query complexity limits belong in the launch plan, not the postmortem.

Should I Use GraphQL or REST for a Content API?

Use GraphQL when your frontend needs different field subsets on different pages, and round trips are expensive: mobile clients, slow networks, deeply nested content. Use REST when your endpoints are simple, cacheable at the HTTP layer by default, and don't need per-client field selection.

Draftbase's delivery API ships both from the same content model, so this isn't an either-or platform choice, it's a per-request one. A build step might use REST for its simplicity; a client-side fetch might use GraphQL to avoid overfetching on a slow connection. The REST API guide covers the REST side of that same delivery API in more depth.

Conclusion

A GraphQL query is the language, a GraphQL request is the transport, and graphql-request is one specific library for sending both. Reach for the lightweight client on a script or static build, and a fuller client like Apollo when a React app needs caching and subscriptions. Fetching from a headless CMS? Draftbase's GraphQL delivery API ships next to REST from the same content model. The choice is per-request, not a platform lock-in.

Ship content that's built to be found

Draftbase generates schema, structured data, and a fast MDX editor for every post.

Frequently asked questions

What is the difference between a GraphQL query and a GraphQL request?

A query is the language, the field tree you ask for. A request is the HTTP call, almost always one POST that carries that query to the server.

What is graphql-request used for?

It's a lightweight JavaScript client for sending GraphQL requests. At about 2.8KB gzipped, it fits scripts and small frontends better than a full client like Apollo.

Do I need a GraphQL client library?

No. A GraphQL request is just a POST with a JSON body, so plain fetch works for a one-off call. A client library earns its place once you need caching or generated types.

Why does GraphQL use only one endpoint?

The query body decides what data comes back, not the URL. That's why almost every GraphQL server exposes a single POST endpoint instead of many resource paths.

Is GraphQL faster than REST?

Not inherently. GraphQL avoids overfetching on the network, but a poorly designed resolver can run many database queries per request, so the real cost depends on resolver design.

SA
Samer Alsayegh
Founder at Draftbase

Samer is a software engineer and entrepreneur, founder of Draftbase and Ezi Home Services, building technology that simplifies home services. Passionate about software, APIs, automation, and creating products that solve real-world problems.

graphqlapi-design

Related posts

Draftbase is a headless CMS built for React devs.