liveBook · Manning

What you will learn in The Design of Web APIs, Second Edition

by Arnaud Lauret
Foreword by Kin Lane

Chapter by chapter

Chapter 1: What is API design?

1.1 What is a web API? · 1.1.1 A web API is a remote interface for applications · 1.1.2 A web API uses the HTTP protocol · 1.1.3 A web API is an interface to an implementation · 1.1.4 A web API is an interface for others · 1.2 Why does the design of any API matter? · 1.2.1 What if a terrible API was a kitchen appliance? · 1.2.2 Poor web API design affects developers and architecture · 1.2.3 Poor web API design puts security and infrastructure at risk · 1.2.4 Poor web API design affects end-user and third-party experiences · 1.2.5 Taking care of design unleashes the power of APIs · 1.3 When to design web APIs? · 1.3.1 Any new API must be designed · 1.3.2 Any modification of any existing API must be designed · 1.3.3 Design happens between choosing to create an API and coding it · 1.4 Who designs web APIs? · 1.4.1 The three profiles needed to design an API · 1.4.2 The stakeholders influencing API design · 1.5 How do we design web APIs? · 1.6 Designing APIs step by step · 1.6.1 Identifying the API capabilities · 1.6.2 Designing the programming interface · 1.6.3 Describing the programming interface · 1.6.4 Enriching API design artifacts · 1.7 Designing APIs layer by layer · 1.7.1 Designing a versatile API that does the right job · 1.7.2 Designing a user-friendly and interoperable API · 1.7.3 Integrating constraints in an API design · 1.7.4 Using a reasoned and continuously improving design process · 1.8 Summary

What you learn in chapter 1 →

Chapter 2: Identifying API capabilities

2.1 An overview of identifying API capabilities · 2.1.1 Starting with the output of the Define stage · 2.1.2 Analyzing what users need to achieve · 2.1.3 Identifying versatile operations to achieve use cases · 2.1.4 Keeping programming interface design concerns for later · 2.1.5 Clarifying the subject matter and input · 2.2 Introducing the API Capabilities Canvas · 2.2.1 How does the API Capabilities Canvas work? · 2.2.2 Tools to use along with the API Capabilities Canvas · 2.3 Walking the nominal paths · 2.3.1 Identifying users · 2.3.2 Listing use cases · 2.3.3 Decomposing use cases in steps · 2.3.4 Determining inputs and success outcomes · 2.3.5 Spotting missing elements with sources and usages · 2.3.6 Analyzing the spotted elements · 2.4 Walking the alternative and failure paths · 2.4.1 Analyzing failures for each step · 2.4.2 Adding alternative branches on each use case · 2.4.3 Analyzing the alternative users and use cases · 2.5 Refining steps to identify operations · 2.5.1 Differentiating steps and operations · 2.5.2 Identifying unique and versatile operations · 2.6 Focusing on the proper needs · 2.6.1 Staying within the Define stage’s needs scope · 2.6.2 Focusing on the proper perspectives · 2.6.3 Asking why to investigate any problem · 2.7 Avoiding integrating too specific consumers’ perspective · 2.7.1 Avoiding mapping consumers’ UI · 2.7.2 Avoiding integrating consumers’ business logic · 2.8 Avoiding exposing the provider’s perspective · 2.8.1 Avoiding exposing the provider’s data organization · 2.8.2 Avoiding exposing the provider’s business logic · 2.8.3 Avoiding exposing the provider’s software architecture · 2.9 Summary · 2.10 Exercises · 2.11 Exercise 2.1 · 2.12 Exercise 2.2 · 2.13 Exercise 2.3 · 2.14 Exercise 2.4 · 2.15 Exercise 2.5

What you learn in chapter 2 →

Chapter 3: Observing operations from the REST angle

3.1 An overview of programming interface design · 3.1.1 Introducing the basics of the HTTP protocol · 3.1.2 Introducing the basics of REST APIs · 3.1.3 Contrasting REST with non-HTTP-compliant web APIs · 3.1.4 How do we design a REST programming interface? · 3.1.5 Why not discuss HTTP and REST when identifying capabilities? · 3.2 Observing the API Capabilities Canvas from the REST angle · 3.2.1 Reorganizing and expanding the API capabilities canvas · 3.2.2 How to observe operations from the REST angle · 3.3 Identifying resources and their relations · 3.3.1 What is a resource? · 3.3.2 Identifying an operation’s resource · 3.3.3 Tweaking an operation’s description to identify resource · 3.3.4 Identifying resource relations · 3.3.5 Using patterns and recipes to identify resources and relations · 3.4 Identifying resource actions · 3.4.1 What is an action, and how can it be identified? · 3.4.2 Listing an action’s inputs · 3.4.3 Dealing with the operation’s resource when listing an action’s inputs · 3.4.4 Listing an action’s outputs · 3.4.5 Dealing with contradictory successes and failures when listing outputs · 3.5 Summary · 3.6 Exercises · 3.7 Exercise 3.1 · 3.8 Exercise 3.2 · 3.9 Exercise 3.3 · 3.10 Exercise 3.4

