Software Architecture Patterns for Serverless Systems: Architecting for innovation with events, autonomous services, and micro frontends

This document was uploaded by one of our users. The uploader already confirmed that they had the permission to publish it. If you are author/publisher or own the copyright of this documents, please report to us by using this DMCA report form.

Simply click on the Download Book button.

Yes, Book downloads on Ebookily are 100% Free.

Sometimes the book is free on Amazon As well, so go ahead and hit "Search on Amazon"

A professional's guide to solving complex problems while designing modern software Key Features Learn best practices for designing enterprise-grade software systems Understand the importance of building reliable, maintainable, and scalable systems Become a professional software architect by learning the most effective software design patterns and architectural concepts Book Description As businesses are undergoing a digital transformation to keep up with competition, it is now more important than ever for IT professionals to design systems to keep up with the rate of change while maintaining stability. This book takes you through the architectural patterns that power enterprise-grade software systems and the key architectural elements that enable change such as events, autonomous services, and micro frontends, along with demonstrating how to implement and operate anti-fragile systems. You'll divide up a system and define boundaries so that teams can work autonomously and accelerate the pace of innovation. The book also covers low-level event and data patterns that support the entire architecture, while getting you up and running with the different autonomous service design patterns. As you progress, you'll focus on best practices for security, reliability, testability, observability, and performance. Finally, the book combines all that you've learned, explaining the methodologies of continuous experimentation, deployment, and delivery before providing you with 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 so that you can deliver value at the pace needed by your business. What you will learn Explore architectural patterns to create anti-fragile systems that thrive with change Focus on DevOps practices that empower self-sufficient, full-stack teams Build enterprise-scale serverless systems Apply microservices principles to the frontend Discover how SOLID principles apply to software and database architecture Create event stream processors that power the event sourcing and CQRS pattern Deploy a multi-regional system, including regional health checks, latency-based routing, and replication Explore the Strangler pattern for migrating legacy systems Who this book is for This book is for software architects and aspiring software architects who want to learn about different patterns and best practices to design better software. Intermediate-level experience in software development and design is required. Beginner-level knowledge of the cloud will also help you get the most out of this software design book. Table of Contents Architecting for Innovation Defining Boundaries and Letting Go Taming the Presentation Tier Trusting Facts and Eventual Consistency Turning the Cloud into the Database A Best Friend for the Frontend Bridging Intersystem Gaps Reacting to Events with More Events Choreographing Deployment and Delivery Don't Delay, Start Experimenting

Author(s): John Gilbert
Edition: 1
Publisher: Packt Publishing
Year: 2021

Language: English
Pages: 432
Tags: software, architecture, patterns, serverless, systems

