Software Architecture Patterns for Serverless Systems - Second Edition

Book description

Delve into the second edition to master serverless proficiency and explore new chapters on security techniques, multi-regional deployment, and optimizing observability.

Key Features

  • Gain insights from a seasoned CTO on best practices for designing enterprise-grade software systems
  • Deepen your understanding of system reliability, maintainability, observability, and scalability with real-world examples
  • Elevate your skills with software design patterns and architectural concepts, including securing in-depth and running in multiple regions

Book Description

Organizations undergoing digital transformation rely on IT professionals to design systems to keep up with the rate of change while maintaining stability. With this edition, enriched with more real-world examples, you’ll be perfectly equipped to architect the future for unparalleled innovation.

This book guides through the architectural patterns that power enterprise-grade software systems while exploring key architectural elements (such as events-driven microservices, and micro frontends) and learning how to implement anti-fragile systems.

First, you'll divide up a system and define boundaries so that your teams can work autonomously and accelerate innovation. You'll cover the low-level event and data patterns that support the entire architecture while getting up and running with the different autonomous service design patterns.

This edition is tailored with several new topics on security, observability, and multi-regional deployment. It focuses on best practices for security, reliability, testability, observability, and performance. You'll be exploring the methodologies of continuous experimentation, deployment, and delivery before delving into some final thoughts on how to start making progress.

By the end of this book, you'll be able to architect your own event-driven, serverless systems that are ready to adapt and change.

What you will learn

  • Explore architectural patterns to create anti-fragile systems
  • Focus on DevSecOps practices that empower self-sufficient, full-stack teams
  • Apply microservices principles to the frontend
  • Discover how SOLID principles apply to software and database architecture
  • Gain practical skills in deploying, securing, and optimizing serverless architectures
  • Deploy a multi-regional system and explore the strangler pattern for migrating legacy systems
  • Master techniques for collecting and utilizing metrics, including RUM, Synthetics, and Anomaly detection

Who this book is for

This book is for software architects who want to learn more about different software design patterns and best practices. This isn't a beginner's manual – you'll need an intermediate level of programming proficiency and software design experience to get started.You'll get the most out of this software design book if you already know the basics of the cloud, but it isn't a prerequisite.

