-
Notifications
You must be signed in to change notification settings - Fork 53
Sharing functionality or data among services
Architectural patterns manifest several ways of sharing functionality or data among their components. Let’s consider a basic example: calls to two pieces of business logic need to be logged, while the logger is doing something more complex than mere console prints. The business logic also needs to access a system-wide counter.
The simplest way to use a shared functionality (aspect) is to call the module which implements it directly. This is possible if the users and the provider of the aspect reside in the same process, as in a Monolith or module-based (single application) Layers.
Sharing data inside a process is similar, but usually requires some kind of protection, like an RW lock, around it to serialize access from multiple threads.
In a distributed system you can place the functionality or data to share into a separate service to be accessed over the network, yielding Service-Oriented Architecture for shared utilities or a Shared Repository / Polyglot Persistence for shared data.
A less obvious solution is delegating our needs to another layer of the system. To continue our example of logging, a Proxy may log user requests and a Middleware – interservice communication. In many cases one of these generic components is configurable to record all calls to the methods which we need to log – with no changes to the code!
In a similar way a service may behave as a function: receive all the data it needs in an input message and send back all its work as an output – and let the database access remain the responsibility of its caller.
Finally, each user of a component can get its own replica. This is done implicitly in Shards and explicitly in a Service Mesh of Microservices for libraries or Data Grid of Space-Based Architecture for data.
Another case of replication is importing the same code in multiple services, which happens in single-layer Nanoservices.
There are four basic ways to share functionality or data in a system:
- Deploy everything together – messy but fast and simple.
- Place the component in question into a shared service to be accessed over the network – slow and less reliable.
- Let another layer of the system both implement and use the needed function on your behalf – easy but generic, thus it may not always fit your code’s needs.
- Make a copy of the component for each of its users – fast, reliable, but the copies are hard to keep in sync.
| << Comparison of architectural patterns | ^ Comparison of architectural patterns ^ | Pipelines in architectural patterns >> |
|---|
CC BY Denys Poltorak. Editor: Lars Noodén. Download the book from Leanpub or GitHub. Generated with odt2wiki.
Analytics
Appendices
- Acknowledgements
- Books referenced
- Copyright
- Disclaimer
-
Evolutions of architectures
- Evolutions of a Monolith that lead to Shards
- Evolutions of a Monolith that result in Layers
- Evolutions of a Monolith that make Services
- Evolutions of a Monolith that rely on Plugins
- Evolutions of Shards that share data
- Evolutions of Shards that share logic
- Evolutions of Layers that make more layers
- Evolutions of Layers that help large projects
- Evolutions of Layers to improve performance
- Evolutions of Layers to gain flexibility
- Evolutions of Services that add or remove services
- Evolutions of Services that add layers
- Evolutions of a Pipeline
- Evolutions of a Middleware
- Evolutions of a Shared Repository
- Evolutions of a Proxy
- Evolutions of an Orchestrator
- Evolutions of a Combined Component
- Format of a metapattern
- Glossary
- History of changes
- Index of patterns