- Introduction
- Chapter 1 The API Landscape: REST, GraphQL, and gRPC
- Chapter 2 Designing for Outcomes: Product Thinking for APIs
- Chapter 3 Resource Modeling and Domain-Driven Design
- Chapter 4 HTTP Semantics and RESTful Constraints
- Chapter 5 GraphQL Schemas, Resolvers, and Federation
- Chapter 6 gRPC and Protocol Buffers for High-Performance Services
- Chapter 7 Choosing a Hybrid Strategy: When and How to Mix Paradigms
- Chapter 8 API Contracts and Versioning Strategies
- Chapter 9 Pagination, Filtering, and Sorting Patterns
- Chapter 10 Rate Limiting, Quotas, and Fair Usage
- Chapter 11 Authentication: OAuth 2.0, OIDC, and Beyond
- Chapter 12 Authorization and Access Control: RBAC, ABAC, and Policy
- Chapter 13 Data Validation, Idempotency, and Error Design
- Chapter 14 Performance Fundamentals: Latency, Throughput, and Tail Effects
- Chapter 15 Caching Strategies: HTTP, CDN, and Application Caches
- Chapter 16 Reliability Patterns: Retries, Timeouts, Circuit Breakers, and SLOs
- Chapter 17 Observability: Logging, Metrics, Tracing, and Monitoring
- Chapter 18 Testing APIs: Contract, Unit, Integration, and Chaos Testing
- Chapter 19 Documentation and Developer Experience: Portals, SDKs, and Sandbox
- Chapter 20 Mobile-Friendly APIs: Offline Sync, Network Variability, and Efficiency
- Chapter 21 Security Best Practices: Threat Modeling, Input Handling, and Secrets
- Chapter 22 API Gateways, Proxies, and Edge Architecture
- Chapter 23 CI/CD for APIs: Schema Checks, Canary, and Zero-Downtime Deploys
- Chapter 24 Compliance and Governance: Audits, PII, and Data Residency
- Chapter 25 Operating at Scale: Multi-Region, Migration, and Evolution
API Design for Web and Mobile
Table of Contents
Introduction
APIs have become the connective tissue of modern software. Whether a product is a mobile app responding to fluctuating network conditions or a web experience integrating with dozens of services, the contract between client and server is where performance, reliability, and developer experience are decided. This book, API Design for Web and Mobile: Building scalable, secure, and developer-friendly APIs that power modern apps, is a practical guide to designing and operating APIs that meet those demands without trading away clarity or speed.
The landscape is rich with paradigms—REST, GraphQL, and gRPC each bring unique strengths and trade-offs. Rather than advocating a single “right” choice, we explore how to select the best tool for a given problem and how to combine them in hybrid strategies. You will learn when resource-oriented REST shines, where GraphQL’s flexibility accelerates iteration, and how gRPC’s efficiency enables high-throughput, low-latency communication.
Designing a great API starts with understanding the domain and the outcomes you want to enable. We emphasize modeling techniques that lead to stable contracts and predictable evolution. From the first endpoint or schema field, you will see how choices about versioning, pagination, filtering, and error design shape developer ergonomics and long-term maintainability. We present patterns for backward compatibility, schema governance, and idempotency so you can ship changes with confidence.
Security is a first-class requirement, not an afterthought. Throughout the book we integrate authentication and authorization strategies, discuss threat modeling, and outline pragmatic defenses against common attacks. You will find guidance for handling secrets, protecting personal data, and meeting compliance obligations without slowing down delivery. We connect policy to implementation so that teams can enforce least privilege while preserving developer velocity.
Performance and reliability determine how users experience your product. We cover latency fundamentals, tail behavior, and workload-specific tuning; show how to apply caching at multiple layers; and explain resiliency patterns like retries, timeouts, and circuit breakers. Equally important is knowing what your system is doing in production. We detail an observability toolkit—structured logging, metrics, traces—and pair it with monitoring and alerting practices that catch issues early and reduce mean time to recovery.
APIs succeed when developers succeed. Beyond correctness and speed, we focus on documentation, SDKs, sandbox environments, and feedback loops that cultivate a thriving ecosystem around your interfaces. Testing strategies—unit, integration, contract, and even chaos testing—are treated as part of everyday development and CI/CD, enabling safe, incremental change and zero-downtime deployments.
Finally, building for mobile requires special attention to the realities of devices and networks. We address offline-first patterns, synchronization and conflict resolution, payload efficiency, and progressive enhancement so that your API serves great experiences from high-end phones on 5G to budget devices on congested networks. By the end of this book you will have a toolkit of patterns, trade-offs, and operational practices to design APIs that are scalable, secure, and a joy to build upon—no matter what your clients look like today or how they evolve tomorrow.
CHAPTER ONE: The API Landscape: REST, GraphQL, and gRPC
APIs are often invisible until they fail. When an app loads a feed, when a payment processes, or when a smart fridge tries to order milk, an API call sits at the center of that interaction. For web and mobile experiences, the API is the product’s nervous system. It shapes performance, dictates what features are possible, and defines how easily developers can build and iterate. The choices you make about how that nervous system is designed—how it speaks, how it moves data, and how it behaves under stress—ripple through the entire stack and directly affect users, even if they never see the interface.
The modern API landscape is shaped by three dominant paradigms: REST, GraphQL, and gRPC. Each emerged to solve specific problems and carries a set of trade-offs that make it better suited for certain scenarios. REST grew out of the web’s architecture, leveraging HTTP semantics to create resource-oriented APIs that are simple to reason about and cache-friendly. GraphQL arose to solve client-driven data fetching in complex frontends, giving consumers control over the shape and size of responses. gRPC, rooted in Protocol Buffers, targets high-performance, low-latency communication, especially between services. They aren’t interchangeable, and understanding their strengths and boundaries is essential before designing anything.
At its core, REST—Representational State Transfer—is an architectural style that uses standard HTTP methods to operate on resources identified by URLs. The design encourages stateless interactions, where each request contains everything the server needs to understand and process it. Resources are manipulated using verbs like GET, POST, PUT, PATCH, and DELETE, and responses often carry representations like JSON or XML. REST’s simplicity and reliance on web infrastructure make it a natural fit for public-facing APIs, where discoverability, cacheability, and a uniform interface matter. It is the lingua franca of the web.
GraphQL takes a different approach. Instead of exposing many endpoints that return fixed data structures, it offers a single endpoint and a strongly typed schema. Clients specify exactly what fields they need, which helps avoid over-fetching and under-fetching, especially in rich user interfaces composed of many components. GraphQL’s schema-first design enables powerful tooling, like automatic documentation and client code generation, and its ecosystem supports features like subscriptions for real-time updates. While it introduces complexity on the server side—resolver execution, batching, and N+1 problems—it delivers significant flexibility for frontend developers and product teams moving quickly.
gRPC, short for gRPC Remote Procedure Calls, focuses on efficiency and contract strictness. It uses Protocol Buffers to define messages and services in a compact binary format, enabling small payloads and fast serialization. Built on HTTP/2, gRPC supports multiplexed streams, header compression, and bidirectional communication, making it excellent for internal microservice architectures where throughput and latency are critical. The trade-off is that gRPC is less human-readable than REST or GraphQL, and it can be trickier to use from browsers or mobile apps without additional gateways. It shines in controlled environments where performance and versioning discipline are paramount.
REST’s strength lies in its alignment with the web. Caching is native via HTTP headers, and intermediaries like CDNs can accelerate delivery without application changes. The uniform interface simplifies client SDKs and makes integration approachable for third-party developers. However, REST can suffer from over-fetching—returning more data than a client needs—and under-fetching—requiring multiple round trips to assemble a complete view. This is especially noticeable in mobile apps operating on constrained networks, where unnecessary bytes and extra requests directly impact user experience. The challenge in REST is often endpoint granularity and the evolution of resource relationships over time.
GraphQL’s power is client empowerment, but it shifts complexity to the server. To fulfill a query efficiently, a server must resolve fields, often across different data sources, while preventing the classic N+1 query problem where one top-level query triggers many sub-queries. Tools like DataLoader help batch and cache requests within a single operation, but careful resolver design is essential. GraphQL is less cacheable at the HTTP layer because queries are often POST requests and payloads vary significantly. Still, clients can cache normalized results, and CDNs can be tuned for specific query shapes when needed. The schema is the contract, and its discipline can be a major advantage for versioning.
gRPC prioritizes raw performance and strict contracts. Protocol Buffers provide a compact, versioned schema that ensures type safety across services, and HTTP/2 features minimize overhead. Streaming—both server-side and bidirectional—enables scenarios like real-time telemetry, chat, or financial feeds. However, gRPC is not as browser-friendly as REST or GraphQL, and mobile use may require a gateway to translate to JSON over HTTP. The binary format reduces payload size but reduces human readability, making debugging more dependent on tooling. In distributed systems with many services, gRPC’s efficiency and contract clarity can be a decisive factor.
There is no single “best” API style; the right choice depends on the problem domain and constraints. For public-facing APIs that prioritize broad accessibility and HTTP caching, REST is often the default. For frontend-heavy applications where data needs vary by screen and feature, GraphQL can accelerate iteration and reduce network chatter. For internal, high-throughput services where latency and contract discipline are critical, gRPC is frequently the tool of choice. Many systems use a mix: REST or GraphQL at the edge for clients, and gRPC internally between services. Understanding these trade-offs prevents over-engineering and aligns the API style with the user experience you want to deliver.
REST maps cleanly to the web’s architecture and is often the simplest choice for resource-oriented APIs. A resource is represented by a URL, and standard HTTP verbs express operations on that resource. This uniformity makes REST easy to understand and adopt. Caching is straightforward because HTTP provides cache-control directives, and intermediaries can store responses without application involvement. In mobile contexts, this caching can significantly reduce latency and data usage. However, REST’s simplicity can become a limitation when client needs diverge, requiring either coarse endpoints that return large payloads or multiple fine-grained endpoints that complicate client logic and increase round trips.
A typical REST design revolves around nouns rather than verbs. You might have /users, /posts, and /orders, with relationships expressed via sub-resources like /users/123/orders. The server defines the structure of the response, which often includes more fields than a particular client needs. This can be fine for simple applications, but as UIs become more complex, the mismatch between server-defined payloads and client requirements grows. Over-fetching wastes bandwidth, and under-fetching forces additional requests. Mobile networks exacerbate these costs. A good REST design mitigates this by using query parameters for sparse fieldsets and pagination, but it’s an opt-in pattern rather than a guarantee.
GraphQL flips the script by letting clients dictate the shape of the response. Instead of a fixed endpoint per resource, there’s a single /graphql endpoint that accepts a query payload. The server validates the query against the schema and executes resolvers to produce the requested data. This model reduces round trips and eliminates wasted bytes, which is a win for mobile apps and feature-rich web UIs. The schema becomes a living contract, and tools like GraphiQL and Apollo Studio provide introspection and documentation. However, the flexibility introduces server-side complexity, particularly in resolver performance and batching, which must be addressed to maintain predictable latency.
The core of GraphQL’s performance challenge is the N+1 problem. Suppose you query a list of authors and their posts. A naive resolver might fetch the list of authors in one query, then issue a separate database query for each author’s posts, leading to N+1 queries total. This can devastate performance under load. The solution involves batching techniques, such as DataLoader, which collect IDs across resolver invocations and issue a single batched request. Careful schema design and resolver optimization are required to ensure GraphQL remains efficient as query complexity grows. When done well, GraphQL can be both flexible and performant.
gRPC’s design philosophy centers on efficiency and contract precision. Protocol Buffers define messages with clear types and versioning semantics, and services specify RPC methods with request and response schemas. Because gRPC uses HTTP/2 under the hood, it supports multiplexing, header compression, and streaming, enabling high-throughput communication. This makes gRPC a strong fit for internal microservices and mobile backends where latency matters. However, gRPC’s binary format is not human-readable, and client support varies across platforms. Gateways or transcoders are often necessary to expose gRPC services to browsers or older mobile clients as JSON over HTTP.
REST is widely used for public-facing APIs because it leverages HTTP and is accessible to a broad range of clients. It’s easy to document, easy to test with a browser or curl, and benefits from standardized caching and security practices. The challenge is designing endpoints that evolve gracefully as products grow. Adding fields can be safe if clients ignore unknown properties, but removing fields or changing semantics can break integrations. Pagination strategies, filtering conventions, and consistent error formats are essential to maintain a coherent developer experience. Well-designed REST APIs feel predictable, even as they scale.
GraphQL’s contract is the schema, which serves as both documentation and a runtime validation mechanism. Types, queries, mutations, and subscriptions define the capabilities of the API, and introspection enables tooling to explore and generate clients. This schema-driven approach reduces friction when iterating on features, as clients can adopt new fields without requiring server changes to existing endpoints. However, the schema must be governed. Without discipline, it can bloat with one-off fields, and resolver performance can degrade as the graph grows. Teams must set policies for schema evolution, deprecation, and field-level ownership.
gRPC is built for service-to-service communication. It excels where strict contracts and high throughput are critical. Using Protocol Buffers, you define a versioned contract that both client and server adhere to, reducing surprises when deploying changes. Streaming capabilities unlock patterns that are awkward in REST or GraphQL, such as continuous updates from server to client or bi-directional streams for collaborative applications. The downside is client support: browsers need a translation layer, and mobile clients may need a gateway to convert between gRPC and JSON over HTTP. In controlled internal networks, gRPC’s performance advantages are compelling.
Each API style interacts differently with the web’s infrastructure. REST leverages HTTP caching and standard status codes, which makes it easy to integrate with CDNs, proxies, and monitoring tools. GraphQL typically bypasses HTTP-level caching because queries are sent via POST and payloads vary widely, though persistent queries and CDN support for specific shapes can help. gRPC sits on HTTP/2 and is optimized for long-lived connections and streaming, which changes how load balancers and proxies handle traffic. Understanding these differences is crucial for performance tuning and reliability, particularly in mobile scenarios where network variability is a constant factor.
Security considerations also differ across paradigms. REST commonly uses standard HTTP authentication and authorization flows, and its resource-oriented design aligns well with scoped access policies. GraphQL requires fine-grained authorization at the field and object level, because a single query can traverse many parts of the graph; you need mechanisms to enforce who can see which fields. gRPC often relies on mutual TLS and service identity for internal security, with additional layers at the edge for public exposure. In all cases, input validation, rate limiting, and protection against injection attacks remain essential.
Versioning is a recurring challenge. REST often uses URL versioning (e.g., /v1/users) or content negotiation, and careful design can minimize breaking changes. GraphQL avoids versioning by extending schemas with new fields and deprecating old ones; clients opt in to new capabilities without disrupting existing queries. gRPC uses explicit versioning in Protocol Buffers and can support backward-compatible changes by adding fields rather than altering existing ones. Each approach has trade-offs, and the best strategy depends on how rapidly your product evolves and how many clients you must support simultaneously.
Operational concerns vary by style. REST APIs often have straightforward deployment and rollback processes, with clear request/response patterns that are easy to trace. GraphQL adds complexity in query analysis and resolver performance; understanding query costs and implementing safeguards is critical to prevent abuse. gRPC benefits from structured contracts and HTTP/2 features but requires tooling for observability, especially with streaming RPCs. Regardless of style, you should plan for logging, metrics, and tracing from day one, and build operational playbooks that account for the unique failure modes of each approach.
The decision between REST, GraphQL, and gRPC rarely needs to be absolute. Many organizations run hybrid architectures: REST or GraphQL at the edge for mobile and web clients, and gRPC internally between microservices. Gateways or API management layers can translate between formats, enforcing security and caching policies consistently. The key is aligning the API style with the consumption pattern: user-facing clients benefit from GraphQL’s flexibility and REST’s simplicity, while internal services benefit from gRPC’s performance and contract strictness. Well-designed boundaries keep complexity contained and allow teams to evolve components independently.
Choosing the right style is about mapping the API to the outcomes you want to enable. If your priority is broad accessibility and leveraging HTTP’s caching and semantics, REST is a strong foundation. If your frontend is complex and your team needs rapid iteration with minimal network overhead, GraphQL can be transformative—if you invest in resolver performance and schema governance. If you need high-throughput, low-latency communication between services, gRPC offers a compelling path. In practice, these styles are complementary, and the best systems use the right tool for the right job.
Whichever path you choose, the principles that follow in this book will help you design APIs that are scalable, secure, and a joy to use. We will explore modeling techniques, contract patterns, and operational practices that apply across paradigms. We’ll examine how to version APIs without breaking clients, how to paginate and filter efficiently, and how to protect your systems and users. We’ll cover performance fundamentals, caching strategies, and reliability patterns, and we’ll look at observability and testing as first-class disciplines. Whether you’re building RESTful resource APIs, GraphQL graphs, or high-performance gRPC services, the goal is the same: predictable, fast, and developer-friendly interfaces that power great web and mobile experiences.
This is a sample preview. The complete book contains 27 sections.