GraphQL
GraphQL - The API Query Language Powering GitHub, Shopify, and Netflix
GraphQL
GraphQL development powers the APIs behind GitHub, Shopify, Netflix, and Meta — the company that invented it in 2015. The September 2025 specification (announced at GraphQLConf 2025) is current; graphql-js reaches 33.6 million weekly npm downloads. 70% of organizations now use GraphQL (Apollo Developer Survey 2024) — 340% Fortune 500 growth since 2023. Apollo Server 5 with Federation v2, The Guild's Yoga Server and Hive schema registry, Strawberry for Python, and Hasura for instant APIs define the 2026 stack. GraphQL's 28% latency disadvantage on single-resource reads disappears entirely on multi-resource queries where it eliminates round-trips.
Build with GraphQLAPI
Who Should Use GraphQL?
GraphQL is the right API layer when: multiple clients (web, mobile, third-party) consume the same API with different data needs; the application has complex, nested data relationships; microservices need to compose a unified API surface; or real-time data updates are required alongside standard queries. REST is still appropriate for simple CRUD APIs with a single client — GraphQL adds schema definition overhead that isn't justified for simple use cases.
Multi-Client Applications (Web + Mobile)
Web dashboards need different data than mobile apps — different fields, different nesting depths, different pagination strategies. GraphQL's client-specified queries eliminate the need for multiple REST endpoint variants (/api/user/summary vs /api/user/full). One API, each client requests exactly what it renders. Mobile apps reduce bandwidth; web dashboards get richer data — both from the same schema.
Microservice Architectures with API Gateway
Apollo Federation v2 allows each microservice team to own a GraphQL subgraph independently. The router composes them into a unified supergraph — clients query across service boundaries without knowing the underlying topology. Teams deploy subgraph changes independently; the router validates schema composition. This is the architecture pattern GitHub, Netflix, and Shopify use to scale GraphQL across hundreds of engineers.
Developer-Facing API Products
GitHub's entire public API is GraphQL. Shopify's Storefront and Admin APIs are GraphQL. Third-party developers exploring an API benefit enormously from GraphQL's introspection — they can discover the entire schema in GraphiQL or Playground without reading documentation. Self-documenting APIs with type information reduce support burden and increase developer adoption.
Data-Rich Dashboard Applications
Analytics dashboards, admin panels, and reporting tools often need deeply nested, aggregated data from multiple sources in a single view. A single GraphQL query can fetch user data, their orders, order items, product details, and shipping status in one round-trip. The equivalent REST calls require 4–6 sequential requests. GraphQL's query batching reduces dashboard load times significantly on complex views.
Real-Time Applications Requiring Subscriptions
GraphQL Subscriptions use the same query language for real-time updates — subscribe to order status changes, live auction bids, or collaborative document edits using GraphQL subscription syntax over WebSocket. One schema, one language for both request-response and event-driven data. Apollo Client manages subscription lifecycle (reconnection, deduplication) transparently.
Rapid Backend from Database (Hasura)
Hasura generates a full GraphQL API from your PostgreSQL schema in seconds — queries, mutations, subscriptions, and relationships derived from foreign keys. Custom business logic added via Actions (REST webhooks) and Event Triggers (Postgres CDC). For applications where the data model is the API, Hasura eliminates the entire resolver layer and ships a production-grade GraphQL backend without custom code.
When GraphQL Might Not Be the Best Choice
We believe in honest communication. Here are scenarios where alternative solutions might be more appropriate:
Simple CRUD APIs with a single client — the overhead of schema definition, resolver implementation, and query parsing is not justified when a REST controller with four endpoints would suffice; GraphQL adds real complexity for simple use cases
File upload-heavy applications — GraphQL's JSON transport doesn't handle multipart file uploads natively; the graphql-multipart-request-spec adds support but it's awkward compared to REST's native multipart/form-data handling
Highly cacheable public APIs — REST's HTTP cache semantics (ETags, Cache-Control, CDN caching) work natively on GET requests; GraphQL's POST-based queries don't cache at the HTTP layer without Persisted Queries and additional CDN configuration
Teams without strong API design discipline — GraphQL's flexibility allows schema design that over-exposes internal data models, creates N+1 query problems, or leaks sensitive fields; without strong schema governance, the flexibility becomes a maintenance burden
Still Not Sure?
We're here to help you find the right solution. Let's have an honest conversation about your specific needs and determine if GraphQL is the right fit for your business.
Why GraphQL Is the Right API Layer for Complex Applications in 2026
GraphQL solves the over-fetching and under-fetching problems that plague REST APIs at scale. One endpoint, one request, exactly the data you need. 70% of organizations adopted it by 2024; the Fortune 500 grew adoption 340% since 2023. GitHub, Shopify, Netflix, and Meta run their entire public APIs on GraphQL. Apollo Federation enables microservice teams to compose a unified API without a single team owning everything — the architecture pattern that makes GraphQL viable at enterprise scale.
70%
Enterprise Adoption (Apollo 2024 Survey)
Apollo Developer Survey 2024340%
Fortune 500 Growth Since 2023
Postman State of APIs Report 202433.6 million
Weekly npm Downloads (graphql-js)
npm registry, 2026September 2025
Current Specification
spec.graphql.org, GraphQLConf 2025Single endpoint, exactly the data requested — clients specify the fields they need in the query; no over-fetching large REST responses; no under-fetching requiring multiple round-trips to assemble a UI view
Strongly-typed schema as the API contract — every field, argument, and return type is defined in the SDL; breaking changes surface at schema validation time, not at runtime; schema introspection generates client-side types automatically
Apollo Federation v2 composes microservice schemas into a unified supergraph — each team owns their subgraph independently; the gateway stitches queries across services transparently without clients knowing the underlying boundaries
GraphQL Subscriptions push real-time data to clients over WebSocket — live feeds, notification systems, and collaborative features use the same query language as regular data fetching; no separate real-time infrastructure required
Persisted queries and automatic persisted queries (APQ) reduce network payload — hash-based query identification sends only a hash on repeat requests; reduces bandwidth by 60–90% for frequently-executed queries in production
Schema-first development aligns frontend and backend teams — agree on the schema before writing implementation; frontend mocks against the schema immediately; parallel development without API integration blockers
graphql-js: 20,328 GitHub stars, 33.6M weekly npm downloads — the reference implementation is the most downloaded API runtime in the JavaScript ecosystem; the ecosystem has reached irreversible critical mass
Hasura generates a production-ready GraphQL API from your PostgreSQL schema instantly — zero custom resolver code for standard CRUD; real-time subscriptions over Postgres LISTEN/NOTIFY built in; REST endpoints from GraphQL queries
GraphQL in Practice
Unified API Gateway for Microservices
Apollo Federation v2 composes multiple subgraphs into a single supergraph endpoint. Order service, user service, product service, and inventory service each own their schema; the Apollo Router stitches queries across all four transparently. We implement federated GraphQL architectures for platforms where multiple backend teams need to collaborate on a unified API surface without coordinating every schema change.
Example: E-commerce platform with 6 microservices federated into one GraphQL API — each team deploys schema changes independently; clients query across service boundaries seamlessly
Multi-Platform Application API
A single GraphQL schema serves web, iOS, Android, and third-party integrations — each client queries exactly the fields it renders. The web admin dashboard fetches full user profiles with nested order history; the mobile app fetches only id, name, and avatar for list views. One API, zero endpoint proliferation, no version negotiation. We design GraphQL schemas that serve multiple client types efficiently with fragments, aliases, and operation variables.
Example: SaaS platform with web app, mobile app, and partner API all served from one GraphQL endpoint — each client queries its specific data shape without backend changes
Instant GraphQL API with Hasura
Hasura generates a complete GraphQL API from a PostgreSQL schema in minutes — queries, mutations, subscriptions, and relationship traversal built from foreign key definitions. We deploy Hasura for applications where the database schema is the primary data model: internal tools, admin panels, and data-heavy SaaS platforms where the resolver layer would add no meaningful business logic. Custom logic is added via Actions (REST webhooks) and Event Triggers.
Example: Operations platform built on Hasura — complete GraphQL API from 40-table PostgreSQL schema in 2 days; custom order processing logic via Hasura Actions to Lambda
Real-Time Collaborative Application
GraphQL Subscriptions over WebSocket push updates to clients using the same query language as regular fetches. Apollo Client manages subscription lifecycle — connection management, reconnection, and result merging into the local cache. We build collaborative features (live document editing, shared dashboards, real-time notifications) using GraphQL subscriptions alongside standard queries and mutations in a unified schema.
Example: Project management tool with real-time task updates — GraphQL subscriptions notify all project members when a task changes; Apollo Client merges updates into the local cache automatically
Public Developer API (Shopify-Style)
GraphQL's introspection turns your API into self-documenting infrastructure — third-party developers explore the schema in GraphiQL, understand available queries from type definitions, and build integrations without waiting for documentation. We design public GraphQL APIs for SaaS platforms that want a developer ecosystem: rate limiting via query complexity analysis, API versioning via schema evolution, and deprecation via the @deprecated directive.
Example: SaaS marketplace with a public GraphQL API for 200+ integration partners — introspection-powered documentation, complexity-based rate limiting, schema versioning via field deprecation
Data-Aggregating Dashboard
Analytics dashboards require deeply nested data from multiple entities in a single view — a GraphQL query for a user profile view might fetch user details, their last 5 orders, each order's items, item product details, and shipping status in one request. We build dashboard GraphQL backends with DataLoader for N+1 batching, persisted queries for performance, and field-level authorization for role-based data access.
Example: E-commerce admin dashboard — single GraphQL query fetches user, orders, revenue metrics, and support tickets; DataLoader batches 50 product lookups into one database query
GraphQL Pros and Cons
Every technology has its strengths and limitations. Here's an honest assessment to help you make an informed decision.
Advantages
Eliminates Over-Fetching and Under-Fetching
Every REST API ships fields no client uses (over-fetching) or requires multiple round-trips to assemble a UI view (under-fetching). GraphQL's client-specified queries return exactly the requested fields — nothing extra, nothing missing. For mobile apps on limited bandwidth, this is not a theoretical improvement; it's measured in seconds of load time and megabytes of data transfer.
Type System as Documentation
The GraphQL Schema Definition Language is executable documentation — every field has a type, every type has fields, every argument is named and typed. Introspection queries generate client SDKs, IDE autocompletion, and API documentation automatically. The schema is always in sync with the implementation; documentation drift is architecturally impossible.
Federation Scales Across Teams
Apollo Federation v2 is the architecture that makes GraphQL viable at enterprise scale. Each team owns their subgraph independently — no coordination required for subgraph schema changes that don't affect other services. The router validates composition and rejects incompatible changes before deployment. Teams at Netflix, Shopify, and GitHub deploy subgraph changes dozens of times per day without a schema freeze.
One Language for Queries and Subscriptions
GraphQL Subscriptions use identical query syntax to standard queries — subscribe to exactly the fields you need, with the same variables and fragments. Apollo Client handles WebSocket connection management transparently. Applications get a unified data-fetching language for request-response, polling, and event-driven real-time data.
Ecosystem Depth
33.6 million weekly npm downloads for graphql-js alone. Apollo Client (19.6K stars), Apollo Server (13.9K stars), graphql-yoga (The Guild), Hasura, Strawberry (Python), graphql-ruby, absinthe (Elixir) — every major language and framework has a mature, maintained GraphQL library. The ecosystem has reached the scale where GraphQL adoption carries no library-availability risk.
Developer Experience with Tooling
GraphiQL and Apollo Sandbox provide interactive API exploration with autocompletion, schema navigation, and query history in the browser. Apollo Studio offers schema registry, field-level usage analytics, breaking change detection, and performance monitoring for production GraphQL APIs. The tooling ecosystem for GraphQL exceeds what's available for REST.
Limitations
N+1 Query Problem
Without DataLoader or equivalent batching, GraphQL resolvers that fetch child entities independently execute O(n) database queries for a list of n parent entities. A query for 100 orders with their products triggers 100 individual product lookups by default.
We implement DataLoader in all GraphQL services that fetch relationships — DataLoader batches child entity lookups across all concurrent resolvers in a single tick, reducing 100 individual queries to 1 batched query. This is standard practice, not optional, for production GraphQL backends.
Query Complexity and DOS Exposure
A deeply nested or self-referential GraphQL query can trigger exponential database lookups — { users { friends { friends { friends { orders { items ... } } } } } }. Public GraphQL APIs without query complexity limits are vulnerable to resource exhaustion.
We implement query complexity analysis (graphql-query-complexity) with per-field cost weights and a maximum complexity threshold. Depth limiting prevents deeply nested queries. Persisted queries for public APIs whitelist approved query shapes and reject arbitrary queries entirely.
HTTP Caching Complexity
REST's GET-based requests benefit from HTTP cache semantics (CDN caching, browser caching, ETags) natively. GraphQL's POST-based transport doesn't cache at the HTTP layer — every query goes to the origin unless Automatic Persisted Queries (APQ) are configured.
We configure APQ (Automatic Persisted Queries) for production GraphQL APIs — the first request registers the query hash; subsequent requests send only the hash and hit CDN caching. Field-level caching via Apollo Cache-Control directives sets TTLs per type, enabling CDN caching for cacheable responses.
Schema Design Complexity
GraphQL schemas that mirror database models directly produce unmaintainable APIs — clients must understand implementation details, business logic leaks into the schema, and refactoring the database breaks the API. Designing a good GraphQL schema requires deliberate effort and domain modeling expertise.
We design GraphQL schemas around the client's view of the domain — not the database schema. We apply schema design principles: use specific types over generic ones, avoid exposing IDs of internal join tables, use connections for pagination, and version via field deprecation. Schema review is part of our API development process.
GraphQL Alternatives & Comparisons
We use all of these in production — the right choice depends on your project's constraints, team familiarity, and scale requirements.
GraphQL vs REST API
Learn More About REST APIREST API Advantages
- •Native HTTP caching (ETags, Cache-Control, CDN caching) without additional configuration
- •Simpler mental model for teams without GraphQL experience — HTTP verbs map directly to operations
- •Better for file uploads — multipart/form-data is native to REST; GraphQL requires the multipart spec
- •28% lower latency on simple single-resource reads in 2026 benchmarks
REST API Limitations
- •Over-fetching and under-fetching are structural problems — endpoints return fixed shapes regardless of client needs
- •Multiple round-trips required for complex views — a dashboard needing user + orders + products requires 3+ requests
- •No type system or schema contract — breaking changes surface at runtime, not at schema validation
- •API versioning requires URL duplication (/v1, /v2) or header negotiation
REST API is Best For:
- •Simple CRUD APIs with a single client and predictable data requirements
- •Highly cacheable public APIs where CDN caching at the HTTP layer is critical
- •File upload or download-heavy APIs where binary transfer efficiency matters
When to Choose REST API
Choose REST for simple, single-client APIs where HTTP caching is critical or the team lacks GraphQL experience. Choose GraphQL when multiple clients need different data shapes, you have complex nested relationships, or you're building a developer-facing API with introspection requirements.
GraphQL vs tRPC
Learn More About tRPCtRPC Advantages
- •End-to-end TypeScript type safety without schema generation — types infer directly from router procedures
- •Zero schema file — no SDL to maintain separately; the TypeScript function is the schema
- •Ideal for TypeScript monorepos where server and client share the same codebase
- •Simpler setup than Apollo Server for TypeScript-first Next.js applications
tRPC Limitations
- •TypeScript-only — no support for non-TypeScript clients or multi-language ecosystems
- •No introspection — third-party API consumers cannot explore the API schema
- •No federation — does not scale to microservice API composition
- •Limited ecosystem compared to GraphQL's Apollo, Hasura, and The Guild libraries
tRPC is Best For:
- •TypeScript monorepos where server and client code share the same repository
- •Next.js full-stack applications with a single TypeScript codebase
- •Internal APIs where all consumers are TypeScript applications in the same org
When to Choose tRPC
Choose tRPC for TypeScript monorepos with a single client where end-to-end type safety without SDL maintenance is the priority. Choose GraphQL when you need multi-language support, third-party API consumers, schema introspection, or microservice federation.
GraphQL vs gRPC
Learn More About gRPCgRPC Advantages
- •Binary Protocol Buffers serialization — 5–10x smaller payload and 2–5x faster serialization than JSON/GraphQL
- •Bidirectional streaming built into the protocol — real-time server push with backpressure support
- •Strongly typed via .proto files — language-agnostic schema generates clients in 10+ languages
- •Ideal for internal microservice communication where latency and throughput matter
gRPC Limitations
- •Browser support requires gRPC-Web proxy — not native to browsers; adds infrastructure complexity
- •Protocol Buffers are binary — not human-readable; debugging requires additional tooling
- •Steeper learning curve than REST or GraphQL; smaller general web developer community
- •Not suitable for developer-facing public APIs where discoverability matters
gRPC is Best For:
- •Internal microservice-to-microservice communication where latency is critical
- •High-throughput data pipelines with large message volumes
- •Polyglot service architectures requiring generated clients in multiple languages
When to Choose gRPC
Choose gRPC for internal service communication where performance and strongly-typed multi-language clients are critical. Choose GraphQL for client-facing APIs where browser compatibility, introspection, and developer experience matter.
Technologies That Pair With This in Production
Services That Use This Technology
Questions from Developers and Teams
GraphQL is a query language and runtime for APIs — clients describe exactly what data they need in a query, and the server returns precisely that shape. REST uses predefined endpoints that return fixed data shapes regardless of what the client actually needs. Key differences: (1) Over/under-fetching — GraphQL returns exactly what's requested; REST returns the endpoint's fixed shape. (2) Multiple resources — one GraphQL query can fetch a user, their orders, and order items; REST requires 3 separate requests. (3) Type system — GraphQL has a strongly-typed schema; REST has no enforced contract. (4) Versioning — GraphQL evolves via schema deprecation; REST versions via URL (/v1, /v2). 70% of organizations now use GraphQL in production, confirming it's not a niche choice.
Use GraphQL when: (1) multiple different clients (web, mobile, third-party) consume the same API with different data needs; (2) you have complex nested data relationships that require multiple REST round-trips to assemble; (3) you're building a microservice architecture that needs a unified API surface; (4) you want real-time subscriptions alongside request-response queries in the same system; (5) you're building a developer-facing API where introspection and self-documentation matter. Stick with REST for: simple CRUD APIs with a single client, file upload-heavy APIs, highly cacheable public APIs where CDN caching is critical, or teams without GraphQL schema design experience.
The September 2025 edition of the GraphQL specification is current, announced at GraphQLConf 2025 (October 2025). A pre-release Working Draft dated April 2, 2026 represents the next iteration in progress. The specification is maintained by the GraphQL Foundation (a Linux Foundation project) with contributions from Meta, Apollo, The Guild, Shopify, and other major users. The September 2025 spec introduced incremental delivery improvements and clarifications to stream and defer directives. The reference implementation graphql-js tracks the specification closely and has 33.6 million weekly npm downloads.
Apollo Federation v2 is an architecture for composing multiple GraphQL subgraphs (owned by different teams) into a single supergraph. An Apollo Router sits in front of all subgraphs and routes queries to the appropriate services, stitching results together. You need Federation when: multiple teams own different parts of your API, you have microservices that need to expose a unified GraphQL surface, or your schema has grown too large for a single team to maintain. You don't need Federation for: single-team APIs, monolithic backends, or APIs with fewer than 3–4 distinct data ownership boundaries.
Hasura is a GraphQL engine that generates a complete GraphQL API from your PostgreSQL (or other supported) database schema automatically — queries, mutations, subscriptions, and relationship traversal derived from foreign keys, all without writing custom resolvers. It ships in minutes: point Hasura at your database, configure permissions, and you have a production-ready API. Add custom business logic via Hasura Actions (REST webhooks) and Event Triggers (CDC on table writes). Hasura's permission system (row-level and column-level) maps to JWT claims for multi-tenant security. It's the right choice when your data model is the API and you want to eliminate the resolver layer entirely.
Authentication in GraphQL follows the same patterns as REST — JWT tokens or session cookies in HTTP headers, validated in middleware before reaching resolvers. Authorization is more nuanced: (1) Schema-level — use directives (@auth, @hasRole) to protect entire types or fields. (2) Resolver-level — check permissions inside each resolver before fetching data. (3) Database-level — use Row Level Security (PostgreSQL + Hasura) to enforce access at the data layer. The most robust pattern is database-level authorization via RLS — even a buggy resolver cannot return data the user isn't authorized to see. We implement field-level authorization for sensitive fields (payment details, PII) separate from the top-level auth check.
The N+1 problem: a GraphQL query for a list of 100 orders, each with their customer, triggers 1 query for orders + 100 individual customer queries = 101 queries total. This happens because resolvers execute independently and don't know about sibling resolver executions. The solution is DataLoader — a utility that batches all child entity lookups within a single JavaScript event loop tick into one database query. The 100 individual customer lookups become 1 query: SELECT * FROM customers WHERE id IN (...100 ids). We implement DataLoader as standard practice in all GraphQL services — it's not optional for production APIs with relationship data.
GraphQL Subscriptions establish a WebSocket connection and push updates to clients when specified events occur. The subscription query defines exactly which fields to receive on each update — the same syntax as standard queries. Server implementations: Apollo Server uses graphql-ws (WebSocket protocol); Hasura uses PostgreSQL's LISTEN/NOTIFY to stream database changes as subscription events. Apollo Client on the frontend manages subscription lifecycle — connection, reconnection, and merging new data into the client cache. Common use cases: live order status, real-time auction bids, collaborative editing notifications, dashboard metric updates.
Our standard GraphQL stack: Apollo Server 5 for Node.js backends (with Federation v2 for microservices); Hasura for instant PostgreSQL-backed APIs; The Guild's graphql-yoga as a lightweight alternative to Apollo Server; graphql-codegen for TypeScript type generation from schema; DataLoader for N+1 batching; graphql-query-complexity for query cost analysis and DOS protection; Apollo Client for React/Next.js frontends; Strawberry for Python backends; and Apollo Studio for schema registry and production monitoring. We select the right combination based on your team's language, scale requirements, and whether you need Federation.
GraphQL security requires several layers: (1) Query complexity limits — assign cost weights to fields and reject queries exceeding a threshold; prevents 'query bombs' that trigger exponential resolver chains. (2) Depth limiting — reject queries nested beyond a maximum depth (typically 5–7 levels). (3) Rate limiting — limit requests per IP or per authenticated user per time window. (4) Introspection in production — disable schema introspection for public production APIs to avoid exposing the full schema to attackers (allow it for developer-facing APIs). (5) Persisted queries — for internal APIs, whitelist approved query hashes and reject arbitrary queries entirely. (6) Field-level authorization — never rely solely on query structure to protect sensitive fields; authorize each field in its resolver or via RLS.
Still have questions?
Contact Us