What you learn in chapter 3 →

Chapter 4: Representing operations with HTTP

4.1 Representing operations with HTTP · 4.1.1 What an operation looks like with HTTP · 4.1.2 How to represent operations with HTTP · 4.2 Representing resources with paths · 4.2.1 What is a resource path? · 4.2.2 Designing meaningful resource paths · 4.2.3 Targeting specific elements with path parameters · 4.2.4 Showing resource relationships with a hierarchy · 4.2.5 Representing lists and their elements · 4.3 Representing actions with HTTP methods · 4.3.1 Determining which HTTP methods to use · 4.3.2 Choosing HTTP methods to represent actions · 4.3.3 Representing search, read, and delete actions · 4.3.4 Representing update actions · 4.3.5 Representing create actions · 4.3.6 Mapping typical operations to HTTP · 4.4 Choosing input data locations in HTTP requests · 4.4.1 Where to put input data in an HTTP request · 4.4.2 An overview of input data natures · 4.4.3 Choosing a location for resource identifiers · 4.4.4 Choosing a location for resource representations · 4.4.5 Choosing a location for resource modifiers · 4.4.6 Hesitating between resource identifiers and modifiers · 4.4.7 Choosing input data locations for typical operations · 4.5 Representing output types with HTTP statuses · 4.5.1 What is an HTTP status? · 4.5.2 Choosing HTTP statuses for outputs · 4.5.3 Choosing successful HTTP statuses for read operations · 4.5.4 Choosing successful HTTP statuses for delete operations · 4.5.5 Choosing successful HTTP statuses for update operations · 4.5.6 Choosing successful HTTP statuses for search operations · 4.5.7 Choosing successful HTTP statuses for create operations · 4.5.8 Choosing error HTTP statuses · 4.5.9 Ensuring exhaustive error-handling · 4.5.10 Choosing HTTP statuses for typical operations · 4.6 Choosing output locations in HTTP responses · 4.6.1 Where to put data in an HTTP response · 4.6.2 Filling the output data gaps · 4.6.3 Choosing output locations · 4.6.4 Choosing output data locations for typical operations · 4.7 Representing a “do” operation with HTTP · 4.7.1 Using an action resource · 4.7.2 Turning the action into a business concept · 4.7.3 Focusing on the result · 4.8 Using the REST architectural style principles for API design · 4.8.1 Introducing the REST architectural style · 4.8.2 Applying REST principles to API design · 4.8.3 Debates about what is (or is not) REST · 4.9 Summary · 4.10 Exercises · 4.11 Exercise 4.1 · 4.12 Exercise 4.2 · 4.13 Exercise 4.3 · 4.14 Exercise 4.4 · 4.15 Exercise 4.5

What you learn in chapter 4 →

Chapter 5: Modeling data

5.1 An overview of data modeling · 5.1.1 Which data are we modeling? · 5.1.2 Introducing the JSON portable data format · 5.1.3 Modeling data · 5.2 Designing theoretical resource data models · 5.2.1 Determining a resource’s structure · 5.2.2 Choosing an object resource’s properties · 5.2.3 Choosing a property name and type · 5.2.4 Indicating required properties · 5.2.5 Listing and modeling properties efficiently · 5.3 Designing inputs and outputs data models · 5.3.1 Designing a read operation’s inputs and success outputs · 5.3.2 Designing a search operation’s inputs and success outputs · 5.3.3 Designing a create operation’s inputs and success outputs · 5.3.4 Designing an update operation’s inputs and success outputs · 5.3.5 Designing a delete operation’s inputs and success outputs · 5.3.6 Designing a temporary error data model · 5.4 Streamlining input and output data modeling · 5.4.1 Designing and using the complete, summarized, minimal, and identifier models · 5.4.2 Designing and using the creation, replacement, and modification models · 5.4.3 Modeling data for “do” operations · 5.4.4 Differentiating similarly named elements · 5.5 Using data to ensure completeness and proper focus · 5.5.1 Spotting missing elements by analyzing input sources and output usages · 5.5.2 Ensuring complete business error-handling · 5.5.3 Focusing on the proper elements · 5.6 Summary · 5.7 Exercises · 5.8 Exercise 5.1 · 5.9 Exercise 5.2 · 5.10 Exercise 5.3 · 5.11 Exercise 5.4

