Home Page Icon
Home Page
Table of Contents for
Index
Close
Index
by Bob Gregory, Harry Percival
Architecture Patterns with Python
Preface
Managing Complexity, Solving Business Problems
Why Python?
TDD, DDD and Event-Driven Architecture
Who Should Read This Book
A note to our Early Release Readers
A Brief Overview of What You’ll Learn
Part I, Building an Architecture to Support Domain Modelling
Part II, Event-Driven Architecture
Epilogue
Example Code and Coding Along
Conventions Used in This Book
O’Reilly Online Learning
How to Contact O’Reilly
Acknowledgments
Introduction: Why Do Our Designs Go Wrong?
Encapsulation and Abstractions
Layering
The Dependency Inversion Principle
A Place for All Our Business Logic: the Domain Model
I. Building an Architecture to Support Domain Modelling
1. Domain Modelling
What Is a Domain Model?
Exploring the Domain Language
Unit Testing Domain Models
Dataclasses Are Great for Value Objects
Value Objects and Entities
Not Everything Has to Be an Object: A Domain Service Function
Python’s Magic Methods Let Us Use Our Models with Idiomatic Python
Exceptions Can Express Domain Concepts Too
2. Repository Pattern
Persisting Our Domain Model
Some Pseudocode: What Are We Going to Need?
Applying the Dependency Inversion Principle to the Database
Reminder: Our Model
The “Normal” ORM Way: Model Depends on ORM
Inverting the Dependency: ORM Depends on Model
Introducing Repository Pattern
The Repository in the Abstract
What Is the Trade-Off?
Building a Fake Repository for Tests Is Now Trivial!
What is a Port and What is an Adapter, in Python?
Wrap-Up
3. A Brief Interlude: On Coupling and Abstractions
Abstracting State Aids Testability
Choosing the Right Abstraction(s)
Implementing Our Chosen Abstractions
Testing Edge-to-Edge with Fakes and Dependency Injection
Why Not Just Patch It Out?
Wrap-up: Some Heuristics for Choosing Abstractions
4. Our First Use Case: Flask API and Service Layer
Connecting Our Application to the Real World
A First End-To-End (E2E) Test
The Straightforward Implementation
Error Conditions That Require Database Checks
Introducing a Service Layer, and Using FakeRepository to Unit Test It
A Typical Service Function
Why Is Everything Called A Service?
Putting things in folders to see where everything belongs
Wrap-Up
The DIP in Action
5. TDD in High Gear and Low Gear
How is our Test Pyramid Looking?
Should Domain Layer Tests Move to the Service Layer?
On Deciding What Kind of Tests to Write
High and Low Gear
Fully Decoupling the Service Layer Tests From the Domain
Mitigation: Keep All Domain Dependencies in Fixture Functions
Adding a Missing Service
Carrying the Improvement Through to the E2E Tests
Wrap-Up
6. Unit of Work Pattern
The Unit of Work Collaborates with Repository(-Ies)
Test-Driving a UoW with Integration Tests
Unit of Work and Its Context Manager
The Real Unit of Work Uses SQLAlchemy Sessions
Fake Unit of Work for Testing:
Using the UoW in the Service Layer
Explicit Tests for Commit/Rollback Behavior
Explicit vs Implicit Commits
Examples: Using UoW to Group Multiple Operations Into an Atomic Unit
Example 1: Reallocate
Example 2: Change Batch Quantity
Tidying Up the Integration Tests
Wrap-Up
7. Aggregates and Consistency Boundaries
Why Not Just Run Everything in a Spreadsheet?
Invariants, Constraints and Consistency
Invariants, Concurrency and Locks
What is an Aggregate?
Choosing an Aggregate
1 Aggregate = 1 Repository
Optimistic Concurrency With Version Numbers
Implementation Options for Version Numbers
Testing for Our Data Integrity Rules
Enforcing Concurrency Rules by Using Database Transaction Isolation Levels
SELECT FOR UPDATE Can Also Help
II. Event-Driven Architecture
8. Events and the Message Bus
Avoiding Making a Mess.
First, Avoid Making a Mess of of Our Web Controllers
… And Let’s Not Make a Mess of Our Model Either
… Or the Service Layer!
Single Responsibility Principle
All Aboard the Message Bus!
The Model Records Events
Events Are Simple Dataclasses
The Model Raises Events
The Message Bus Maps Events to Handlers
Option 1 : The Service Layer Takes Events from the Model and Puts them on the Message Bus
Option 2: The Service Layer Raises Its Own Events
Option 3: The Unit of Work Can Publish Events to the Message Bus
Wrap-Up
9. Going to Town on the Message Bus
A New Requirement Leads Us to Consider a New Architecture
Imagining an Architecture Change: Everything Will Be an Event Handler
Refactoring Service Functions to Message Handlers
The MessageBus Becomes Responsible for Collecting Events from the UoW
Our Tests Are All Written in Terms of Events Too:
A Temporary Ugly Hack: The Messagebus Has to Return Results
Modifying Our API to Do Events
Implementing Our New Requirement
Our New Event
Test-Driving a New Handler
Implementation
A New Method on the Domain Model
What Have We Achieved?
Why Have We Achieved?
10. Commands and Command Handler
Commands and Events
Differences in Exception-handling
Discussion: Events, Commands, and Error Handling
Recovering From Errors Synchronously
11. Event-Driven Architecture: Using Events to Integrate Microservices
Distributed Ball of Mud, and Thinking in Nouns
Error Handling in Distributed Systems
The Alternative: Temporal Decoupling using Asynchronous Messaging
Using a Redis Pubsub Channel for Integration
Test-Driving It All Using an End-To-End Test
Redis Is Another Thin Adapter Around Our Message Bus
Our New Outgoing Event
Wrap-Up
12. Command-Query Responsibility Separation (CQRS)
Domain models are for writing
Most users aren’t going to buy your furniture
Post/Redirect/Get and CQS
Hold on to Your Lunch Folks.
Testing CQRS Views
“Obvious” Alternative 1: Using the Existing Repository
Your Domain Model is not Optimized for Read Operations
“Obvious” Alternative 2: Using the ORM
SELECT N+1, and Other Performance Considerations
Time to completely jump the shark
Updating a Read Model Table Using an Event Handler
Changing our Read Model Implementation is Easy
But Would You Really? CRUD versus CQRS.
13. Dependency Injection (And Bootstrapping)
Implicit vs Explicit Dependencies
Aren’t Explicit Dependencies Totally Weird and Java-Ey Tho?
Preparing Handlers: Manual DI with Closures and Partials
An Alternative Using Classes
A Bootstrap Script
Messagebus Gets Given Handlers at Runtime
Using Bootstrap in Our Entrypoints
Initializing DI in Our Tests
Building an Adapter “Properly”: A Worked Example
Define the Abstract and Concrete Implementations
Make a Fake Version for your Tests
Figure out how to Integration Test the Real Thing
DI and bootstrap wrap-up
Epilogue: What now?
How do I get there from here?
Separating entangled responsibilities
Identifying Aggregates and Bounded Contexts
An Event-driven Approach to go Microservices Via Strangler Pattern
Convincing your stakeholders to try something new
Getting started
More required reading
Questions our Tech Reviewers Asked That We Couldn’t Work Into Prose
Footguns
Reliable messaging is hard
We explicitly choose small, focused transactions that can fail independently
We don’t discuss idempotency
Your events will need to change their schema over time
A. Summary diagram and table
B. A Template Project Structure
Env Vars, 12-Factor, and Config, Inside and Outside Containers.
Config.py
Docker-Compose and Containers Config
Installing Your Source as a Package
Dockerfile
Tests
Wrap-up
C. Swapping Out the Infrastructure: Do Everything with CSVs
Implementing a Repository and Unit of Work for CSVs
D. Repository and Unit of Work Patterns with Django
Repository Pattern with Django
Custom Methods on Django ORM Classes to Translate To/From Our Domain Model
Unit of Work Pattern with Django
API: Django Views Are Adapters
Why was this all so hard?
What To Do If You Already Have Django
Steps along the way
E. Validation
What is validation anyway?
Validating Syntax
Postel’s Law and the Tolerant Reader Pattern
Validating At The Edge
Validating Semantics
Validating Pragmatics
Index
Search in book...
Toggle Font Controls
Playlists
Add To
Create new playlist
Name your new playlist
Playlist description (optional)
Cancel
Create playlist
Sign In
Email address
Password
Forgot Password?
Create account
Login
or
Continue with Facebook
Continue with Google
Sign Up
Full Name
Email address
Confirm Email Address
Password
Login
Create account
or
Continue with Facebook
Continue with Google
Prev
Previous Chapter
E. Validation
Next
Next Chapter
About the Authors
Add Highlight
No Comment
..................Content has been hidden....................
You can't read the all page of ebook, please click
here
login for view all page.
Day Mode
Cloud Mode
Night Mode
Reset