GraphQL is a query language for APIs and a server-side runtime for executing those queries, developed by Facebook in 2012 and open-sourced in 2015. It gives clients precise control over the data they request, replacing the rigid, over-fetching nature of traditional REST APIs.
GraphQL allows clients to describe exactly what data they need in a single request, rather than the server deciding what to return. Instead of multiple endpoints, there is typically one endpoint that accepts flexible queries. This client-driven approach eliminates over-fetching (getting more data than needed) and under-fetching (requiring multiple requests to assemble data).
A GraphQL query is a structured string that mirrors the shape of the data you want back. You send it as an HTTP POST to the GraphQL endpoint, and the server returns a JSON object matching that exact shape. For example, querying a user's name and email returns only those two fields, nothing more.
Every GraphQL API is built around a strongly typed schema written in Schema Definition Language (SDL). The schema defines all available types, fields, and their relationships, acting as a contract between client and server. This type system enables powerful tooling such as auto-completion, validation, and documentation generation at build time.
GraphQL has three operation types: queries for reading data, mutations for writing or modifying data, and subscriptions for real-time event-driven updates over WebSockets. Mutations follow the same typed structure as queries, so the client specifies exactly which fields to return after a write operation. Subscriptions enable live data without polling, making GraphQL well-suited for chat apps, dashboards, and feeds.
Behind each field in a schema sits a resolver function, which is responsible for returning the actual data for that field. Resolvers can fetch from databases, REST services, caches, or any data source, making GraphQL a flexible orchestration layer. The runtime calls only the resolvers needed to satisfy the specific fields requested in a query.
A common performance pitfall in GraphQL is the N+1 query problem, where resolving a list of N items triggers N additional database queries for each item's nested fields. The standard solution is the DataLoader pattern, which batches and caches multiple individual requests into a single efficient query. Always audit resolver logic and apply batching early to avoid serious performance degradation at scale.
© RM Full Stack & AI Engineer · All guides · Roadmaps · Open the app