Solving Microservice Challenges
Implementing a microservice infrastructure comes with many challenges.
There are numerous factors and trade-offs to consider.
A microservice should provide the ability to run background processes and tasks.
We provide (2) two managed background processing solutions for ordered and period-defined invocation.
You can additionally use any 3rd party or built-in functions as well.
- Queue-based Service - implemented using a queue, you can queue tasks to be run in order.
- Timer-based Service - implemented using a timer, you can configure a task to run on any schedule.
- 3rd Party and Built-in .NET Core Tasks - implement Azure functions, AWS labdas, 3rd party products like Hangfire or built-in .NET Core Tasks.
A microservice should allow easy customization of its logic for development speed and maintainability.
We have create a unique, generic business rule engine that allows unprecedented customization of logic for a microservice.
Business rules allow you to "hook" into the API request pipeline of any microservice already built and customize it however you like.
A microservice should provide synchronous and asyncronous communication.
We provide (3) three communication protocols in our platform:
- Synchronous Communication - Direct HTTP/HTTPS access to each microservice using a service client. Every microservice includes a client with token-based authentication for accessing the service.
- Asynchronous Communication - We provide Service Bus integration for inter-process communication between microservies using Broadcasts. You can choose between in-memory, single receiver (Queues) or multi-receiver (Topics and Subscriptions).
- Intra-Process Communication - Our platform supports running multiple microservices on the same server.
A microservice should own all if its own data and logic.
Each microservice we develop is autonomous and independent of other Service Bricks.
This gives you the ability to design, develop, test and deploy each microservice independently.
A microservice should be as small as possible and have defined boundaries.
Similar to Bounded Contexts in Domain Driven Design, the goal of is to appropriately size each microservice based on its business domain.
You don't want any references, or as few as possible, so the underlying data model does not become fragmented over multiple services causing issues should dependencies be offline.
A microservice should provide an eventing mechanism for integration.
We provide (3) three types of eventing in our platform, all of which can be customized with our Business Rule engine:
- Broadcast (inter-process) - is an event that is sent via Service Bus using asynchronous communication to inform other microservice subsystems of a change.
- Event (intra-process) - is an event that is occurring as apart of a defined process and you want other Domain Objects to be aware of the change.
- Process (intra-process) - is an event that executes a packaged set of logic and instructions that can be customized as a whole.
A microservice should be designed in layers with each performing an area of concern for the architecture.
Our platform provides a layered design for the operation of the service as well as the release of a service.
We provide NuGet release packages for each service and each layer.
A microservice should implement a storage provider that best suits its needs.
The platform implements several on-premise and cloud-based persistent storage providers.
Each Service Brick we develop can be run on all supported storage providers.
A customized design for each storage provider is implemented that best utilizes the features of that platform.
A microservice should implement security and authorize the caller for methods it exposes.
We have implemented (2) two types of security for our platform:
- ASP.NET Core Identity - that provides authentication and authorization of requests using an industry standard.
- Token-based Security (JWT) - that provides token-based authorization of requests for member microservices.
A microservice should implement a way to query for data over the service API.
We have developed a companion product, SERVICE QUERY, that allows you to dynamically query over service boundaries.
Each storage provider implements querying data differntly.
SERVICE QUERY allows you to serialize the query over service boundaries, in a storage provider agnostic way.
A microservice should provide a mechanism for versioning its API.
We have implemented OpenAPI and Swagger for our default versioning scheme.
Both technologies provide tremendous standardization and access to versioned APIs.
Configuration for this is handled outside of the platform and can be changed or customized based on a customer's need.
The SERVICE BRICK platform was created to provide guidance and to help solve these challenges.
We have tried to templatize as much of the design artifacts needed to create a Service Brick.
Considerations for each of these challenges have been solved, implemented and documented in our further sections.