Building blocks — Core Components | Part 1
When we cook a recipe, we require different ingredients like oil, butter, seeds, vegetables, spices, gas, a place to cook, and whatnot; similarly, when we plan to write a boilerplate code or a framework based on which the overall application will be developed, it requires its own set of ingredients as listed below. A proper mix of the elements (building blocks) results in well-architected boilerplate code.
A well-defined boilerplate/framework code is the key to success in developing the underlying product. This is equally true for microservice and monolith architecture.
Core components boilerplate
Environment
Every organisation has a list of steps when taking a product from the developers' local environment to production. The most common are local, dev, QA, UAT, and production.
The key attributes of the environment module are:
- A global environment object that should hold the generic environment-specific attributes
- We should be able to easily add a new environment to the application stack and create new environment-specific configurations.
- We should be able to create one or more sub-environments for every environment, i.e., we should be able to create dev1, dev2, etc., for dev if necessary.
- We should be able to configure or change configurations for each environment with ease.
- Environment-specific configurations should not reside with the Microservice code. They should be managed from an external repository or file system and bundled as part of the deployment.
- We should have a provision to extend the environmental object per product/microservice need.
Platform
Every platform has its associated nuances. i.e., A node application deployed on a server (EC2) versus on serverless (Lambda) might behave a bit differently or have some limitations due to the ecosystem it is running in.
Depending on the platform on which the microservice is running, the bootstrap code might require tweaking the application's behaviour.
A few features that should be developed as part of the platform module are:
- A global platform object that should hold the platform-specific information
- It should know the platform on which the microservice is running.
- It should hold the knowledge of the cloud provider as well.
- Provision to extend the platform object as per product/microservice custom requirement
Logging
The logging library empowers developers to log messages (plain text or JSON objects) while executing the code.
A few features that should be developed as part of the logging module are:
- It should wrap the third-party logging framework in case we are using any so that if we plan to change the framework in the future, the interfaces will not change, but the code within the wapper will change.
- It should be able to define different log levels like info, debug, warning, trace, error or fatal.
- Publish messages as per the environment configuration it is running into. This can be achieved via design.
- Publish logs asynchronously as per the appender settings.
- An appender can be used in the file system, database, or log streams.
- We should be able to change the log level on the fly in the distributed architecture without relaunching.
- It should support a log object via which the log would be published.
- Provision to extend the log object as per product/microservice need
- We should have a provision to purge the log based on the retention period
Utils
Reasonable sums of libraries are available to work with date, string, number, object, collection, JSON or YAML. But usually, a library only provides some of what a project requires. So, in a project, every developer tries to reinvent by writing their utility function or attempting to use Adhoc from different sources by adding their respective dependencies.
A few features that should be developed as part of the utils module are:
- Different utility classes for various purposes. i.e., a utility class/script for string manipulation and so on
- The utility classes should be static.
- Support to enhance this library as per the business need
Exception
When executed, a program either runs successfully or throws exceptions. An exception can be checked or unchecked. These exceptions give us insight into what might be going wrong in the application compared to the expected behaviour.
The exception module helps us define some generic exception classes, which should be used to throw any custom/business exception in the application.
A few features that should be developed as part of the exception module are:
- Predefined exception classes around generic scenarios and business exceptions
- Definitive skeleton for all exception classes
- A flag to define what should be published to third-party platforms and what not
- Support to enhance this library to create custom exception(s) as per the business need
Mapper
Standard mapper classes transform data from one object to another. This data can be from an Entity to a DTO or vice versa.
A few features that should be developed as part of the mapper module are:
- Library of transformers to transform data from one data type to another and vice versa. i.e., date to string and vice versa
- Base code around the mapper to transform source to target based on the input provided
- Support to enhance this library to add new custom transformer(s) as per the business need
Validator
Every service that interacts with an internal or external system interchanges data. A few services publish data, and others produce or transform data. The validator module can play a vital role in both scenarios.
A few features that should be developed as part of the validator module are:
- Validator library around common business scenarios
- Framework to implement and apply validators out of the box with the minimum code possible
- Utility to publish validator error via standard exception class defined in Exception module.
- Support to enhance this library to create custom exception(s) as per the business need
- Provision to use validator in the controller as well as business layer
Future Release in Building Blocks
- Database Provider | Part 2
- Configuration & Metadata| Part 3
- Key Store | Part 4
- Security Management | Part 5
- Session Manager | Part 6
- Event Management | Part 7
- REST APIs | Part 8
- Batch Processing| Part 9
- Serverless | Part 10
- Communication Library | Part 11
- File Management| Part 12
- Third-party Interface | Part 13
- Testing Framework| Part 14
- DevOps | Part 15
- Monitoring and Alert | Part 16
- to be released in phases by September…
This post is inspired by Why is Software Architecture Important?