What you learn in chapter 5 →

Chapter 6: Describing HTTP operations with OpenAPI

6.1 Overview of describing the programming interface · 6.1.1 Introducing the OpenAPI Specification · 6.1.2 Using OpenAPI during design · 6.1.3 Introducing the YAML format · 6.1.4 Contrasting an OpenAPI document with our API spreadsheet · 6.1.5 Describing the programming interface while designing it · 6.2 Authoring OpenAPI documents · 6.2.1 Introducing the specification-first and code-first approaches · 6.2.2 Contrasting the specification-first and code-first approaches · 6.2.3 Picking an OpenAPI editor · 6.2.4 Choosing an OpenAPI version · 6.2.5 Choosing between JSON and YAML · 6.3 Describing HTTP operations with OpenAPI · 6.4 Describing resource paths · 6.4.1 Initiating an OpenAPI document · 6.4.2 Describing a path · 6.4.3 Describing a path with path parameters · 6.5 Describing operations · 6.6 Describing operation inputs · 6.6.1 Describing query parameters and other non-body parameters · 6.6.2 Describing request bodies · 6.7 Describing operation output HTTP status codes · 6.7.1 Describing an output case type with an HTTP status · 6.7.2 Dealing with outputs sharing the same HTTP status code · 6.8 Describing operation output contents · 6.8.1 Describing response bodies · 6.8.2 Dealing with responses without bodies · 6.8.3 Describing response headers · 6.9 Summary · 6.10 Exercises · 6.11 Exercise 6.1 · 6.12 Exercise 6.2 · 6.13 Exercise 6.3 · 6.14 Exercise 6.4 · 6.15 Exercise 6.5

What you learn in chapter 6 →

Chapter 7: Describing data with JSON Schema in OpenAPI

7.1 An overview of describing data · 7.1.1 Introducing JSON Schema · 7.1.2 Contrasting OpenAPI and JSON Schema with our API spreadsheet · 7.1.3 Describing data while designing it · 7.2 Authoring a JSON Schema data model in OpenAPI · 7.3 Adding complete resource data models to the OpenAPI document · 7.3.1 Choosing a location for the resource model in the OpenAPI document · 7.3.2 Initiating the resource model description · 7.4 Describing complete resource data models with JSON Schema · 7.4.1 Describing an object · 7.4.2 Adding properties to an object · 7.4.3 Describing an atomic property · 7.4.4 Describing an object property · 7.4.5 Describing an array property · 7.4.6 Stating which properties are required · 7.5 Describing operation input and output data · 7.6 Describing operation non-body data · 7.6.1 Describing non-body request parameters with inline schemas · 7.6.2 Tweaking non-atomic parameter serialization · 7.6.3 Describing response headers with inline schemas · 7.7 Describing operation body data · 7.7.1 Using references to resource models in response bodies · 7.7.2 Deriving the complete resource model to create other reusable models · 7.7.3 Using references to resource models in request bodies · 7.7.4 Mixing inline schema and reference · 7.8 Summary · 7.9 Exercises · 7.10 Exercise 7.1 · 7.11 Exercise 7.2 · 7.12 Exercise 7.3

What you learn in chapter 7 →

Chapter 8: Designing user-friendly, interoperable data

