Side-by-side comparison — over-fetching, type safety, caching, and when to use each.
Welcome everyone. Today we're diving into one of the most debated topics in API design: GraphQL versus REST. If you've ever wondered which approach is right for your next project, or why so many companies are adopting GraphQL alongside their existing REST APIs, this talk is for you. We'll compare these two paradigms head-to-head, look at real-world use cases, and give you a practical framework for making the right choice. Let's get started.
Let's begin with REST, the resource-based approach that's been the standard for web APIs for over two decades. Looking at the diagram, you can see how REST organizes data around resources. The client makes three separate requests to get a user's profile, their posts, and their followers. Each resource lives at its own URL endpoint. Now, looking at the bash code below, notice how we define endpoints for each resource and action. We have GET for reading, POST for creating, PUT for updating, and DELETE for removing resources. Each of these operations maps to a specific HTTP verb and URL pattern. This is the foundation of RESTful design.
GraphQL takes a fundamentally different approach. As you can see in the sequence diagram, there's only one endpoint: slash graphql. Instead of multiple URLs, the client sends a query that specifies exactly what data it needs. In this example, we're asking for a user's name and their post titles in a single request. The server responds with precisely that structure. Looking at the schema definition below, GraphQL uses a strongly-typed schema. We define types like User and Post, and the relationships between them. Notice how the User type has a posts field that returns an array of Post objects. This schema becomes the contract between client and server.
Here's where we see REST's biggest pain point: over-fetching. Look at the REST response on the left. We asked for a user, and got back their ID, name, email, avatar, bio, phone, address, timestamps, and preferences. But what if we only needed the name and email? We've wasted bandwidth transferring all that extra data. Now compare that to the GraphQL query on the right. We explicitly request just name and email, and that's exactly what we get back. No wasted bytes. This becomes critical for mobile apps on cellular networks or when serving millions of requests per day.
The flip side is under-fetching. Looking at the terminal output, see how REST requires three separate HTTP requests to display a user dashboard. First we fetch the user, then their posts, then the comments on those posts. That's three round-trips with network latency between each one. If the user has ten posts, we'd need eleven requests total. This is the infamous N plus 1 problem. Now look at the GraphQL query below. We get the user, their posts, and nested comments all in a single request with one response. The query structure mirrors exactly what we need to render the page. This eliminates those costly network waterfalls.
Let's compare these approaches across ten key dimensions. Looking at the table, REST uses multiple endpoints per resource, while GraphQL has a single endpoint. For data fetching, REST's server decides what you get, but GraphQL lets the client specify the exact shape. Caching is interesting: REST benefits from native HTTP caching with ETags and cache headers, but GraphQL requires a normalized cache like Apollo's. Error handling differs too: REST uses standard HTTP status codes, while GraphQL always returns 200 with errors embedded in the response body. For versioning, REST typically uses URL-based versions like v1 or v2, whereas GraphQL evolves the schema without breaking changes. Both have trade-offs in tooling, learning curve, and real-time capabilities.
One of GraphQL's killer features is built-in type safety. Looking at the schema on the left, we define a mutation for creating posts with a strongly-typed input. Notice how fields are marked with exclamation points to indicate they're required. The tags field is optional and nullable. Now here's the magic: on the right, we have TypeScript types that were auto-generated from that schema. Tools like GraphQL Code Generator parse your schema and create matching TypeScript interfaces. This means compile-time validation in your frontend code. If you try to access a field that doesn't exist or pass the wrong type, your IDE catches it before you even run the code. REST can achieve this with OpenAPI specs, but it's not built into the protocol like it is with GraphQL.
So when should you choose each approach? We have four cards here covering the strengths and pitfalls of both. REST excels at simple CRUD operations, public-facing APIs where HTTP semantics matter, scenarios where caching is critical, and file-heavy operations. It's also great when your team is new to API design. GraphQL shines with complex nested data, multiple client platforms with different needs, rapidly evolving frontends, real-time subscriptions, and when strict type safety is required. But watch out for REST's over-fetching and versioning headaches. And be aware that GraphQL introduces complexity in caching, can cause N plus 1 queries on your server if you're not careful, and has a steeper learning curve.
Let's look at some real numbers. The stats show that 90 percent of APIs still use REST as of 2025, but GraphQL adoption has jumped to 38 percent, up from just 14 percent in 2021. GitHub's GraphQL API serves over 47,000 daily users, and Shopify processes a staggering 200 billion GraphQL queries per day. Looking at the cards, GitHub migrated from REST v3 to GraphQL v4, though they kept REST available for backward compatibility. Shopify went GraphQL-first back in 2018 and now powers all their APIs with it. Interestingly, Netflix and Twitter use GraphQL federation internally for microservice composition, but still expose REST APIs to the public. This hybrid approach is becoming increasingly common.
Here's a practical framework for making your choice. The callout at the top summarizes it well: choose REST for resource-oriented, cache-heavy, or public APIs. Choose GraphQL for diverse clients, complex data relationships, or maximum frontend flexibility. Many teams use both. Now let's walk through three scenarios. For a mobile app, GraphQL wins because mobile devices need minimal payloads and single-request loading to reduce latency on cellular networks. For a public API, REST wins because external developers expect standard HTTP semantics, status codes, and cacheable endpoints. For microservices, consider both: use GraphQL federation as a gateway layer for your frontend teams, but stick with REST or gRPC for internal service-to-service communication.
Let's wrap up with the key points to remember. First, REST excels at simple CRUD operations, HTTP caching, and public APIs. It's still the default choice for most backend systems and that's not changing anytime soon. Second, GraphQL eliminates over-fetching and under-fetching by letting clients specify their exact data needs in a single request. Third, type safety is intrinsic to GraphQL's schema-first design, enabling powerful code generation and compile-time validation that catches errors before they reach production. And finally, don't think of this as an either-or decision. Choose based on your specific use case, and remember that many successful production systems use both REST and GraphQL together, each playing to their strengths. Thanks for watching.
Hands-on implementation guides with detailed code examples, step-by-step instructions, and expanded explanations for each topic.