Why GraphQL Got Popular
GraphQL has been around for years now, but it’s still common to hear the question: what actually is it? Eve Porcello, co-author of Learning GraphQL and co-founder of Moon Highway, joined the podcast to break down the technology and the API problems it was designed to solve. GraphQL wasn’t invented in a vacuum—it came out of Facebook’s internal struggles with its mobile apps. The core problem was that a single screen in the mobile app needed data from many different places, and the existing REST endpoints often delivered either too much data or too little.
GraphQL is a specification, not a framework. It sits on top of your existing backend, acting as an abstraction layer. You may still have REST APIs or a database underneath, but clients talk to the GraphQL layer rather than hitting multiple endpoints directly. One of the defining features is the schema: you define types and their fields, and the data is guaranteed to match that shape. Eve emphasized that this is usually the first thing teams notice—the schema makes the data contract explicit.
GraphQL As An Implementation Detail
One point Eve stressed is that GraphQL is just a specification. You don’t “install” GraphQL globally; you pick a server library or a client library for your language of choice. Popular options include Apollo, Relay, and GraphQL Yoga. And—contrary to what some assume—GraphQL is not tied to a particular database or even to JavaScript. “The tech community is convinced that all of GraphQL is JavaScript,” she noted, but implementations exist in Ruby, Python, Go, and other languages. The spec is language-agnostic; the ecosystem just happens to be especially rich in the JavaScript world.
The choice of server library is essentially an implementation detail. “The spec is the bare bones of what you need, and each library brings its own extras,” Eve explained. That means teams often start with an easy scaffolding tool like GraphQL Yoga to avoid boilerplate, then go deeper as their needs grow.
The Schema And Resolvers
A GraphQL schema looks a lot like a typed object definition. You describe a User type with fields like id, name, and friends, and crucially you also say what each field returns. That friends field might return a list of User objects, for example. All of this is declared in the schema definition language. From there, you write resolver functions that tell GraphQL exactly how to fetch the data for each field when a query comes in.
This separation enables one of GraphQL’s greatest selling points: the single request. “That makes it easy for you to ask for exactly what you need,” Eve said about the request model. Once you’ve set up your schema and resolvers, clients can compose queries that pull exactly the fields they need, across previously separate data domains, in a single round trip from the client to the GraphQL endpoint.
GraphQL Versus REST
The comparison to REST is inevitable, and Eve offered a practical frame for it. REST has distinct problems around over-fetching (where you receive related fields you don’t need) and under-fetching (where you have to make multiple calls to assemble the full picture because one endpoint won’t give you everything). Depending on your view, those are hard architectural flaws or just annoying constraints that have existed so long you don’t notice them.
A simple schema preview shows the difference: with a REST API you’d often make one call to get the user (GET to /api/users/1), then another to get that user’s posts. With GraphQL you can send a single query that asks for the user’s name and their last three posts, in the same structure you want them displayed in. That’s powerful for the frontend team—they define what they need rather than adapting to what a backend endpoint happens to offer.
Hard Parts And Preparation
GraphQL is not all smooth sailing. The biggest pain point is shifting error handling and authorization logic into your backend, but that’s not unique to GraphQL; those are classic problems in any layered architecture. Beyond that, “You have to be prepared for figuring out your caching story and knowing how the Dataloader library solves the n+1 problem,” Eve advised.
The n+1 problem deserves special mention: without mitigation, a query for a user and all their posts could result in an overwhelming number of database hits—one for the main query and one for every nested item. Tools like Dataloader exist to coalesce these into efficient batch requests. Frustration usually peaks among teams that avoid proper preparation, which often leads to folks writing off GraphQL prematurely. “The newness of it can be great, but it can also be a source of resistance if people don’t embrace learning,” Eve said about the human side of rolling out a new technology. Honestly, this applies to just about any serious tool investment, not just GraphQL.
Can REST And GraphQL Coexist?
You’re never forced to make a bulldozer-style migration: replacing everything at once. REST is still everywhere, and many organizations run hybrid setups where some microservices follow the traditional REST approach while others behave individually or part of a federation. This pragmatic strategy lets teams introduce GraphQL alongside the data services that fit the pattern best, gradually.
The undercurrent of the conversation is that there’s no one golden rule for API development. The more you know about schemas, resolvers, and the underlying REST conventions, the better equipped you are to use GraphQL intentionally rather than recreating your old problems in a new language.
GraphQL: The Query Language That Sits Between Front End and Back End
GraphQL is often described as living “in the middle” between the front end and back end of a web stack. For front-end developers, it provides a way to define exactly what data a page or component needs. For back-end teams, it acts as an orchestration layer that can pull together data from REST APIs, databases, and other sources into a single, coherent interface.
Rather than tearing down existing REST APIs, GraphQL is frequently implemented as a wrapper around them. The query language gives developers a consistent way to think about data requirements, even when some of that data originates from REST endpoints and some from a database.
Solving the Over-Fetching Problem
The core problem GraphQL addresses is over-fetching. With a traditional REST endpoint like /users or /products, every request returns the full payload, regardless of what the client actually needs. GraphQL lets clients be selective: if only four fields are needed from an object with a hundred, the query can pinpoint exactly those four fields, reducing the amount of data loaded onto a device.
This is a formalization of the idea behind optional fields or field selectors in some REST APIs. The query itself becomes the mechanism for asking, filtering, and retrieving information from anywhere in the stack.
The Schema as a Shared Contract
While the query language gets much of the attention, the GraphQL Schema is arguably more important. It provides a type system for the API, giving teams a single source of truth. Front-end developers, back-end developers, and managers can look at the Schema and understand exactly what data is available, what fields exist, and what types are returned.
This formalization also helps as organizations move away from sprawling microservices. GraphQL can feel like a return to a monolith, but with the benefits of microservices preserved—one place to look up any endpoint, one dictionary for how the API works.
Queries, Not Commands
Unlike SQL’s command-like syntax (SELECT this FROM that WHERE ...), GraphQL queries are text strings that are field-oriented. They don’t specify where data comes from—that logic lives on the server. The GraphQL server is responsible for fetching data from whichever source holds it and filtering it according to parameters.
A single query can mix and match different types of data, including deeply nested relationships. For example, a user type might have a products field that returns a list of products, and each product might have its own associated types. Queries can go as deep as needed. The response is JSON, and because the data shape mirrors the query structure, it’s clear what you’re getting.
Complex Logic on the Server
Business logic that goes beyond simple field selection is handled on the server. If a client needs a “complicated user”—say, a user who is an admin of an active team—the Schema can define a type or query for that, and the resolver function implements the actual logic. Resolvers can call other APIs, query databases, check caches, or perform any other operation, as long as the return value matches the Schema’s type requirements.
GraphQL servers can be built in JavaScript, Python, Go, C++, or essentially any language. The original reference implementation was in JavaScript for Node.js, which remains the most popular option, but servers can run on custom instances, on AWS Lambda, or through frameworks like Apollo Server Express or Apollo Server Lambda.
Types, Mutations, and Real-Time Data
The Schema definition language describes types, queries, and mutations. Mutations are the “verbs”—operations like creating an account or logging in. A mutation takes input (such as an email and password) and returns a result, which might be a simple Boolean or an entire user object. Custom return types can include metadata like timestamps.
The Schema also supports GraphQL subscriptions, enabling real-time updates. The type enforcement built into the Schema means that deviations from defined fields or types produce errors early, which helps maintain consistency across large teams and complex APIs.
This type system pairs well with TypeScript. Types can be auto-generated for front-end applications directly from the Schema, providing strong interoperability. When the Schema changes, types can be regenerated, keeping front-end code in sync.
Authorization and Security
Authorization is handled entirely on the server, within resolvers. Strategies vary widely—some teams build authorization directly into the Schema, distinguishing between authorized and regular user types. Others integrate third-party services like Auth0 or OAuth providers like GitHub, Facebook, or Google. Larger platforms such as AWS AppSync have built-in authorization roles.
Security is a major consideration. Since GraphQL allows nested queries, an attacker could send a deeply nested query that resembles a denial-of-service attack—following “friends of friends of friends” indefinitely. Servers should limit query depth and complexity, or maintain a safelist of allowed queries for known front-end clients.
Pagination and Data Modeling
Pagination isn’t built into the query language; it’s designed into the Schema. The GitHub GraphQL API is a well-regarded public example, supporting both positional pagination (first, last) and cursor-based pagination for navigating records.
GraphQL is not always the right fit. Modeling very large, tabular datasets can become unwieldy—auto-generating a Schema from a database with thousands of fields may result in a Schema that’s millions of lines long and no longer readable. The technology shines when there’s a human-curated Schema, where types are carefully defined and the focus is on abstracting logic to the server.