8.1 The user-friendliness and interoperability layer of API design · 8.1.1 Overview of the API user experience · 8.1.2 Which users’ experiences matter to us? · 8.1.3 How API design user-friendliness and interoperability affect UX · 8.2 What makes data user-friendly and interoperable? · 8.2.1 User-friendly data meets user needs · 8.2.2 User-friendly data helps us find and interpret information · 8.2.3 User-friendly data limits consumers’ work · 8.2.4 User-friendly data is consistent · 8.2.5 Interoperable data is consistent and standard · 8.3 When and how to design user-friendly, interoperable data · 8.3.1 Which data must be user-friendly and interoperable? · 8.3.2 When to address user-friendly, interoperable data · 8.3.3 How to design user-friendly, interoperable data · 8.4 Selecting and crafting ready-to-use data · 8.4.1 Choosing simple and meaningful but useful data · 8.4.2 Adding supporting data to ease and secure interpretation · 8.4.3 Adding processed data to reduce consumer effort · 8.4.4 Choosing well-known or standard resource identifiers · 8.4.5 Choosing well-known or standard data · 8.5 Choosing user-friendly, interoperable atomic types and formats · 8.5.1 Considering formatting numbers as strings · 8.5.2 Managing non-human-readable codes · 8.5.3 Managing dates and times · 8.6 Organizing data · 8.6.1 Grouping data with objects · 8.6.2 Grouping data with arrays · 8.6.3 Sorting data in arrays and objects · 8.7 Choosing data granularity and scope · 8.7.1 Considering relevance, not size · 8.7.2 Embedding lists in a resource model · 8.7.3 Modeling embedded resources · 8.8 Designing user-friendly names · 8.8.1 When to design user-friendly names · 8.8.2 Designing simple, clearly organized, concise names · 8.8.3 Learning by fixing non-user-friendly names · 8.9 Aiming for consistency and standardization · 8.9.1 Seeking local, domain, or global standardization · 8.9.2 Using well-known or standard identifiers consistently · 8.9.3 Defining a naming pattern for identifiers · 8.9.4 Naming, typing, and structuring consistently · 8.10 Summary · 8.11 Exercises · 8.12 Exercise 8.1 · 8.13 Exercise 8.2 · 8.14 Exercise 8.3

What you learn in chapter 8 →

Chapter 9: Designing user-friendly, interoperable operations

9.1 What makes operations user-friendly and interoperable? · 9.1.1 User-friendly operations expose clear capabilities that meet the needs · 9.1.2 User-friendly operations use user-friendly data and are helpful · 9.1.3 User-friendly, interoperable operations are consistent and standard · 9.2 When and how to design user-friendly, interoperable operations · 9.2.1 When to take user-friendly, interoperable operations into consideration · 9.2.2 How to design user-friendly, interoperable operations · 9.3 Designing easy-to-understand, guessable operations · 9.3.1 Combining meaningful resource paths and HTTP compliance · 9.3.2 Creating predictable resource paths · 9.3.3 Crafting short but accurate resource paths · 9.4 Requesting easy-to-provide inputs · 9.4.1 Using typical and HTTP-compliant input locations · 9.4.2 Mapping inputs to outputs · 9.4.3 Requesting well-known or standard data · 9.4.4 Minimizing inputs with default and server-processed data · 9.5 Returning ready-to-use successful responses · 9.5.1 Choosing adequate HTTP status and HTTP-compliant data locations · 9.5.2 Returning sufficiently informative data · 9.6 Filtering, sorting, and paginating lists · 9.6.1 Designing guessable filters that map returned data · 9.6.2 Designing flexible filters · 9.6.3 Enabling free search and complex logic with a q filter · 9.6.4 Minimizing filters · 9.6.5 Enabling sort with helpful defaults · 9.6.6 Paginating lists · 9.6.7 Returning filter, sort, and pagination metadata · 9.7 Adapting request and response data · 9.7.1 Handling different data formats · 9.7.2 Translating data and adapting to locale · 9.7.3 Tweaking returned data · 9.8 Handling consumer errors gracefully · 9.8.1 Limiting consumer errors · 9.8.2 Using adequate HTTP status codes · 9.8.3 Providing informative, problem-solving feedback · 9.8.4 Returning machine-readable feedback · 9.8.5 Returning an exhaustive list of errors · 9.8.6 Using standards · 9.9 Avoiding hiding multiple capabilities in a single operation · 9.9.1 Reconsidering request and response data granularity · 9.9.2 Reconsidering an operation’s purpose · 9.10 Aiming for consistency and standardization · 9.10.1 Using standardized data consistently · 9.10.2 Adopting standardized behavior consistently · 9.10.3 Offering standardized features consistently · 9.11 Summary · 9.12 Exercises · 9.13 Exercise 9.1 · 9.14 Exercise 9.2 · 9.15 Exercise 9.3 · 9.16 Exercise 9.4 · 9.17 Exercise 9.5

What you learn in chapter 9 →

Chapter 10: Designing user-friendly, interoperable operation flows

