More on this book
Community
Kindle Notes & Highlights
by
Sam Newman
Read between
November 1 - December 24, 2017
different types of calls from one service to another,
We want related behavior to sit together, and unrelated behavior to sit elsewhere.
Each bounded context has an explicit interface, where it decides what models to share with other contexts.
If you want information from a bounded context, or want to make requests of functionality within a bounded context, you communicate with its explicit boundary using models.
The stock item then becomes a shared model between the two contexts.
By thinking clearly about what models should be shared, and not sharing our internal representations, we avoid one of the potential pitfalls that can result in tight coupling
In general, microservices should cleanly align to bounded contexts.
if our service boundaries align to the bounded contexts in our domain, and our microservices represent those bounded contexts, we are off to an excellent start in ensuring that our microservices are loosely coupled and strongly cohesive.
Prematurely decomposing a system into microservices can be costly, especially if you are new to the domain. In many ways, having an existing codebase you want to decompose into microservices is much easier than trying to go to microservices from
When you start to think about the bounded contexts that exist in your organization, you should be thinking not in terms of data that is shared, but about the capabilities those contexts provide the rest of the domain.
If our systems are decomposed along the bounded contexts that represent our domain, the changes we
want to make are more likely to be isolated to one, single microservice boundary. This reduces the number of places we need to make a change, and allows us to deploy that change quickly.
The service interface was also very chatty too, resulting in performance issues.
I called this onion architecture, as it had lots of layers and made me cry when we had to cut through it.
Getting integration right is the single most important aspect of the technology associated with microservices in my opinion.
keep the APIs used for communication between microservices technology-agnostic.
Ideally, we’d like to allow our clients full freedom in their technology choice, but on the other hand, providing a client library can ease adoption.
We don’t want our consumers to be bound to our internal implementation.
By far the most common form of integration that I or any of my colleagues see in the industry is database (DB) integration.
First, we are allowing external parties to view and bind to internal implementation details.
Second, my consumers are tied to a specific technology choice.
Strong cohesion and loose coupling — with database integration, we lose both things. Database integration makes it easy for services to share data, but does nothing about sharing behavior.
Event-based systems by their nature are asynchronous.
Event-based collaboration is also highly decoupled.
With orchestration, we rely on a central brain to guide and drive the process, much like the conductor in an orchestra. With choreography, we inform each part of the system of its job, and let it work out the details, like dancers all finding their way
The downside to this orchestration approach is that the customer service can become too much of a central governing authority.
email service, postal service, and loyalty points bank then just subscribe to these events and react accordingly, as
Synchronous calls are simpler, and we get to know if things worked straightaway.
Remote procedure call refers to the technique of making a local call and having it execute on a remote service somewhere.
This is often one of the main selling points of RPC: its ease of use.
With RPC, though, the cost of marshalling and un-marshalling payloads can be significant, not to mention the time taken to send things over the network.
This brittleness results in the types being exposed over the wire and becoming a mass of fields, some of which are no longer used but can’t be safely removed.
How a resource is shown externally is completely decoupled from how it is stored internally.
REST architectural style actually tells us that methods should behave the same way on all resources,
and the HTTP specification happens to define a bunch of methods we can use.
The idea behind HATEOAS is that clients should perform interactions (potentially leading to state transitions) with the server via these links to other resources. It doesn’t need to know where exactly customers live on the server by knowing which URI to hit; instead, the client looks for and navigates links to find what it needs.
The overhead of HTTP for each request may also be a concern for low-latency requirements.
But once it does, it can be an incredibly effective way to implement loosely coupled,
However, vendors tend to want to package lots of software with them, which can lead to more and more smarts being pushed into the middleware, as evidenced by things like the Enterprise Service Bus.
keep your middleware dumb, and keep the smarts in the endpoints.
If you already have a good, resilient message broker available to you, consider using it to handle publishing and subscribing to events.
fallacy. If you find yourself wanting more and more of the support that a message broker gives you, at a certain point you might want to change your approach.
Ensure you have good monitoring in place, and strongly consider the use of correlation IDs, which allow you to trace requests across process boundaries, as we’ll cover in depth in Chapter 8
We want to avoid dumb, anemic services that are little more than CRUD wrappers.
As you find yourself making more service calls, especially when making multiple calls to perform a single operation,
One of the things we want to avoid at all costs is overly coupling a microservice and consumers such that any small change to the microservice itself can cause unnecessary changes to the consumer.
Sometimes, however, the use of shared code can create this very coupling.