Table of contents

  1. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
  2. Architecting for Innovation
    1. Continuously delivering business value
      1. By the skin of our teeth
      2. Through high-velocity teamwork
    2. Dissecting lead time
      1. Risk mitigation
      2. Decision making
      3. Software development life cycle methodology
      4. Hardware provisioning
      5. Deployments
      6. Software structure
      7. Testing and confidence
      8. Dependencies and inter-team communication
    3. Dissecting integration styles
      1. Batch integration
      2. Spaghetti integration
      3. Real-time integration
      4. Enterprise application integration
      5. Shared database
      6. Service-oriented architecture
      7. Microservices
    4. Enabling autonomous teams with autonomous services
      1. Autonomous services – creating bulkheads
        1. Asynchronous inter-service communication
        2. Fortified boundaries
      2. Event-first – valuing facts
        1. Inversion of responsibility
        2. Events as first-class citizens
        3. Idempotence and ordered tolerance
      3. Serverless-first – creating knowledge
        1. Self-service
        2. Disposable architecture
      4. Data life cycle – fighting data gravity
      5. Micro frontends – equalizing tiers
      6. Observability – optimizing everything
      7. Organic evolution – embracing change
    5. Summary
  3. Defining Boundaries and Letting Go
    1. Learning the hard way
    2. Building on proven concepts
      1. Domain-driven design
        1. Bounded context
        2. Domain aggregate
        3. Domain event
      2. SOLID principles
        1. Single Responsibility Principle
        2. Open-Closed Principle
        3. Liskov Substitution Principle
        4. Interface Segregation Principle
        5. Dependency Inversion Principle
      3. Hexagonal Architecture
        1. Function-level (nano)
        2. Service-level (micro)
        3. Subsystem-level (macro)
    3. Thinking about events first
      1. Start with event storming
      2. Focus on verbs instead of nouns
      3. Treat events as facts instead of ephemeral messages
      4. Turn APIs inside out by treating events as contracts
      5. Invert responsibility for invocation
      6. Connect services through an event hub
    4. Dividing a system into autonomous subsystems
      1. By actor
      2. By business unit
      3. By business capability
      4. By data life cycle
      5. By legacy system
    5. Creating subsystem bulkheads
      1. Separate cloud accounts
      2. External domain events
    6. Dissecting an autonomous subsystem
      1. Context diagram
      2. Micro frontend
      3. Event hub
      4. Autonomous service patterns
        1. Backend For Frontend
        2. External Service Gateways
        3. Control services
    7. Dissecting an autonomous service
      1. Repository
      2. CI/CD pipeline and GitOps
      3. Tests
      4. Stack
      5. Persistence
      6. Trilateral API
        1. Events
        2. API Gateway
      7. Functions
        1. Nano architecture
        2. Micro architecture
      8. Shared libraries
    8. Governing without impeding
      1. Providing automation and cross-cutting concerns
      2. Promoting a culture of robustness
      3. Harnessing the four key team metrics
    9. Summary
  4. Taming the Presentation Tier
    1. Presentation tier innovation – zigzagging through time
      1. Client-side versus server-side rendering
      2. Build-time versus runtime rendering
      3. Web versus mobile
    2. Breaking up the frontend monolith
      1. By subsystem
      2. By user activity
      3. By device type
      4. By version
    3. Dissecting micro frontends
      1. The main app
        1. The index file
        2. The importmap file
        3. Micro-app registration
      2. Micro-app
        1. The entry file
        2. Root component
      3. Micro-app activation
        1. Micro-app life cycle
        2. Route-based activation
        3. Manual activation
      4. Mount points
      5. Manifest deployer
      6. Inter-application communication
    4. Designing for offline-first
      1. Transparency
        1. Status indicators
        2. Outbox
        3. Inbox
      2. Local cache
        1. Caching code
        2. Caching data reads
        3. Caching data writes
      3. Live updates
        1. WebSocket
        2. Long polling
    5. Summary
  5. Trusting Facts and Eventual Consistency
    1. Living in an eventually consistent world
      1. Staging
        1. Cooperative
        2. Atomic
      2. Consistency
        1. Transparency
        2. Facts
        3. Chain reaction
      3. Concurrency and partitions
      4. Order tolerance and idempotence
      5. Parallelism
    2. Publishing to an event hub
      1. Event bus
      2. Domain events
        1. Event envelope
        2. Event-carried state transfer
        3. Substitution
        4. Internal versus external
      3. Routing and channel topology
    3. Dissecting the Event Sourcing pattern
      1. System-wide event sourcing
      2. Event lake
        1. Perpetual storage
        2. Indexing events
        3. Replaying events
    4. Event streams
      1. Temporal storage
      2. Stream-first event sourcing
      3. Concurrency control
      4. Micro-event stores
    5. Processing event streams
      1. Micro batching
      2. Choosing a programming paradigm
        1. Imperative programming
        2. Functional reactive programming
        3. Stream processing
      3. Creating a stream
      4. Unit of work
      5. Filtering and multiplexing
      6. Mapping
      7. Connectors
    6. Designing for failure
      1. Backpressure and rate limiting
      2. Poison events
      3. Fault events
      4. Resubmission
    7. Optimizing throughput
      1. Batch size function parameter
      2. Asynchronous non-blocking I/O
      3. Pipelines and multiplexing
        1. Pipeline patterns
      4. Sharding
      5. Batching and grouping
        1. Batching
        2. Grouping
    8. Summary
  6. Turning the Cloud into the Database
    1. Fighting data gravity
      1. Competing demands
      2. Insufficient capacity
      3. Intractable volumes
    2. Embracing the data life cycle
      1. Create phase
      2. Use phase
      3. Analyze phase
      4. Archive phase
    3. Turning the database inside out
      1. The transaction log
      2. Derived data
    4. Dissecting the CQRS pattern
      1. System wide CQRS
      2. Materialized views
      3. Inbound bulkheads
      4. Live cache
      5. Capacity per reader, per query
    5. Keeping data lean
      1. Projections
      2. Time to live
    6. Implementing idempotence and order tolerance
      1. Deterministic identifiers
      2. Inverse optimistic locking
      3. Immutable event triggers
    7. Modeling data for operational performance
      1. Nodes, edges, and aggregates
      2. Sharding and partition keys
      3. Single table design examples
        1. Restaurant service
        2. Customer service
        3. Cart service
        4. Delivery service
    8. Leveraging change data capture
      1. Database-first event sourcing
      2. Soft deletes
      3. Latching
    9. Summary
  7. A Best Friend for the Frontend
    1. Focusing on user activities
      1. A BFF service is responsible for a single user activity
      2. A BFF service is owned by the frontend team
      3. A BFF service is decoupled, autonomous, and resilient
    2. Dissecting the Backend for Frontend pattern
      1. Datastore
      2. API gateway
      3. Query and command functions
      4. Listener function
      5. Trigger function
    3. Dissecting function-level nano architecture
      1. Models
      2. Connectors
      3. Handlers
    4. Choosing between REST and GraphQL
      1. REST
      2. GraphQL
    5. Implementing different kinds of BFF services
      1. CRUD BFF services
      2. List-of-values (Lov) BFF services
      3. Task BFF services
      4. Search BFF services
      5. Action BFF services
      6. Dashboard BFF services
      7. Reporting BFF services
      8. Archive BFF services
    6. Summary
  8. Bridging Intersystem Gaps
    1. Creating an anti-corruption layer
      1. Macro-level ports and adapters
      2. Substitution principle
      3. External bulkhead
    2. Dissecting the External Service Gateway pattern
      1. Connectivity
      2. Semantic transformation
        1. Ingress
        2. Egress
      3. Packaging
      4. Separate cloud accounts
    3. Integrating with third-party systems
      1. Egress – API call
      2. Ingress – webhook
      3. Asynchronous request response
      4. Synchronous ESG/BFF hybrid
    4. Integrating with other subsystems
      1. Egress – upstream subsystem
      2. Ingress – downstream subsystem
    5. Integrating across cloud providers
    6. Integrating with legacy systems
      1. Ingress – Change Data Capture
      2. Egress – Direct SQL
      3. Egress – circuit breaker
      4. Ingress – relay
    7. Providing an open API and SPI
      1. Ingress API – event
      2. Ingress API – command
      3. Egress SPI – webhook
      4. Egress API – query
    8. Tackling common data challenges
      1. Idempotence
      2. Enriching data
      3. Latching and cross-referencing
      4. Slow data resync
    9. Summary
  9. Reacting to Events with More Events
    1. Promoting inter-service collaboration
      1. Choreography’s pros and cons
    2. Dissecting the Control Service pattern
      1. collect
      2. correlate
      3. collate
      4. evaluate
      5. emit
      6. expire
    3. Orchestrating business processes
      1. Entry and exit events
      2. Parallel execution
    4. Employing the Saga pattern
      1. Compensating transactions
      2. Abort events
    5. Calculating event-sourcing snapshots
      1. What is ACID 2.0?
      2. Snapshot events
    6. Implementing complex event processing (CEP) logic
      1. Decision tables
      2. Missing events
    7. Leveraging machine learning (ML) for control flow
      1. Models
      2. Predictions
    8. Summary
  10. Running in Multiple Regions
    1. Justifying multi-regional deployment
      1. Regional disruptions
      2. Nominal cost
      3. Higher user satisfaction
    2. Choosing a regional topology
      1. Primary/hot-secondary
      2. Active/active
        1. Balanced users
        2. Balanced data processing
    3. Preparing for regional failover
      1. Offline-first
      2. Protracted eventual consistency
    4. Checking regional health
      1. Traditional health checks
      2. Regional health checks
        1. Metrics
        2. Regional health check service
    5. Configuring regional routing
      1. Content Delivery Network (CDN)
      2. API Gateway
        1. Regional endpoints
        2. Global endpoints
      3. CDN plus API Gateway
      4. Global bus
    6. Replicating across regions
      1. Change event vs domain event replication
      2. Multi-master replication
      3. Round-robin replication
    7. Dissecting regional failover
      1. Query failover
      2. Command failover
      3. Trigger failure points
      4. Listener failure points
    8. Addressing intersystem differences
      1. External global endpoints
      2. Legacy regional endpoints
    9. Implementing multi-regional cron jobs
      1. Inserting job records and events
      2. Relying on replication and idempotence
    10. Summary
  11. Securing Autonomous Subsystems in Depth
    1. Shared responsibility model
    2. Securing cloud accounts
      1. Accounts-as-code
      2. Identity access management
    3. Securing CI/CD pipelines
      1. Pipeline permissions
      2. Deployment service permissions
      3. Permission boundaries
    4. Securing the perimeter
      1. Global/edge infrastructure
      2. Encryption in transit
      3. Federated identity
    5. Securing the frontend
      1. OpenID Connect
      2. Conditional rendering
      3. Protected routes
      4. Passing the JWT to BFF services
    6. Securing BFF services
      1. JWT authorizer
      2. JWT assertion
      3. JWT filter
      4. Last modified by
      5. Least privilege
    7. Redacting sensitive data
      1. Envelope encryption
      2. Crypto-shredding
    8. Securing ESG services
      1. Securing shared secrets
      2. Using API keys
    9. Auditing continuously
      1. Build-time and runtime auditing
      2. Change event audit
    10. Summary
  12. Choreographing Deployment and Delivery
    1. Optimizing testing for continuous deployment
      1. Continuous discovery
      2. Continuous testing
    2. Focusing on risk mitigation
      1. Small batch size
      2. Decoupling deployment from release
      3. Feature flags
        1. Natural
        2. Keystone
        3. Artificial
      4. Fail forward fast
    3. Achieving zero-downtime deployments
      1. The Robustness principle
      2. Between the frontend and its backend
      3. Between producers and consumers
      4. Between the backend and its data store
    4. Planning at multiple levels
      1. Experiments
      2. Story backlog
        1. Story mapping
        2. Story planning
      3. Task roadmaps
    5. Turning the crank
      1. Task branch workflow
        1. Create task branch
        2. Create draft pull request
        3. Ready for review
        4. Merge to master
        5. Accept canary deployment
      2. Feature flipping
        1. Exploratory testing
        2. Beta users
        3. General availability
    6. Dissecting CI/CD pipelines
      1. Continuous integration pipeline
        1. Serverless testing honeycomb
        2. Unit testing
        3. Integration testing
        4. Contract testing
        5. Transitive end-to-end testing
      2. Continuous deployment pipeline
        1. Regional canary deployments
        2. Synthetics
    7. Summary
  13. Optimizing Observability
    1. Failing forward fast
    2. Turning observability inside out
    3. Leveraging FinOps
      1. Cost is a metric
      2. Dissecting monthly cloud cost
      3. Worth-based development
    4. Collecting resource metrics
      1. The USE method
      2. Capacity and concurrency limits
      3. Throttling, iterator age, and queue depth
      4. Errors and fault events
    5. Tracking system events
    6. Alerting on work metrics
      1. The RED method
      2. BFF service metrics
      3. Domain event metrics
      4. Anomaly detection
    7. Observing real user activity
      1. Real User Monitoring (RUM)
      2. Synthetics
    8. Tuning continuously
      1. Function memory allocation
      2. Cold starts
      3. Timeouts and retries
      4. Cache-control
    9. Summary
  14. Don’t Delay, Start Experimenting
    1. Gaining trust and changing culture
      1. Establishing a vision
      2. Building momentum
      3. Constructing an architectural runway
      4. Seeding and splitting teams
    2. Funding products, not projects
      1. Architecture-driven funding
      2. Team capacity-driven funding
    3. Dissecting the Strangler pattern
      1. Event-first migration
      2. Micro frontend – headless mode
      3. Retirement
    4. Addressing event-first concerns
      1. System of record versus source of truth
      2. Duplicate data is good
      3. Avoid false reuse
    5. Poly everything
      1. Polyglot programming
      2. Polyglot persistence
      3. Polycloud
    6. Summary
  15. Other Books You May Enjoy
  16. Index

Product information

  • Title: Software Architecture Patterns for Serverless Systems - Second Edition
  • Author(s): John Gilbert
  • Release date: February 2024
  • Publisher(s): Packt Publishing
  • ISBN: 9781803235448