y Cesar de la Torre Bill Wagner Mike Rousos i Microsoft Corporation EDITION v1.0 DOWNLOAD available at: https://aka.ms/microservicesebook PUBLISHED BY Microsoft Developer Division, .NET and Visual Studio product teams A division of Microsoft Corporation One Microsoft Way Redmond, Washington 98052-6399 Copyright © 2017 by Microsoft Corporation All rights reserved. No part of the contents of this book may be reproduced or transmitted in any form or by any means without the written permission of the publisher. This book is provided “as-is” and expresses the author’s views and opinions. The views, opinions and information expressed in this book, including URL and other Internet website references, may change without notice. Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred. Microsoft and the trademarks listed at http://www.microsoft.com on the “Trademarks” webpage are trademarks of the Microsoft group of companies. Mac and macOS are trademarks of Apple Inc. The Docker whale logo is a registered trademark of Docker, Inc. Used by permission. All other marks and logos are property of their respective owners. Co-Authors: Editors: Cesar de la Torre, Sr. PM, .NET product team, Microsoft Corp. Mike Pope Bill Wagner, Sr. Content Developer, C+E, Microsoft Corp. Steve Hoag Mike Rousos, Principal Software Engineer, DevDiv CAT team, Microsoft Participants and reviewers: Jeffrey Ritcher, Partner Software Eng, Azure team, Microsoft Dylan Reisenberger, Architect and Dev Lead at Polly Jimmy Bogard, Chief Architect at Headspring Steve Smith, Software Craftsman & Trainer at ASPSmith Ltd. Udi Dahan, Founder & CEO, Particular Software Ian Cooper, Coding Architect at Brighter Jimmy Nilsson, Co-founder and CEO of Factor10 Unai Zorrilla, Architect and Dev Lead at Plain Concepts Glenn Condron, Sr. Program Manager, ASP.NET team Eduard Tomas, Dev Lead at Plain Concepts Mark Fussell, Principal PM Lead, Azure Service Fabric team, Microsoft Ramon Tomas, Developer at Plain Concepts Diego Vega, PM Lead, Entity Framework team, Microsoft David Sanz, Developer at Plain Concepts Barry Dorrans, Sr. Security Program Manager Javier Valero, Chief Operating Officer at Grupo Solutio Rowan Miller, Sr. Program Manager, Microsoft Pierre Millet, Sr. Consultant, Microsoft Ankit Asthana, Principal PM Manager, .NET team, Microsoft Michael Friis, Product Manager, Docker Inc Scott Hunter, Partner Director PM, .NET team, Microsoft Charles Lowell, Software Engineer, VS CAT team, Microsoft ii Contents Introduction ................................................................................................................................................. 1 About this guide ...................................................................................................................................................................... 1 What this guide does not cover ......................................................................................................................................... 1 Who should use this guide .................................................................................................................................................. 2 How to use this guide ............................................................................................................................................................ 2 Related microservice and container-based reference application: eShopOnContainers ............................ 2 Send us your feedback! ......................................................................................................................................................... 2 Introduction to Containers and Docker .................................................................................................. 3 What is Docker?........................................................................................................................................................................ 4 Comparing Docker containers with virtual machines ........................................................................................... 5 Docker terminology ................................................................................................................................................................ 6 Docker containers, images, and registries ..................................................................................................................... 7 Choosing Between .NET Core and .NET Framework for Docker Containers ..................................... 9 General guidance ..................................................................................................................................................................... 9 When to choose .NET Core for Docker containers .................................................................................................. 10 Developing and deploying cross platform ............................................................................................................ 10 Using containers for new (“green-field”) projects ............................................................................................... 10 Creating and deploying microservices on containers ....................................................................................... 10 Deploying high density in scalable systems .......................................................................................................... 11 When to choose .NET Framework for Docker containers ..................................................................................... 11 Migrating existing applications directly to a Docker container ..................................................................... 12 Using third-party .NET libraries or NuGet packages not available for .NET Core .................................. 12 Using.NET technologies not available for .NET Core ......................................................................................... 12 Using a platform or API that does not support .NET Core .............................................................................. 13 Decision table: .NET frameworks to use for Docker ................................................................................................ 14 What OS to target with .NET containers...................................................................................................................... 15 Official .NET Docker images ............................................................................................................................................. 16 .NET Core and Docker image optimizations for development versus production ................................ 16 Architecting Container- and Microservice-Based Applications ........................................................ 18 Vision ......................................................................................................................................................................................... 18 Container design principles .............................................................................................................................................. 18 Containerizing monolithic applications ....................................................................................................................... 19 Deploying a monolithic application as a container ............................................................................................ 21 iii Publishing a single-container-based application to Azure App Service .................................................... 21 State and data in Docker applications ......................................................................................................................... 22 Service-oriented architecture ........................................................................................................................................... 24 Microservices architecture ................................................................................................................................................ 25 Data sovereignty per microservice ............................................................................................................................ 27 The relationship between microservices and the Bounded Context pattern ........................................... 28 Logical architecture versus physical architecture ................................................................................................ 29 Challenges and solutions for distributed data management ......................................................................... 30 Identifying domain-model boundaries for each microservice ....................................................................... 34 Direct client-to-microservice communication versus the API Gateway pattern ..................................... 38 Communication between microservices ................................................................................................................. 42 Creating composite UI based on microservices, including visual UI shape and layout generated by multiple microservices ................................................................................................................................................... 53 Resiliency and high availability in microservices ................................................................................................. 55 Health management and diagnostics in microservices .................................................................................... 55 Orchestrating microservices and multi-container applications for high scalability and availability ... 58 Using container-based orchestrators in Microsoft Azure ................................................................................ 60 Using Azure Container Service ................................................................................................................................... 60 Using Azure Service Fabric ........................................................................................................................................... 62 Stateless versus stateful microservices .................................................................................................................... 65 Development Process for Docker-Based Applications ....................................................................... 67 Vision ......................................................................................................................................................................................... 67 Development environment for Docker apps ............................................................................................................. 67 Development tool choices: IDE or editor................................................................................................................ 67 .NET languages and frameworks for Docker containers .................................................................................. 68 Development workflow for Docker apps .................................................................................................................... 68 Workflow for developing Docker container-based applications .................................................................. 68 Simplified workflow when developing containers with Visual Studio ........................................................ 81 Using PowerShell commands in a Dockerfile to set up Windows Containers ......................................... 82 Deploying Single-Container-Based .NET Core Web Applications on Linux or Windows Nano Server Hosts ............................................................................................................................................... 83 Vision ......................................................................................................................................................................................... 83 Application tour ..................................................................................................................................................................... 84 Docker support ...................................................................................................................................................................... 85 Troubleshooting .................................................................................................................................................................... 87 Stopping Docker containers ........................................................................................................................................ 87 Adding Docker to your projects ................................................................................................................................. 87 Migrating Legacy Monolithic .NET Framework Applications to Windows Containers ................. 88 Vision ......................................................................................................................................................................................... 88 iv Benefits of containerizing a monolithic application ............................................................................................... 89 Possible migration paths ................................................................................................................................................... 90 Application tour ..................................................................................................................................................................... 90 Lifting and shifting ............................................................................................................................................................... 92 Getting data from the existing catalog .NET Core microservice ........................................................................ 94 Development and production environments ............................................................................................................ 94 Designing and Developing Multi-Container and Microservice-Based .NET Applications ............ 95 Vision ......................................................................................................................................................................................... 95 Designing a microservice-oriented application ........................................................................................................ 95 Application specifications ............................................................................................................................................. 95 Development team context ......................................................................................................................................... 96 Choosing an architecture .............................................................................................................................................. 96 Benefits of a microservice-based solution ............................................................................................................. 99 Downsides of a microservice-based solution ....................................................................................................... 99 External versus internal architecture and design patterns ............................................................................ 101 The new world: multiple architectural patterns and polyglot microservices.......................................... 102 Creating a simple data-driven CRUD microservice ............................................................................................... 103 Designing a simple CRUD microservice ................................................................................................................ 103 Implementing a simple CRUD microservice with ASP.NET Core ................................................................. 105 Generating Swagger description metadata from your ASP.NET Core Web API ................................... 111 Defining your multi-container application with docker-compose.yml ......................................................... 115 Using a database server running as a container .................................................................................................... 130 Implementing event-based communication between microservices (integration events) ................... 134 Using message brokers and services buses for production systems ........................................................ 135 Integration events .......................................................................................................................................................... 136 The event bus .................................................................................................................................................................. 137 Testing ASP.NET Core services and web apps ........................................................................................................ 154 Tackling Business Complexity in a Microservice with DDD and CQRS Patterns ........................... 158 Vision ....................................................................................................................................................................................... 158 Applying simplified CQRS and DDD patterns in a microservice ...................................................................... 160 Applying CQRS and CQS approaches in a DDD microservice in eShopOnContainers ........................... 161 CQRS and DDD patterns are not top-level architectures............................................................................... 162 Implementing reads/queries in a CQRS microservice .......................................................................................... 163 Using ViewModels specifically made for client apps, independent from domain model constraints ............................................................................................................................................................................................... 164 Using Dapper as a micro ORM to perform queries .......................................................................................... 164 Dynamic and static ViewModels .............................................................................................................................. 165 Designing a DDD-oriented microservice ................................................................................................................... 166 v Keep the microservice context boundaries relatively small .......................................................................... 166 Layers in DDD microservices ..................................................................................................................................... 166 Designing a microservice domain model.................................................................................................................. 170 The Domain Entity pattern ......................................................................................................................................... 170 Implementing a microservice domain model with .NET Core .......................................................................... 175 Domain model structure in a custom .NET Standard Library ....................................................................... 175 Structuring aggregates in a custom .NET Standard Library .......................................................................... 176 Implementing domain entities as POCO classes ............................................................................................... 177 Seedwork (reusable base classes and interfaces for your domain model) ............................................. 182 Repository contracts (interfaces) in the domain model layer ...................................................................... 184 Implementing value objects ...................................................................................................................................... 184 Using Enumeration classes instead of C# language enum types ............................................................... 189 Designing validations in the domain model layer ............................................................................................ 191 Implementing validations in the domain model layer .................................................................................... 192 Client-side validation (validation in the presentation layers) ....................................................................... 194 Domain events: design and implementation ........................................................................................................... 196 What is a domain event? ............................................................................................................................................. 196 Domain events versus integration events ............................................................................................................ 196 Implementing domain events ........................................................................................................................................ 199 Raising domain events ................................................................................................................................................. 200 Single transaction across aggregates versus eventual consistency across aggregates ..................... 203 The domain event dispatcher: mapping from events to event handlers ................................................. 205 How to subscribe to domain events ....................................................................................................................... 206 How to handle domain events.................................................................................................................................. 206 Conclusions on domain events................................................................................................................................. 208 Designing the infrastructure persistence layer ....................................................................................................... 209 The Repository pattern ................................................................................................................................................ 209 Implementing the infrastructure persistence layer with Entity Framework Core ...................................... 213 Introduction to Entity Framework Core ................................................................................................................. 213 Infrastructure in Entity Framework Core from a DDD perspective ............................................................. 213 Implementing custom repositories with Entity Framework Core ............................................................... 216 EF DbContext and IUnitOfWork instance lifetime in your IoC container ................................................. 219 The repository instance lifetime in your IoC container ................................................................................... 220 Table mapping ................................................................................................................................................................ 221 Using NoSQL databases as a persistence infrastructure ..................................................................................... 225 Designing the microservice application layer and Web API .............................................................................. 228 Using SOLID principles and Dependency Injection .......................................................................................... 228 Implementing the microservice application layer using the Web API .......................................................... 229 vi Using Dependency Injection to inject infrastructure objects into your application layer ................. 229 Implementing the Command and Command Handler patterns ................................................................. 233 The Command process pipeline: how to trigger a command handler ..................................................... 239 Implementing the command process pipeline with a mediator pattern (MediatR) ............................ 242 Applying cross-cutting concerns when processing commands with the Mediator and Decorator patterns .............................................................................................................................................................................. 244 Implementing Resilient Applications .................................................................................................. 248 Vision ....................................................................................................................................................................................... 248 Handling partial failure ..................................................................................................................................................... 248 Strategies for handling partial failure ......................................................................................................................... 250 Implementing retries with exponential backoff ................................................................................................. 251 Implementing the Circuit Breaker pattern ........................................................................................................... 260 Using the ResilientHttpClient utility class from eShopOnContainers ....................................................... 262 Testing retries in eShopOnContainers ................................................................................................................... 264 Testing the circuit breaker in eShopOnContainers ........................................................................................... 264 Adding a jitter strategy to the retry policy .......................................................................................................... 266 Health monitoring .............................................................................................................................................................. 268 Implementing health checks in ASP.NET Core services .................................................................................. 268 Using watchdogs ............................................................................................................................................................ 272 Health checks when using orchestrators .............................................................................................................. 273 Advanced monitoring: visualization, analysis, and alerts ............................................................................... 273 Securing .NET Microservices and Web Applications ......................................................................... 274 Implementing authentication in .NET microservices and web applications ................................................ 274 Authenticating using ASP.NET Core Identity ...................................................................................................... 275 Authenticating using external providers ............................................................................................................... 276 Authenticating with bearer tokens .......................................................................................................................... 278 About authorization in .NET microservices and web applications .................................................................. 282 Implementing role-based authorization ............................................................................................................... 282 Implementing policy-based authorization ........................................................................................................... 283 Storing application secrets safely during development ...................................................................................... 285 Storing secrets in environment variables ............................................................................................................. 285 Storing secrets using the ASP.NET Core Secret Manager .............................................................................. 285 Using Azure Key Vault to protect secrets at production time .......................................................................... 286 Key Takeaways ........................................................................................................................................ 288 vii viii 1 SECTION Introduction Enterprises are increasingly realizing cost savings, solving deployment problems, and improving DevOps and production operations by using containers. Microsoft has been releasing container innovations for Windows and Linux by creating products like Azure Container Service and Azure Service Fabric, and by partnering with industry leaders like Docker, Mesosphere, and Kubernetes. These products deliver container solutions that help companies build and deploy applications at cloud speed and scale, whatever their choice of platform or tools. Docker is becoming the de facto standard in the container industry, supported by the most significant vendors in the Windows and Linux ecosystems. (Microsoft is one of the main cloud vendors supporting Docker.) In the future, Docker will probably be ubiquitous in any datacenter in the cloud or on-premises. In addition, the microservices architecture is emerging as an important approach for distributed mission-critical applications. In a microservice-based architecture, the application is built on a collection of services that can be developed, tested, deployed, and versioned independently. About this guide This guide is an introduction to developing microservices-based applications and managing them using containers. It discusses architectural design and implementation approaches using .NET Core and Docker containers. To make it easier to get started with containers and microservices, the guide focuses on a reference containerized and microservice-based application that you can explore. The sample application is available at the eShopOnContainers GitHub repo. This guide provides foundational development and architectural guidance primarily at a development environment level with a focus on two technologies: Docker and .NET Core. Our intention is that you read this guide when thinking about your application design without focusing on the infrastructure (cloud or on-premises) of your production environment. You will make decisions about your infrastructure later, when you create your production-ready applications. Therefore, this guide is intended to be infrastructure agnostic and more development-environment-centric. After you have studied this guide, your next step would be to learn about production-ready microservices on Microsoft Azure. What this guide does not cover This guide does not focus on the application lifecycle, DevOps, CI/CD pipelines, or team work. The complementary guide Containerized Docker Application Lifecycle with Microsoft Platform and Tools focuses on that subject. The current guide also does not provide implementation details on Azure infrastructure, such as information on specific orchestrators. 1 Introduction Additional resources • Containerized Docker Application Lifecycle with Microsoft Platform and Tools (downloadable eBook) https://aka.ms/dockerlifecycleebook Who should use this guide We wrote this guide for developers and solution architects who are new to Docker-based application development and to microservices-based architecture. This guide is for you if you want to learn how to architect, design, and implement proof-of-concept applications with Microsoft development technologies (with special focus on .NET Core) and with Docker containers. You will also find this guide useful if you are a technical decision maker, such as an enterprise architect, who wants an architecture and technology overview before you decide on what approach to select for new and modern distributed applications. How to use this guide The first part of this guide introduces Docker containers, discusses how to choose between .NET Core and the .NET Framework as a development framework, and provides an overview of microservices. This content is for architects and technical decision makers who want an overview but who do not need to focus on code implementation details. The second part of the guide starts with the Development process for Docker based applications section. It focuses on development and microservice patterns for implementing applications using .NET Core and Docker. This section will be of most interest to developers and architects who want to focus on code and on patterns and implementation details. Related microservice and container-based reference application: eShopOnContainers The eShopOnContainers application is a reference app for .NET Core and microservices that is designed to be deployed using Docker containers. The application consists of multiple subsystems, including several e-store UI front ends (a Web app and a native mobile app). It also includes the back- end microservices and containers for all required server-side operations. This microservice and container-based application source code is open source and available at the eShopOnContainers GitHub repo. Send us your feedback! We wrote this guide to help you understand the architecture of containerized applications and microservices in .NET. The guide and related reference application will be evolving, so we welcome your feedback! If you have comments about how this guide can be improved, please send them to: mailto:[email protected] 2 Introduction