10.1 What makes an operation flow user-friendly and interoperable? · 10.1.1 Using user-friendly, interoperable elements · 10.1.2 Being designed as a whole · 10.1.3 Being concise and flexible · 10.1.4 Meeting user needs within the flow · 10.1.5 Being helpful across operations · 10.1.6 Aiming for consistency and standardization · 10.2 When and how to optimize flows · 10.2.1 When to consider flow optimization · 10.2.2 How to optimize flows · 10.3 Designing concise, error-limiting, flexible flows · 10.3.1 Introducing the money-transfer use case · 10.3.2 Uncovering operation flow problems · 10.3.3 Calling read and search operations once · 10.3.4 Enhancing operations with use-case-specific features · 10.3.5 Adding use-case-specific operations · 10.3.6 Combining operations into a use-case-specific operation · 10.3.7 Adding use-case-specific output data · 10.3.8 Avoiding constraining consumer flow · 10.4 Designing flexible data-saving flows · 10.4.1 Introducing the “Open an account” use case · 10.4.2 Understanding how data-saving constrains consumer flow · 10.4.3 Enabling partial data-saving · 10.4.4 Carefully aggregating saving operations · 10.4.5 Smoothing validation and separating it from completion · 10.4.6 Enabling full and partial data-saving flows · 10.4.7 Redirecting the consumer to the finalized resource · 10.5 Summary · 10.6 Exercises · 10.7 Exercise 10.1 · 10.8 Exercise 10.2

What you learn in chapter 10 →

Chapter 11: Designing user-friendly, interoperable APIs

11.1 What makes an API user-friendly and interoperable? · 11.1.1 Having a clear purpose that meets focused needs · 11.1.2 Enabling discovery and navigation · 11.1.3 How to create user-friendly, interoperable APIs · 11.2 Creating one or multiple APIs · 11.2.1 When to discuss API granularity · 11.2.2 Identifying independent sets of operations · 11.2.3 Keeping in mind that sub-APIs can be related · 11.3 Clarifying the API’s purpose with its name · 11.3.1 When to choose an API name · 11.3.2 Choosing an API name · 11.3.3 Adding the API name to the API base path · 11.4 Enabling interoperable API browsing with HTTP and hypermedia APIs · 11.4.1 Listing a resource’s operations with the OPTIONS HTTP method · 11.4.2 Providing pagination, formats, and resources links with the Link header · 11.4.3 Using hypermedia formats for relations and actions · 11.4.4 Using content negotiation to select hypermedia or plain JSON format · 11.4.5 Ensuring that subject matter data is always available · 11.4.6 Considering browsing capabilities · 11.5 Summary · 11.6 Exercises · 11.7 Exercise 11.1 · 11.8 Exercise 11.2

What you learn in chapter 11 →

Chapter 12: Designing a secure API

12.1 Overview of API security · 12.1.1 What happens during an API call? · 12.1.2 Uncovering design-related API security problems · 12.2 When and how to handle security during design · 12.2.1 When to consider security during API design · 12.2.2 How API design contributes to API security · 12.3 Exposing only the necessary data and operations · 12.3.1 What are sensitive operations and data? · 12.3.2 Challenging sensitive and non-sensitive data and operations · 12.3.3 Modifying data to make it less sensitive or non-sensitive · 12.3.4 Splitting an operation to separate concerns · 12.3.5 Separating sensitive operations in dedicated APIs · 12.4 Ensuring that implemented operations behave according to context · 12.4.1 Describing who sees or does what · 12.4.2 Describing what list or search operations return · 12.4.3 Describing how inputs narrow access · 12.4.4 Describing all expected implementation checks and behaviors · 12.4.5 Narrowing access by design · 12.5 Ensuring data integrity · 12.5.1 Corrupting data with regular API calls · 12.5.2 Correctly implementing HTTP methods · 12.5.3 Preventing request replay · 12.5.4 Enabling and enforcing conditional updates · 12.6 Avoiding protocol- or architecture-based security problems · 12.6.1 What may not be secured on an API call over HTTPS · 12.6.2 Dealing with sensitive search parameters · 12.6.3 Dealing with sensitive resource IDs · 12.6.4 Integrating data encryption or signing in the design · 12.7 Limiting consumer access with scopes · 12.7.1 Limiting access to an operation with a scope · 12.7.2 Measuring the importance of scopes and their design · 12.8 Designing scopes · 12.8.1 Creating operation-based scopes · 12.8.2 Creating resource-, concept-, or use-case-based scopes · 12.8.3 Creating scopes for read or write operations · 12.8.4 Creating end-user- or consumer-based scopes · 12.8.5 Tweaking operation behavior with scopes · 12.8.6 Deciding which scope types to use · 12.9 Describing scopes with OpenAPI · 12.9.1 Defining scopes · 12.9.2 Using scopes · 12.10 Erroring securely · 12.10.1 Handling token-related errors · 12.10.2 Handling missing scopes or permissions · 12.10.3 Avoiding disclosing implementation details on server errors · 12.10.4 Providing implementation details in response descriptions in OpenAPI · 12.10.5 Enforcing expected error data with JSON Schema · 12.11 Summary · 12.12 Exercises · 12.13 Exercise 12.1 · 12.14 Exercise 12.2 · 12.15 Exercise 12.3 · 12.16 Exercise 12.4 · 12.17 Exercise 12.5

