/.well-known/openid-configuration endpoint 277
$ref keyword, JSON Schema/OpenAPI 93 – 94
ACU (Aurora Capacity Units) 364
adapters, hexagonal architecture 145
additionalProperties, JSON schema/OpenAPI 115 – 116
add_middleware() method, FastAPI framework 290, 292
AKS (Azure’s Kubernetes Service) 343
ALB (Application Load Balancer), AWS
run_migrations_online() function 296
running migrations with 155, 339
allOf keyword, JSON Schema/OpenAPI 104
restricting user access to their own resources 297 – 300
updating database to link users and orders 294 – 297
APIIntegrationError exception, orders service 169
API layer, integrating with service layer 177 – 181
APISpec object, apispec library 142
API testing and validation 302 – 330
designing testing strategy 329 – 330
property-based testing 315 – 322
traditional approach to testing 316 – 317
REST API testing with Dredd 304 – 315
customizing test suite with hooks 307 – 315
running default test suite 305 – 307
REST API testing with Schemathesis 322 – 327
running default test suite 322 – 323
using - -stateful=links 323 – 327
implementing with marshmallow 129 – 130
implementing with pydantic 30 – 34
apiVersion property, Kubernetes manifest 356
arguments() decorator, flask-smorest 130, 134
building resolvers for custom scalars 258 – 262
creating entry point for GraphQL server 242 – 243
handling query parameters 252 – 255
implementing field resolvers 262 – 265
implementing mutation resolvers 256 – 258
implementing query resolvers 243 – 246
implementing resolvers for custom scalars 258 – 262
implementing type resolvers 246 – 252
array type, JSON Schema/OpenAPI 92, 99
ASGI (asynchronous server gateway interface) 24
asynchronous server gateway interface (ASGI) 24
aud reserved claim, JWT 281 – 282
Aurora Capacity Units (ACU) 364
authorization and authentication 269 – 301
adding authorization to server 287 – 293
creating authorization middleware 289 – 292
creating authorization modules 287 – 289
authorizing requests in Swagger UI 400 – 402
authorizing resource access 293 – 300
restricting user access to their own resources 297 – 300
updating database to link users and orders 294 – 297
client credentials flow 399 – 400
using identity as service provider 392 – 397
Authorization server, OAuth 272
AuthorizeRequestMiddleware class, orders API 289
creating serverless databases 361 – 364
running database migrations and connecting service to database 367 – 370
aws ecr get-login-password command 341
AWS KMS (Key Managed Service) 364
AWS Load Balancer Controller, installing 353
aws rds create-db-cluster command 365
azp reserved claim, JWT, OIDC 282
BaseConfig class, flask-smorest 124
BaseHTTPMiddleware class, FastAPI/Starlette 289
bearerAuth security scheme, OpenAPI 304, 400 – 401
Blueprint class (flask-smorest) 125
boolean type, JSON Schema/OpenAPI 92
build context, Docker Compose 338
Building Microservices (Newman) 8
business layer, implementing 162 – 172
cacheability principle (REST) 65 – 66
calendar versioning (CalVer) 388
CIDR (Classless Inter-Domain Routing) 349
class-based views 122 – 123, 125 – 127
client credentials flow, OAuth 275, 399 – 400
client-server architecture principle (REST) 64
CLIs (command-line interfaces) 8
ClusterIP (Kubernetes service) 357 – 358
code-on-demand principle (REST) 66
analyzing business structure of 49 – 50
applying strategic analysis to 53 – 56
decomposing microservices 50 – 52
implementing endpoints 125 – 129
implementing in-memory list of schedules 140 – 142
implementing payload validation models 129 – 132
initializing web application 123 – 125
overriding dynamically generated specification 142 – 143
validating data before serializing response 136 – 139
validating URL query parameters 133 – 136
high-level architecture 22 – 23
implementing API endpoints 23 – 28
implementing data validation models with pydantic 30 – 34
implementing in-memory list of orders 41 – 43
marshalling and validating response payloads with pydantic 38 – 41
overriding FastAPI’s dynamically generated specification 118 – 120
URL query parameters for 112 – 115
validating payloads with unknown fields 115 – 118
validating request payloads with pydantic 34 – 38
products API (GraphQL) 241 – 265
combining types through unions and interfaces 200 – 202
constraining property values with enumerations 202 – 203
creating entry point for GraphQL server 242 – 243
handling query parameters 252 – 255
implementing field resolvers 262 – 265
implementing mutation resolvers 256 – 258
implementing query resolvers 243 – 246
implementing resolvers for custom scalars 258 – 262
implementing type resolvers 246 – 252
laying out project structure 241 – 242
collections resources, REST 62
commit() method (SQLAlchemy) 175 – 176
configure() method (Alembic) 296
container registry, publishing Docker builds to 340 – 341
core domain, domain-driven design 53
Core Kubernetes (Vyas and Love) 345
CORS (cross-origin resource sharing)
adding CORS middleware 292 – 293
CORS (Cross-Origin Resource Sharing) middleware 292 – 293
create_engine() function (SQLAlchemy) 175
cryptography library 271, 283, 286, 288, 395 – 397
DaemonSet, Kubernetes workload 345
database-data volume, Docker Compose 338
database models, implementing 149 – 155
database-per-service principle 46 – 48
database subnet group, AWS 361
Datetime custom scalar (GraphQL) 194, 258 – 260
datetime.fromisoformat() method 260
db-credentials secret 366, 369
DDD (domain-driven design) 52 – 53, 166
declarative_base() function (SQLAlchemy) 153
default namespace, Kubernetes 347
dependency injection pattern 165
dependency inversion pattern 146
Deployment workload, Kubernetes 345
deployment objects, creating 354 – 356
Deprecation HTTP header 389 – 390
directed connections (GraphQL) 197
discoverability (HATEOAS, REST) 72 – 73
dispatch() method (Starlette middleware) 289
distributed transaction tracing 13 – 14
publishing Docker builds to container registry 340 – 341
running applications with Docker Compose 338 – 340
Docker Compose, running applications with 338 – 340
Docker in Action (Kuenzli) 338
documentation-driven development 15 – 17
domain-driven design (DDD) 52 – 53, 166
Domain-Driven Design (Evans) 52
REST API testing with 304 – 315
customizing test suite with hooks 307 – 315
installing and running default test suite 305 – 307
using hooks to make Dredd use custom URLs 311
creating resources before test 312
generating error responses 313 – 314
saving ID of created resource 309 – 311
dredd_hooks.after() decorator 310
dredd_hooks.before() decorator 310
ECR (Elastic Container Registry) 340 – 341
EKS (Elastic Kubernetes Service), AWS 346 – 349
Elastic Container Registry (ECR), AWS 340 – 341
encode() function, PyJWT 282 – 283
__enter__() method, context manager class 174 – 176
envFrom property, Kubernetes manifest 369
environment keyword, Docker Compose 338
Error generic model, OpenAPI 105, 107
__exit__() method, context manager class 174 – 175
exp reserved claim, JWT 281 – 283
ExternalName, Kubernates service 358
implementing API endpoints 23 – 28
implementing data validation models with pydantic 30 – 34
marshalling and validating response payloads with pydantic 38 – 41
overriding dynamically generated specification 118 – 120
validating payloads with unknown fields 115 – 118
validating request payloads with pydantic 34 – 38
validating URL query parameters 112 – 115
field() decorator (Ariadne) 240, 256
field resolvers, implementing with Ariadne 262 – 265
filter_by() method (SQLAlchemy) 160
first() method (SQLAlchemy) 160
fixed_dictionaries(), hypothesis 319 – 320
implementing endpoints 125 – 129
implementing payload validation models 129 – 132
initializing web application 123 – 125
overriding dynamically generated specification 142 – 143
validating response payload 136 – 139
validating URL query parameters 133 – 136
Float scalar (GraphQL) 192, 194
GET requests, response payloads for (REST) 86
given() decorator, hypothesis 321
grant_type property, OAuth 399
with edge properties 196 – 198
designing and documenting queries 203 – 206
SDL (Schema Definition Language) 15, 186
unions and interfaces 200 – 202
GraphQL API implementation 233 – 266
building resolvers for custom scalars 258 – 262
creating entry point for GraphQL server 242 – 243
handling query parameters 252 – 255
implementing field resolvers 262 – 265
implementing mutation resolvers 256 – 258
implementing query resolvers 243 – 246
implementing type resolvers 246 – 252
laying out project structure 241 – 242
GraphQL API querying 210 – 232
calling GraphQL API with Python code 230 – 231
running parametrized 226 – 229
navigating the API graph 219 – 221
running parametrized 226 – 229
running with input parameters 219
understanding errors 215 – 217
GraphQL class (Ariadne framework) 237, 242 – 243
graphql-faker (GraphQL mocking tool) 211 – 213
GraphQL type resolvers (Ariadne library) 246 – 252
HATEOAS (Hypermedia as Engine of Application State) 67 – 70
hexagonal architecture 145 – 148
HTTP (Hypertext Transfer Protocol) 9
HTTP-native APIs with REST 382
response payloads for GET requests 86
response payloads for POST requests 84
response payloads for PUT and PATCH requests 85
defined 77 – 78
reporting client errors with 78 – 81
reporting errors in server with 82 – 83
Hypermedia as Engine of Application State (HATEOAS) 67 – 70
hypothesis library 315 – 316, 318, 322 – 323
- -hypothesis-database flag 323
- -hypothesis-deadline option 328
- -hypothesis-suppress-health-check flag 327
property-based testing with 318 – 319
ID (Unique Identifiers) scalar, GraphQL 192 – 194
info parameter (Ariadne resolvers) 239 – 240, 256
infrastructure overhead 14 – 15
ingress controller, Kubernetes 351
ingress objects, Kubernetes 359 – 361
input parameters (GraphQL) 225, 252, 256
Integer field class, marshmallow library 129
integers() strategy, hypothesis 318
InterfaceType (Ariadne framework) 240
interface type (GraphQL) 200 – 202
inversion of control container 147, 165
inversion of control principle 165
JSON (JavaScript Object Notation) 377, 380
jwt_generator.py script 284, 292
JWTs (JSON Web Tokens) 108, 278 – 286, 391
kind property, Kubernetes manifest 357
implementing API endpoints 125 – 129
implementing in-memory list of schedules 140 – 142
implementing payload validation models with marshmallow 129 – 132
initializing web application for API 123 – 125
overriding flask-smorest dynamically generated API specification 142 – 143
validating response payloads 136 – 139
validating URL query parameters 133 – 136
creating clusters with EKS 346 – 349
deploying load balancers 351 – 353
deploying microservices to cluster 353 – 361
creating deployment object 354 – 356
creating service object 357 – 358
exposing services with ingress objects 359 – 361
IAM roles for service accounts 350 – 351
managing secrets in Kubernetes 364 – 367
deploying microservices to 353 – 361
Kubernetes in Action (Lukša) 372
kube-system namespace 347, 352 – 353
lists() strategy, hypothesis 320
LoadBalancer, Kubernetes service 358
machine_to_machine_test.py script 400 – 401
make_executable_schema() function (Ariadne framework) 237, 240, 243, 245, 251 – 252, 257, 261
marshmallow, implementing payload validation models 129 – 132
metadata property, Kubernetes manifest 357
MethodView class, Flask 125 – 127
microservice API deployment 342 – 375
creating clusters with EKS 346 – 349
deploying microservices to cluster 353 – 361
creating deployment object 354 – 356
creating service object 357 – 358
exposing services with ingress objects 359 – 361
authorization and authentication 269 – 301
basic implementation of REST API with FastAPI 20 – 44
implementing data validation models 30 – 34
implementing endpoints 23 – 28
marshalling and validating response payloads 38 – 41
validating request payloads 34 – 38
building REST APIs with Python 110 – 143
challenges of microservices architecture 11 – 15
distributed transaction tracing 13 – 14
microservices integration tests 12
operational complexity and infrastructure overhead 14 – 15
service unavailability 12 – 13
documentation-driven development 15 – 17
REST API design principles 61 – 89
REST API documentation 90 – 109
service implementation patterns 144 – 181
testing and validation 302 – 330
web APIs 8 – 11
role of in microservices integration 9 – 11
database-per-service principle 46 – 48
single responsibility principle 49
by business capability 49 – 52, 57 – 58
microservices integration tests 12
Microservices Patterns (Richardson) 11
Microservices Security in Action (Siriwardena and Dias) 333
running with Alembic 151, 155, 339
model composition, JSON Schema/OpenAPI 103 – 104
MTV (model-template-view) pattern 17
mutation resolvers, implementing, GraphQL/Ariadne framework 256 – 258
implementing mutation resolvers 256 – 258
running parametrized 226 – 229
MutationType class (Ariadne framework) 256 – 257
Networking and Kubernetes (Strong and Lancey) 348
NodePort service, Kubernetes 358
null type, JSON Schema/OpenAPI 92
number type, JSON Schema/OpenAPI 92
OAS (OpenAPI Specification) 21, 382
OAuth2 (Open Authorization) 108
OAuth (Open Authorization) 271 – 275, 391
object relational mapper (ORM) 150 – 151
object type, JSON Schema/OpenAPI 92
obj parameter, Ariadne resolvers 239 – 240, 256
OIDC (OpenID Connect) 18, 271, 276 – 278, 350, 391
one-to-many connection, GraphQL 197
one-to-one connection, GraphQL 197
OpenAPI 21, 90 – 109, 382
refactoring schema definitions 100 – 102
servers property 96, 370 – 372
Open Authorization (OAuth) 108
OpenID Connect in Action (Siriwardena) 278
OpenID Connect (OIDC) 18, 271, 276 – 278, 350, 391
operational complexity 14 – 15
high-level architecture 22 – 23
implementing API endpoints 23 – 28
implementing data validation models with pydantic 30 – 34
implementing in-memory list of orders 41 – 43
marshalling and validating response payloads with pydantic 38 – 41
overriding FastAPI dynamically generated specification 118 – 120
URL query parameters for 112 – 115
validating payloads with unknown fields 115 – 118
validating request payloads with pydantic 34 – 38
ORM (object relational mapper) 150 – 151
PATCH (HTTP method) 74, 85, 384
pickle serialization (Python) 380
PKCE (Proof of Key for Code Exchange) flow, OAuth 273 – 275, 397 – 398
ports, hexagonal architecture 145 – 146
POST requests, response payloads for 84
prism (API mocking tool) 168 – 169
ProductInterface type, Products API 201 – 202, 218, 220 – 221, 225, 234, 247
products API (GraphQL) 241 – 265
building resolvers for custom scalars 258 – 262
combining types through unions and interfaces 200 – 202
constraining property values with enumerations 202 – 203
creating entry point for GraphQL server 242 – 243
handling query parameters 252 – 255
implementing field resolvers 262 – 265
implementing mutation resolvers 256 – 258
implementing query resolvers 243 – 246
implementing type resolvers 246 – 252
laying out project structure 241 – 242
Product type 201 – 202, 207, 217, 225, 234, 239, 247, 250 – 251, 258
Product type 201 – 202, 207, 217, 225, 234, 239, 243, 247, 250 – 251, 258
properties, JSON Schema/OpenAPI 92
property() decorator, Python built-in 166
property-based testing 315 – 322
using hypothesis to test endpoints 319 – 322
vs. traditional approach to testing 316 – 317
Protobuf (Protocol Buffers) 380
implementing data validation models 30 – 34
marshalling and validating response payloads 38 – 41
validating payloads with unknown fields 115 – 118
validating request payloads 34 – 38
PYTHONPATH environment variable 155
queries (GraphQL) 206, 214, 217
handling query parameters 252 – 255
implementing query resolvers 243 – 246
running parametrized 226 – 229
running with input parameters 219
understanding errors 215 – 217
query aliasing, GraphQL 222 – 225
query resolvers, implementing (GraphQL) 243 – 246
QueryType class (Ariadne framework) 240, 245, 256
read-only properties (REST) 84
Real-World Cryptography (Wong) 280
relationship() function, SQLAlchemy 153
implementing validation models with marshmallow 129 – 132
validating with pydantic 34 – 38
reserved claims, OIDC, OAuth, and JWT 281
resolvers (GraphQL; Ariadne framework)
building resolvers for custom scalars 258 – 262
implementing field resolvers 262 – 265
implementing mutation resolvers 256 – 258
implementing query resolvers 243 – 246
implementing type resolvers 246 – 252
response() decorator, flask-smorest 130
implementing validation models with marshmallow 129 – 132
marshalling and validating with pydantic 38 – 41
REST API design principles 61 – 89
architectural constraints of REST applications 63 – 67
cacheability principle 65 – 66
client-server architecture principle 64
statelessness principle 64 – 65
uniform interface principle 67
HATEOAS 67 – 70
HTTP-native APIs with REST 382
defined 83 – 84
defined 77 – 78
reporting client errors in request 78 – 81
reporting errors in server 82 – 83
Richardson maturity model 70 – 73
structured resource URLs with HTTP methods 73 – 76
URL query parameter design 87 – 88
implementing with FastAPI 23 – 28
implementing with flask-smorest 125 – 129
testing with hypothesis 319 – 322
REST API implementation 110 – 143
implementing endpoints 125 – 129
implementing payload validation models 129 – 132
initializing web application 123 – 125
overriding dynamically generated specification 142 – 143
validating response payloads 136 – 139
validating URL query parameters 133 – 136
high-level architecture 22 – 23
implementing API endpoints 23 – 28
implementing data validation models with pydantic 30 – 34
marshalling and validating response payloads with pydantic 38 – 41
overriding FastAPI dynamically generated specification 118 – 120
URL query parameters for 112 – 115
validating payloads with unknown fields 115 – 118
validating request payloads with pydantic 34 – 38
customizing test suite with hooks 307 – 315
installing and running default test suite 305 – 307
running default test suite 322 – 323
using - -stateful=links 323 – 327
REST (Representational State Transfer) 61, 382
Richardson maturity model 70 – 73
rollback() method (SQLAlchemy) 174, 176
route() decorator, flask-smorest 125, 127
RPC (remote procedure call) 71, 377 – 386
run_migrations_online() function (Alembic) 296
ScalarType class (Ariadne framework) 260
building resolvers for custom scalars 258 – 262
designing object properties with 192 – 193
ScheduleOrderSchema schema, kitchen API 121, 129
running default test suite 322 – 323
using - -stateful=links 323 – 327
SDL (Schema Definition Language) 15, 186
securitySchemes, OpenAPI 107 – 109
serializer() decorator, ScalarType (Ariadne framework) 260
serverless databases 361 – 370
running database migrations and connecting service to database 367 – 370
server-side properties, REST APIs 84
servers section, OpenAPI 96, 119, 370 – 372
service, Kubernetes 354, 357 – 358
by business capability 49 – 52
analyzing business structure 49 – 50
decomposing microservices 50 – 52
applying strategic analysis 53 – 56
vs. by business capability 57 – 58
service implementation patterns 144 – 181
hexagonal architecture 145 – 148
implementing business layer 162 – 172
implementing database models 149 – 155
implementing unit of work pattern 172 – 177
integrating API layer and service layer 177 – 181
service layer, integrating with API layer 177 – 181
service-oriented architecture 7
service unavailability 12 – 13
sessionmaker() function (SQLAlchemy) 175
session object, UnitOfWork 176
Session object (SQLAlchemy) 161, 174
single responsibility principle (SRP) 46, 49
singleton resource, REST APIs 62
SOAP (Simple Object Access Protocol) 378 – 379
Software Telemetry (Riedesel) 14
solution space, domain-driven design 53
SPAs (single-page applications) 64, 274, 397
declarative_base() function 153
SQLite 150 – 151, 295 – 296
SRP (single responsibility principle) 46, 49
StatefulSet workload (Kubernetes) 345
statelessness principle (REST) 64 – 65
strategic design, domain-driven design 53
string data type, JSON Schema/OpenAPI 92
String field class, marshmallow 129
String scalar (GraphQL) 192 – 194
subdomain, domain-driven design 53
supportive subdomain, domain-driven design 53
authorizing requests 400 – 402
Testing Web APIs (Winteringham) 304
text() strategy, hypothesis 318
three-tier architecture 22 – 23
tolerant reader pattern 115 – 116
building resolvers for custom scalars 258 – 262
combining through unions and interfaces 200 – 202
scalars, creating custom 194 – 195
ubiquitous language, domain-driven design 53
unevaluatedProperties, JSON Schema/OpenAPI 114
uniform interface principle, REST APIs 67
unit of work pattern 172 – 177
Unprocessable Entity (409 HTTP status code) 79
URI (Uniform Resource Identifier) 67
for kitchen API (flask-smorest) 133 – 136
for orders API (FastAPI) 112 – 115
URLs (Uniform Resource Locators) 9
structured resource URLs with HTTP methods 73 – 76
UUID (universally unique identifier) 27, 102
uvicorn 24, 112, 235
validate() function, jsonschema 321
ValidationError exception, marshmallow 139
validator() decorator, Pydantic 37
value_parser() decorator (Ariadne) 260
VPC (Virtual Private Cloud), AWS 348
web APIs 8 – 11, 376 – 386
emergence of API standards 378 – 379
granular queries with GraphQL 382 – 386
HTTP-native APIs with REST 382
role of in microservices integration 9 – 11
3.142.43.216