Cover
Title Page
Copyright and credits
Contributors
Table of Contents
Preface
Section 1: Establishing an Architectural Vision
Chapter 1: Architecting for Innovation
Continuously delivering business value
By the skin of our teeth
Through high-velocity teamwork
Taking control of lead time
Risk mitigation
Decision making
Software Development Life Cycle methodology
Hardware provisioning
Software deployment
Software structure
Testing and confidence
Dependencies and inter-team communication
Dissecting integration styles
Batch integration
Spaghetti integration
Real-time integration
Enterprise application integration
Shared database
Service-oriented architecture
Microservices
Enabling autonomous teams with autonomous services
Autonomous services – creating bulkheads
Event-first – valuing facts
Serverless-first – creating knowledge
Data life cycle – fighting data gravity
Micro frontends – equalizing tiers
Observability – optimizing everything
Organic evolution – embracing change
Summary
Chapter 2: Defining Boundaries and Letting Go
Building on SOLID principles
Single Responsibility Principle
Open-Closed Principle
Liskov Substitution Principle
Interface Segregation Principle
Dependency Inversion Principle
Thinking about events first
Event storming
Verbs versus nouns
Facts versus ephemeral messages
Contracts versus notifications
React and evolve
Powered by an event hub
Dividing a system into autonomous subsystems
By actor
By business unit
By business capability
By data life cycle
By legacy system
Creating subsystem bulkheads
Decomposing a subsystem into autonomous services
Context diagram
Micro frontend
Event hub
Autonomous service patterns
Dissecting an autonomous service
Repository
CI/CD pipeline and GitOps
Tests
Stack
Persistence
Trilateral API
Functions
Micro-app
Shared libraries
Governing without impeding
Leveraging observability
Facilitating a culture of robustness
Audit continuously
Securing the perimeter
Elevating TestOps
Automating account creation
Summary
Section 2: Dissecting the Software Architecture Patterns
Chapter 3: Taming the Presentation Tier
Zigzagging through time
Client-side versus server-side rendering
Build-time versus runtime rendering
Web versus mobile
Breaking up the frontend monolith
By subsystem
By user activity
By device type
By version
Dissecting micro frontends
The main app
Micro-app
Micro-app activation
Mount points
Manifest deployer
Inter-application communication
Designing for offline-first
Transparency
Local cache
Live updates
Regional failover
Securing the user experience
OpenID Connect
Conditional rendering
Protected routes
Passing the JWT to BFF services
Observing real user activity
RUM
Synthetics
Summary
Chapter 4: Trusting Facts and Eventual Consistency
Living in an eventually consistent world
Staging
Consistency
Concurrency and partitions
Order tolerance and idempotence
Parallelism
Publishing to an event hub
Event bus
Domain events
Routing and channel topology
Dissecting the Event Sourcing pattern
Systemwide event sourcing
Event lake
Event streams
Micro event stores
Processing event streams
Batch size
Functional reactive programming
Unit of work
Filtering and multiplexing
Mapping
Connectors
Designing for failure
Backpressure and rate limiting
Poison events
Fault events
Resubmission
Optimizing throughput
Batch size
Asynchronous non-blocking I/O
Pipelines and multiplexing
Sharding
Batching and grouping
Observing throughput
Work metrics
Iterator age
Fault events
Accounting for regional failover
Protracted eventual consistency
Regional messaging channels
Summary
Chapter 5: Turning the Cloud into the Database
Escaping data's gravity
Competing demands
Insufficient capacity
Intractable volumes
Embracing data life cycle
Create phase
Use phase
Analyze phase
Archive phase
Turning the database inside out
The transaction log
Derived data
Dissecting the CQRS pattern
Systemwide CQRS
Materialized views
Inbound bulkheads
Live cache
Capacity per reader, per query
Keeping data lean
Projections
Time to live
Implementing idempotence and order tolerance
Deterministic identifiers
Inverse optimistic locking
Immutable event triggers
Modeling data for operational performance
Nodes, edges, and aggregates
Sharding and partition keys
Single table design examples
Leveraging change data capture
Database-first event sourcing
Soft deletes
Latching
Replicating across regions
Multi-master replication
Round-robin replication
Regional failover, protracted eventual consistency, and order tolerance
Observing resource metrics
Capacity
Throttling and errors
Performance
Redacting sensitive data
Envelope encryption
General Data Protection Regulation (GDPR)
Summary
Chapter 6: A Best Friend for the Frontend
Focusing on user activities
A BFF service is responsible for a single user activity
A BFF service is owned by the frontend team
Decoupled, autonomous, and resilient
Dissecting the Backend for Frontend (BFF) pattern
Datastore
API Gateway
Query and command functions
Listener function
Trigger function
Models and connectors
Choosing between GraphQL and REST
REST
GraphQL
Implementing different kinds of BFF services
Task BFF services
Search BFF services
Action BFF services
Dashboard BFF services
Reporting BFF services
Archive BFF services
Securing a BFF in depth
The perimeter
Federated identity
In transit
JWT authorizer
JWT assertion
JWT filter
Last modified by
Least privilege
At rest
Leveraging multiple regions
Latency-based routing
Regional health checks
Regional failover
Observing BFF metrics
Work metrics
Throttling and concurrency limits
Optimizing BFF performance
Function memory allocation
Cold starts
Timeouts and retries
cache-control
Summary
Chapter 7: Bridging Intersystem Gaps
Creating an anti-corruption layer
Dissecting the External Service Gateway pattern
Connectivity
Semantic transformation
Action versus reaction
Egress
Ingress
Packaging
Separate cloud accounts
Integrating with third-party systems
Egress – API call
Ingress – webhook
Asynchronous request response
Integrating with other subsystems
Egress – upstream subsystem
Ingress – downstream subsystem
Integrating across cloud providers
Integrating with legacy systems
Ingress – Change Data Capture
Egress – Direct SQL
Egress – circuit breaker
Ingress – relay
Egress – relay
Providing an external API and SPI
Ingress – event
Ingress – command
Egress – webhook
Egress – query
Tackling common data challenges
Idempotence
Enriching data
Latching and cross-referencing
Slow data resync
Managing shared secrets
Securing secrets
Using API keys
Addressing multi-regional differences
Egress routing and failover
Ingress routing and failover
Summary
Chapter 8: Reacting to Events with More Events
Promoting inter-service collaboration
Dissecting the Control Service pattern
collect
correlate
collate
evaluate
emit
expire
Orchestrating business processes
Entry and exit events
Parallel execution
Employing the Saga pattern
Compensating transactions
Abort events
Calculating event-sourcing snapshots
What is ACID 2.0?
Snapshot events
Implementing CEP logic
Decision tables
Missing events
Leveraging ML for control flow
Models
Predictions
Implementing multi-regional cron jobs
Job records and events
Replication and idempotence
Summary
Section 3: Putting Everything in Motion
Chapter 9: Choreographing Deployment and Delivery
Optimizing testing for continuous deployment
Continuous discovery
Continuous testing
Focusing on risk mitigation
Small batch size
Decoupling deployment from release
Feature flags
Fail forward fast
Achieving zero-downtime deployments
The Robustness principle
Between the frontend and its backend
Between producers and consumers
Between the backend and its data store
Planning at multiple levels
Experiments
Story backlog
Task roadmaps
Turning the crank
Task branch workflow
Continuous integration pipeline
Continuous deployment pipeline
Feature flipping
Summary
Chapter 10: Don't Delay, Start Experimenting
Gaining trust and changing culture
Establishing a vision
Building momentum
Constructing an architectural runway
Seed and split
Funding products, not projects
Architecture-driven
Team capacity-driven
Dissecting the Strangler pattern
Event-first migration
Micro frontend – headless mode
Retirement
Addressing event-first concerns
System of record versus source of truth
Duplicate data is good
Avoid false reuse
Poly everything
Polyglot programming
Polyglot persistence
Polycloud
Summary
Other Books You May Enjoy
Index