What you learn in chapter 12 →

Chapter 13: Designing an efficient API

13.1 An overview of API efficiency · 13.1.1 How an API can be inefficient · 13.1.2 When to be concerned about efficiency · 13.1.3 How design contributes to API efficiency · 13.2 Optimizing the design only when necessary · 13.2.1 Ensuring HTTP configuration efficiency · 13.2.2 Limiting API usage with rate-limiting · 13.2.3 Enhancing response with rate-limiting headers · 13.2.4 Finding the true root cause · 13.3 Focusing on user needs and user-friendliness to be efficient · 13.3.1 What we’ve learned so far · 13.3.2 Analyzing an inefficient flow · 13.3.3 Optimizing each operation · 13.3.4 Rethinking the flow · 13.4 Enabling caching and conditional readings · 13.4.1 An overview of caching and conditional readings · 13.4.2 Not letting consumers decide how to cache · 13.4.3 Defining caching policies based on data and context · 13.4.4 Returning cache directives · 13.4.5 Retrieving data only when modified · 13.5 Optimizing data volume · 13.5.1 Enabling resource model selection · 13.5.2 Toggling the return of updated or created resources · 13.5.3 Enabling field selection · 13.5.4 Centralizing redundant data in dedicated operations · 13.5.5 Considering a partial update over total replacement · 13.5.6 Contrasting JSON Merge Patch and JSON Patch for array updates · 13.6 Optimizing pagination · 13.6.1 Optimizing page size limits · 13.6.2 Choosing cursor- or index-based pagination · 13.7 Processing multiple elements with bulk or batch operations · 13.7.1 Designing bulk operation requests · 13.7.2 Optimizing bulk operation requests · 13.7.3 Clarifying a bulk operation error policy · 13.7.4 Designing a mixed response · 13.7.5 Designing an all-or-nothing response · 13.7.6 Optimizing bulk request responses · 13.7.7 Partitioning access to bulk operations · 13.8 Considering a separate optimized API · 13.9 Summary · 13.10 Exercises · 13.11 Exercise 13.1 · 13.12 Exercise 13.2 · 13.13 Exercise 13.3

What you learn in chapter 13 →

Chapter 14: Adapting the API design to the context

14.1 Integrating context into the API design · 14.1.1 How context can affect the design of an API · 14.1.2 Seeking constraints and limitations during design · 14.1.3 Challenging constraints and limitations · 14.1.4 Making trade-offs · 14.2 Dealing with consumer and provider constraints · 14.2.1 Working around consumer HTTP method limitations · 14.2.2 Accommodating consumers who are used to different data formats · 14.2.3 Managing planned interruptions · 14.2.4 Ensuring data and URL compatibility · 14.2.5 Implementing partial updates · 14.3 Handling data and files · 14.3.1 Collecting data and files in a flow · 14.3.2 Sending data and files with a single call · 14.3.3 Retrieving data and files with a single call · 14.3.4 Describing files with OpenAPI · 14.3.5 Describing mixed data and files with OpenAPI · 14.4 Providing efficient file management features · 14.4.1 Returning file data only when necessary · 14.4.2 Enabling partial downloads and uploads · 14.4.3 Preventing unnecessary uploads · 14.5 Delegating file downloads and uploads · 14.5.1 Downloading files from another system · 14.5.2 Uploading files to another system · 14.6 Notifying consumers about provider-sourced events with a webhook · 14.6.1 What is a webhook, and why should we consider using one? · 14.6.2 Webhooks should be optional · 14.6.3 Designing a webhook operation · 14.6.4 Using a standard event format · 14.6.5 Choosing event data granularity · 14.6.6 Designing a secure webhook · 14.6.7 Defining the expected webhook behavior · 14.6.8 Dealing with webhook failures · 14.6.9 Describing a webhook with OpenAPI · 14.7 Handling long operations · 14.7.1 Starting a long operation and monitoring its status with polling · 14.7.2 Using a callback API to avoid polling · 14.7.3 Describing a callback with OpenAPI · 14.7.4 Choosing an execution mode with the Prefer header · 14.8 Considering other API types · 14.8.1 Introducing REST API alternatives · 14.8.2 When to select an API type · 14.9 Summary · 14.10 Exercises · 14.11 Exercise 14.1 · 14.12 Exercise 14.2 · 14.13 Exercise 14.3

