Strategies, best practices, and patterns that will help you design resilient microservices architecture and streamline your API integrations.
In Microservice APIs, you'll discover:
• Service decomposition strategies for microservices
• Documentation-driven development for APIs
• Best practices for designing REST and GraphQL APIs
• Documenting REST APIs with the OpenAPI specification (formerly Swagger)
• Documenting GraphQL APIs using the Schema Definition Language
• Building microservices APIs with Flask, FastAPI, Ariadne, and other frameworks
• Service implementation patterns for loosely coupled services
• Property-based testing to validate your APIs, and using automated API testing frameworks like schemathesis and Dredd
• Adding authentication and authorization to your microservice APIs using OAuth and OpenID Connect (OIDC)
• Deploying and operating microservices in AWS with Docker and Kubernetes
Microservice APIs teaches you practical techniques for designing robust microservices with APIs that are easy to understand, consume, and maintain. You'll benefit from author José Haro Peralta's years of experience experimenting with microservices architecture, dodging pitfalls and learning from mistakes he's made. Inside you'll find strategies for delivering successful API integrations, implementing services with clear boundaries, managing cloud deployments, and handling microservices security. Written in a framework-agnostic manner, its universal principles can easily be applied to your favorite stack and toolset.
About the technology
Clean, clear APIs are essential to the success of microservice applications. Well-designed APIs enable reliable integrations between services and help simplify maintenance, scaling, and redesigns. This book teaches you the patterns, protocols, and strategies you need to design, build, and deploy effective REST and GraphQL microservices APIs.
About the book
Microservice APIs gathers proven techniques for creating and building easy-to-consume APIs for microservices applications. Rich with proven advice and Python-based examples, this practical book focuses on implementation over philosophy. You'll learn how to build robust microservice APIs, test and protect them, and deploy them to the cloud following principles and patterns that work in any language.
What's inside
• Service decomposition strategies for microservices
• Best practices for designing and building REST and GraphQL APIs
• Service implementation patterns for loosely coupled components
• API authorization with OAuth and OIDC
• Deployments with AWS and Kubernetes
About the reader
For developers familiar with the basics of web development. Examples are in Python.
About the author
José Haro Peralta is a consultant, author, and instructor. He's also the founder of microapis.io.
Author(s): José Haro Peralta
Edition: 1
Publisher: Manning Publications
Year: 2023
Language: English
Commentary: Publisher's PDF
Pages: 440
City: Shelter Island, NY
Tags: Security; Python; Web Applications; Microservices; Docker; GraphQL; Flask; API Design; Kubernetes; Software Architecture; Testing; Serverless Applications; REST API; AWS Aurora; OpenAPI; Authentication; FastAPI
Microservice APIs
brief contents
contents
preface
acknowledgments
about this book
Who should read this book?
How this book is organized: A roadmap
About the code
liveBook discussion forum
Other online resources
about the author
about the cover illustration
Part 1—Introducing Microservice APIs
1 What are microservice APIs?
1.1 What are microservices?
1.1.1 Defining microservices
1.1.2 Microservices vs. monoliths
1.1.3 Microservices today and how we got here
1.2 What are web APIs?
1.2.1 What is an API?
1.2.2 What is a web API?
1.2.3 How do APIs help us drive microservices integrations?
1.3 Challenges of microservices architecture
1.3.1 Effective service decomposition
1.3.2 Microservices integration tests
1.3.3 Handling service unavailability
1.3.4 Tracing distributed transactions
1.3.5 Increased operational complexity and infrastructure overhead
1.4 Introducing documentation-driven development
1.5 Introducing the CoffeeMesh application
1.6 Who this book is for and what you will learn
Summary
2 A basic API implementation
2.1 Introducing the orders API specification
2.2 High-level architecture of the orders application
2.3 Implementing the API endpoints
2.4 Implementing data validation models with pydantic
2.5 Validating request payloads with pydantic
2.6 Marshalling and validating response payloads with pydantic
2.7 Adding an in-memory list of orders to the API
Summary
3 Designing microservices
3.1 Introducing CoffeeMesh
3.2 Microservices design principles
3.2.1 Database-per-service principle
3.2.2 Loose coupling principle
3.2.3 Single Responsibility Principle
3.3 Service decomposition by business capability
3.3.1 Analyzing the business structure of CoffeeMesh
3.3.2 Decomposing microservices by business capabilities
3.4 Service decomposition by subdomains
3.4.1 What is domain-driven design?
3.4.2 Applying strategic analysis to CoffeeMesh
3.5 Decomposition by business capability vs. decomposition by subdomain
Summary
Part 2—Designing and building REST APIs
4 Principles of REST API design
4.1 What is REST?
4.2 Architectural constraints of REST applications
4.2.1 Separation of concerns: The client-server architecture principle
4.2.2 Make it scalable: The statelessness principle
4.2.3 Optimize for performance: The cacheability principle
4.2.4 Make it simple for the client: The layered system principle
4.2.5 Extendable interfaces: The code-on-demand principle
4.2.6 Keep it consistent: The uniform interface principle
4.3 Hypermedia as the engine of application state
4.4 Analyzing the maturity of an API with the Richardson maturity model
4.4.1 Level 0: Web APIs à la RPC
4.4.2 Level 1: Introducing the concept of resource
4.4.3 Level 2: Using HTTP methods and status codes
4.4.4 Level 3: API discoverability
4.5 Structured resource URLs with HTTP methods
4.6 Using HTTP status codes to create expressive HTTP responses
4.6.1 What are HTTP status codes?
4.6.2 Using HTTP status codes to report client errors in the request
4.6.3 Using HTTP status codes to report errors in the server
4.7 Designing API payloads
4.7.1 What are HTTP payloads, and when do we use them?
4.7.2 HTTP payload design patterns
4.8 Designing URL query parameters
Summary
5 Documenting REST APIs with OpenAPI
5.1 Using JSON Schema to model data
5.2 Anatomy of an OpenAPI specification
5.3 Documenting the API endpoints
5.4 Documenting URL query parameters
5.5 Documenting request payloads
5.6 Refactoring schema definitions to avoid repetition
5.7 Documenting API responses
5.8 Creating generic responses
5.9 Defining the authentication scheme of the API
Summary
6 Building REST APIs with Python
6.1 Overview of the orders API
6.2 URL query parameters for the orders API
6.3 Validating payloads with unknown fields
6.4 Overriding FastAPI’s dynamically generated specification
6.5 Overview of the kitchen API
6.6 Introducing flask-smorest
6.7 Initializing the web application for the API
6.8 Implementing the API endpoints
6.9 Implementing payload validation models with marshmallow
6.10 Validating URL query parameters
6.11 Validating data before serializing the response
6.12 Implementing an in-memory list of schedules
6.13 Overriding flask-smorest’s dynamically generated API specification
Summary
7 Service implementation patterns for microservices
7.1 Hexagonal architectures for microservices
7.2 Setting up the environment and the project structure
7.3 Implementing the database models
7.4 Implementing the repository pattern for data access
7.4.1 The case for the repository pattern: What is it, and why is it useful?
7.4.2 Implementing the repository pattern
7.5 Implementing the business layer
7.6 Implementing the unit of work pattern
7.7 Integrating the API layer and the service layer
Summary
Part 3—Designing and building GraphQL APIs
8 Designing GraphQL APIs
8.1 Introducing GraphQL
8.2 Introducing the products API
8.3 Introducing GraphQL’s type system
8.3.1 Creating property definitions with scalars
8.3.2 Modeling resources with object types
8.3.3 Creating custom scalars
8.4 Representing collections of items with lists
8.5 Think graphs: Building meaningful connections between object types
8.5.1 Connecting types through edge properties
8.5.2 Creating connections with through types
8.6 Combining different types through unions and interfaces
8.7 Constraining property values with enumerations
8.8 Defining queries to serve data from the API
8.9 Altering the state of the server with mutations
Summary
9 Consuming GraphQL APIs
9.1 Running a GraphQL mock server
9.2 Introducing GraphQL queries
9.2.1 Running simple queries
9.2.2 Running queries with parameters
9.2.3 Understanding query errors
9.3 Using fragments in queries
9.4 Running queries with input parameters
9.5 Navigating the API graph
9.6 Running multiple queries and query aliasing
9.6.1 Running multiple queries in the same request
9.6.2 Aliasing our queries
9.7 Running GraphQL mutations
9.8 Running parameterized queries and mutations
9.9 Demystifying GraphQL queries
9.10 Calling a GraphQL API with Python code
Summary
10 Building GraphQL APIs with Python
10.1 Analyzing the API requirements
10.2 Introducing the tech stack
10.3 Introducing Ariadne
10.4 Implementing the products API
10.4.1 Laying out the project structure
10.4.2 Creating an entry point for the GraphQL server
10.4.3 Implementing query resolvers
10.4.4 Implementing type resolvers
10.4.5 Handling query parameters
10.4.6 Implementing mutation resolvers
10.4.7 Building resolvers for custom scalar types
10.4.8 Implementing field resolvers
Summary
Part 4—Securing, testing, and deploying microservice APIs
11 API authorization and authentication
11.1 Setting up the environment for this chapter
11.2 Understanding authentication and authorization protocols
11.2.1 Understanding Open Authorization
11.2.2 Understanding OpenID Connect
11.3 Working with JSON Web Tokens
11.3.1 Understanding the JWT header
11.3.2 Understanding JWT claims
11.3.3 Producing JWTs
11.3.4 Inspecting JWTs
11.3.5 Validating JWTs
11.4 Adding authorization to the API server
11.4.1 Creating an authorization module
11.4.2 Creating an authorization middleware
11.4.3 Adding CORS middleware
11.5 Authorizing resource access
11.5.1 Updating the database to link users and orders
11.5.2 Restricting user access to their own resources
Summary
12 Testing and validating APIs
12.1 Setting up the environment for API testing
12.2 Testing REST APIs with Dredd
12.2.1 What is Dredd?
12.2.2 Installing and running Dredd’s default test suite
12.2.3 Customizing Dredd’s test suite with hooks
12.2.4 Using Dredd in your API testing strategy
12.3 Introduction to property-based testing
12.3.1 What is property-based testing?
12.3.2 The traditional approach to API testing
12.3.3 Property-based testing with Hypothesis
12.3.4 Using Hypothesis to test a REST API endpoint
12.4 Testing REST APIs with Schemathesis
12.4.1 Running Schemathesis’s default test suite
12.4.2 Using links to enhance Schemathesis’ test suite
12.5 Testing GraphQL APIs
12.5.1 Testing GraphQL APIs with Schemathesis
12.6 Designing your API testing strategy
Summary
13 Dockerizing microservice APIs
13.1 Setting up the environment for this chapter
13.2 Dockerizing a microservice
13.3 Running applications with Docker Compose
13.4 Publishing Docker builds to a container registry
Summary
14 Deploying microservice APIs with Kubernetes
14.1 Setting up the environment for this chapter
14.2 How Kubernetes works: The “CliffsNotes” version
14.3 Creating a Kubernetes cluster with EKS
14.4 Using IAM roles for Kubernetes service accounts
14.5 Deploying a Kubernetes load balancer
14.6 Deploying microservices to the Kubernetes cluster
14.6.1 Creating a deployment object
14.6.2 Creating a service object
14.6.3 Exposing services with ingress objects
14.7 Setting up a serverless database with AWS Aurora
14.7.1 Creating an Aurora Serverless database
14.7.2 Managing secrets in Kubernetes
14.7.3 Running the database migrations and connecting our service to the database
14.8 Updating the OpenAPI specification with the ALB’s hostname
14.9 Deleting the Kubernetes cluster
Summary
appendix A—Types of web APIs and protocols
A.1 The dawn of APIs: RPC, XML-RPC, and JSON-RPC
A.2 SOAP and the emergence of API standards
A.3 RPC strikes again: Fast exchanges over gRPC
A.4 HTTP-native APIs with REST
A.5 Granular queries with GraphQL
appendix B—Managing an API’s life cycle
B.1 Versioning strategies for evolving APIs
B.2 Managing the life cycle of your APIs
appendix C—API authorization using an identity provider
C.1 Using an identity as a service provider
C.2 Using the PKCE authorization flow
C.3 Using the client credentials flow
C.4 Authorizing requests in the Swagger UI
index
Symbols
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y