[ Development ]

GraphQL API Development

One flexible endpoint, without the surprise bills.

GraphQL gives front-end teams exactly the data they ask for. Without care it also gives anyone on the internet a way to write one query that makes four thousand database calls. I design schemas that are pleasant to consume and servers that stay fast, authorized and bounded when clients get creative.

Schema-first · N+1 handled from day one · Fixed scope

Schemadesigned first
DataLoaderbatching by default
Limitson depth and cost
Testsincluded, not extra

[ What goes wrong ]

How GraphQL APIs fail in production.

Usually not on launch day. Once the schema has grown and clients start composing queries nobody planned for.

The N+1 query problem

A list of fifty orders, each resolving its customer and items separately, turning one request into hundreds of database queries.

Authorization only at the top

The login check happens at the query root, but nested fields happily return another customer's data through a relationship.

Unbounded queries

No depth, complexity or pagination limits, so one deeply nested query — accidental or malicious — can take the API down.

A schema that mirrors the database

Tables exposed one-to-one as types, so every internal column rename becomes a breaking change for every client.

Everything is a 200

Errors hidden inside successful responses, so monitoring shows a healthy API while users see broken screens.

Breaking changes shipped silently

Fields removed or retyped without deprecation, and mobile apps still in users' pockets start failing.

[ How it works ]

Design, build, harden.

01  —  Week 1

Schema design

Types, queries and mutations designed with the teams that will consume them, before resolvers exist. You get the draft schema, a written scope and a fixed price.

02  —  Week 2+

Build

Resolvers with batching, authorization and validation built in, tested against real queries and shipped in reviewable pull requests to staging.

03  —  Launch

Harden & document

Depth and cost limits, persisted queries where they fit, tracing per resolver, and schema checks in CI so breaking changes are caught before merge.

[ What actually changes ]

How I build GraphQL APIs.

Framework chosen to fit your stack. The patterns that keep it fast and safe are the same everywhere.

The API

  • Schema design — modeled on what clients need, with cursor pagination, clear nullability, input types and a deprecation policy.
  • Your stack — Apollo Server or GraphQL Yoga on Node.js, Laravel Lighthouse on PHP, Strawberry on Python, or Hasura over PostgreSQL.
  • N+1 and DataLoader — per-request batching and caching, so nested fields cost a handful of queries rather than hundreds.
  • Authentication and field-level permissions — checked where the data is resolved, not only at the entry point, and tested per role.
  • REST to GraphQL migration — a GraphQL layer over existing REST services first, then moved behind it gradually without a rewrite.

Production readiness

  • Depth and complexity limits — cost analysis per query, pagination caps and timeouts, so no single request can exhaust the server.
  • Persisted queries — known operations allow-listed for public clients, smaller requests and CDN caching of GET queries.
  • Federation — Apollo Federation or schema stitching when several teams or services own parts of the graph, and not before.
  • Error handling and observability — typed errors, per-resolver tracing and metrics that show which fields are slow or failing.
  • Client integration — Apollo Client, urql or Relay set up with sensible caching, generated TypeScript types and schema checks in CI.

[ Example engagement ]

A slow dashboard query, batched properly.

A GraphQL API where the main dashboard query triggered several hundred database calls. DataLoader batching, one missing index and query cost limits added.

Illustrative example of a typical engagement. Figures vary with the state of your systems and are not a guarantee of a specific outcome.

412 → 9database queries per request
76%lower p95 latency
0schema-breaking changes
2 weeksincluding tests

[ Free · no obligation ]

Planning or fixing a GraphQL API?

Describe what the API serves, or the query that is slow. You get a written scope and a fixed price — not a sequence of discovery calls.

Get a scope

[ Pricing ]

Straightforward pricing. $20/hour or fixed.

Tell me the number you have to work with. I'll tell you honestly what's achievable within it — and if it isn't enough, I'll say so before we start rather than halfway through.

Hourly rate $20/hoursmall jobs and ongoing work · fixed price for defined projects

Fixed project price

Scope agreed in writing, price agreed in writing, before any work starts. No hourly creep and no invoice you haven't already approved.

Monthly retainer

For ongoing work — maintenance, monitoring, updates and small changes. Month to month, cancel whenever, no minimum term.

$20/hour for small jobs

For a single bug, a short task or ongoing tweaks, where writing a full scope would cost more than simply doing the work. Billed in real time, reported in writing.

Budget too tight for the whole thing? I'll often suggest doing the highest-value part first and the rest later, rather than doing all of it badly.

[ Questions ]

Common questions.

What does GraphQL API development cost?

Small or hourly work — fixing an N+1 problem, reviewing a schema, adding query limits — is billed at $20 per hour. A defined build or migration gets a fixed price agreed in writing before I start, so the number does not change halfway through.

GraphQL or REST?

GraphQL earns its keep when several clients — web, mobile, partners — need different shapes of the same data, or when the front end keeps waiting for new endpoints. For a simple public API or file-heavy endpoints, REST is often simpler and easier to cache. I will tell you which fits.

Which GraphQL server do you use?

Whatever matches your stack. Apollo Server or GraphQL Yoga on Node.js, Lighthouse for Laravel, Strawberry for Python, and Hasura when you want an instant API over PostgreSQL with permissions defined declaratively.

How do you handle the N+1 problem?

DataLoader or its equivalent from the first resolver, so related records are batched into one query per type per request. Then I check the actual SQL a real query produces, because batching only helps if the underlying queries are indexed.

How do you keep a public GraphQL API secure?

Authorization checked at field level, query depth and cost limits, pagination caps, introspection disabled or restricted in production, and persisted queries for first-party clients so arbitrary operations are not accepted at all.

Can we move from REST to GraphQL gradually?

Yes, and that is usually the right approach. A GraphQL layer can sit in front of your existing REST services, so clients switch over screen by screen while the backend is moved behind it at whatever pace makes sense.

Do we need federation?

Only if several teams or services genuinely own separate parts of the graph. For a single team, one well-organized schema is simpler to build, test and operate. Federation solves an organizational problem, and it has a real operational cost.

Can you work with our front-end team?

Yes. I design the schema with the people who will consume it, set up generated types for Apollo Client, urql or Relay, and add schema checks to CI so neither side breaks the other. I work remotely with teams in the US, UK, Europe, Canada and Australia.

[ Let's talk ]

Tell me what your API needs.

Describe it in a few lines and you'll get a straight answer on scope, cost and timeline — from the person who would actually build it.