What you learn in chapter 14 →

Chapter 15: Modifying an API

15.1 An overview of API modification concerns · 15.1.1 What can happen when modifying an API? · 15.1.2 Uncovering API design modification concerns · 15.1.3 How to design API modifications · 15.2 Identifying breaking changes and ensuring backward compatibility · 15.2.1 Modifying output data · 15.2.2 Modifying input data · 15.2.3 Modifying resource paths · 15.2.4 Modifying operations or their HTTP methods · 15.2.5 Modifying HTTP statuses · 15.2.6 Modifying operation flows · 15.2.7 Being aware of the invisible contract · 15.2.8 Preventing unintended modifications · 15.3 Identifying security-breaking changes and preventing breaches · 15.4 Assigning a version to an API · 15.4.1 Differentiating interface and implementation versioning · 15.4.2 Choosing an API version identifier · 15.4.3 How the API version can be represented in a request · 15.4.4 Choosing how to represent the API version in a request · 15.4.5 When to choose an API version scheme and representation · 15.4.6 Avoiding sub-API-level versioning · 15.5 Carefully breaking and versioning an API · 15.5.1 Listing consumers and their types · 15.5.2 Checking whether consumers use what we break · 15.5.3 Determining whether it’s possible to expose multiple API versions · 15.5.4 Complying with the API versioning policy · 15.5.5 Balancing effects and benefits of breaking changes · 15.5.6 Accumulating trade-offs or breaking regularly · 15.6 Creating extensible API designs · 15.6.1 Designing a user-friendly, interoperable REST API that does the job · 15.6.2 Learning from past decisions · 15.6.3 Using extensible design patterns · 15.6.4 Providing deprecation runtime information · 15.7 Describing the design modifications with OpenAPI · 15.7.1 Indicating the API version · 15.7.2 Deprecating elements · 15.7.3 Adding a changelog · 15.8 Summary · 15.9 Exercises · 15.10 Exercise 15.1 · 15.11 Exercise 15.2 · 15.12 Exercise 15.3 · 15.13 Exercise 15.4 · 15.14 Exercise 15.5

What you learn in chapter 15 →

Chapter 16: Facilitating API design decision-making

16.1 Making design decisions confidently and consistently · 16.1.1 Ensuring that it’s the right time to make a decision · 16.1.2 Evaluating the scope of the decision · 16.1.3 Deciding based on trusted past decisions · 16.1.4 Deciding based on trusted external sources · 16.1.5 Backing decisions with reasoning and sourced information · 16.1.6 Explaining out loud · 16.2 Researching solutions to API design questions · 16.2.1 Where to research solutions to design questions · 16.2.2 Searching and considering · 16.2.3 Using an architectural decision record format · 16.3 What are API design guidelines? · 16.3.1 How design guidelines can help us · 16.3.2 How API design guidelines relate to API governance · 16.3.3 When do we need design guidelines? · 16.4 What to put in user-friendly API design guidelines · 16.4.1 Listing principles and rules · 16.4.2 Providing actionable recipes · 16.4.3 Providing ready-to-use artifacts and tools · 16.4.4 Helping with the API design process · 16.4.5 Adding implementation or architecture considerations · 16.5 How to build API design guidelines · 16.5.1 Starting with basic API design guidelines · 16.5.2 Considering existing APIs · 16.5.3 Expanding the guidelines when new questions arise · 16.5.4 Ensuring that each rule brings value · 16.5.5 Carefully modifying API design guidelines · 16.6 Summary · 16.7 Exercises · 16.8 Exercise 16.1 · 16.9 Exercise 16.2 · 16.10 Exercise 16.3 · 16.11 Exercise 16.4 · 16.12 Exercise 16.5

What you learn in chapter 16 →

Chapter 17: Optimizing an OpenAPI document

17.1 An overview of OpenAPI document optimization · 17.2 Defining consistent data models · 17.2.1 Reusing schemas · 17.2.2 Defining subschemas · 17.2.3 Targeting part of a schema with a deep reference · 17.2.4 Overriding descriptions when using a $ref · 17.2.5 Creating unique read-and-write models · 17.2.6 Defining a complete schema from its summary · 17.2.7 Considering schema optimizations · 17.3 Defining consistent parameters · 17.3.1 Using path-level parameters · 17.3.2 Reusing parameters · 17.3.3 Defining reusable groups of query parameters · 17.4 Defining consistent request bodies · 17.5 Defining consistent responses · 17.5.1 Reusing response headers · 17.5.2 Reusing responses · 17.6 Ensuring cross-API consistency with external shared components · 17.6.1 Defining a library of reusable components · 17.6.2 Using a shared component in an API · 17.6.3 Ensure that library files are editable independently · 17.7 Enhancing API design guidelines · 17.8 Summary · 17.9 Exercises · 17.10 Exercise 17.1 · 17.11 Exercise 17.2 · 17.12 Exercise 17.3 · 17.13 Exercise 17.4

What you learn in chapter 17 →

Chapter 18: Automating API design guidelines

18.1 What API linting is and how it can help us · 18.1.1 Detecting API design and OpenAPI authoring problems · 18.1.2 Applying guidelines seamlessly and concentrating on user needs · 18.2 Using an API linter to automate API design guidelines · 18.2.1 Developing linting rules to automate guidelines · 18.2.2 Using our automated guidelines while designing APIs · 18.2.3 Choosing an API linter · 18.3 Introducing Spectral · 18.3.1 Linting an OpenAPI document with Spectral CLI · 18.3.2 How Spectral lints an OpenAPI document · 18.3.3 Editing Spectral rulesets · 18.4 Deciding what API linting rules verify · 18.4.1 Using our guidelines to create only needed rules · 18.4.2 Finding small problems to solve · 18.4.3 Simplifying rules with shared OpenAPI components · 18.4.4 Ensuring appropriate granularity with a concise name and description · 18.5 Targeting elements to check in the OpenAPI documents · 18.5.1 Starting rule development by targeting the proper elements · 18.5.2 Targeting any element in the OpenAPI document · 18.5.3 Dealing with references to local or shared components · 18.5.4 Creating a library to target typical elements · 18.6 Checking element values · 18.6.1 Performing basic checks on values and keys · 18.6.2 Ensuring that an element is defined · 18.6.3 Ensuring that an element is not defined · 18.6.4 Checking references · 18.6.5 Checking partial JSON schemas · 18.6.6 Performing cross-element checks · 18.7 Returning helpful feedback when problems are detected · 18.7.1 Stating the importance or nature of a problem with a severity · 18.7.2 Returning problem-solving message · 18.7.3 Splitting rules due to severity or message concerns · 18.8 Organizing rules · 18.9 Using our automated guidelines when designing APIs · 18.9.1 Importing and tweaking the guidelines ruleset · 18.9.2 Ignoring certain problems · 18.10 Summary · 18.11 Exercises · 18.12 Exercise 18.1 · 18.13 Exercise 18.2 · 18.14 Exercise 18.3 · 18.15 Exercise 18.4 · 18.16 Exercise 18.5

What you learn in chapter 18 →

Chapter 19: Enriching API design artifacts

19.1 Crafting an API design reference kit · 19.1.1 What an API design reference kit can contain · 19.1.2 Using the kit to design the API · 19.1.3 Using the kit to develop the API · 19.1.4 Using the kit to test the API · 19.1.5 Using the kit to deploy the API · 19.1.6 Using the kit to provide and consume the API · 19.1.7 What we already have and what we may want to add · 19.2 Providing an overview of the API design with OpenAPI · 19.2.1 Adding links to other artifacts and describing the API · 19.2.2 Organizing operations around concepts and use cases · 19.2.3 Describing use cases · 19.3 Enhancing the precision of data models with JSON Schema · 19.3.1 Describing a number or element size range · 19.3.2 Describing a value with pattern, enum, and default · 19.4 Providing examples to illustrate data and operations · 19.4.1 Adding property examples with JSON Schema · 19.4.2 Adding examples of parameters, request and response bodies, and headers with OpenAPI · 19.4.3 Authoring accurate and realistic examples · 19.4.4 Sharing OpenAPI examples across operations · 19.4.5 Connecting examples to each other · 19.5 Enhancing and adapting artifacts for implementers · 19.5.1 Embedding implementation notes in artifacts · 19.5.2 Enhancing or adapting OpenAPI for code generation · 19.6 Considering API mocking or prototyping during API design · 19.6.1 Creating a basic mock with OpenAPI · 19.6.2 Favoring an early prototype over a complex mock during design · 19.7 Considering creating functional API tests during API design · 19.7.1 Clarifying logic · 19.7.2 Smoothing collaboration · 19.7.3 Designing standard APIs · 19.8 Summary · 19.9 Exercises · 19.10 Exercise 19.1 · 19.11 Exercise 19.2

What you learn in chapter 19 →

Concepts explained in this book

These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.