Chenile - An introduction
Basics
What is Chenile?
Who
Intended Users
Patterns
Patterns/blue prints
Extensible
Extending Chenile
ESB
Request Pipeline
Workflows
State Management
Details
Basics
Chenile is a Rapid Application Development (RAD) framework to build Microservices using a unique industrial strength Modulith architecture in Java using Spring Boot. Chenile establishes standards, conventions and provides common services to get developers immediately productive. It enables developers to focus on functionality.
Chenile can also be viewed as a mini ESB. It decouples services from transports. You don't write code that can work only with HTTP. The same code can be accessed via multiple transports such as MQ, Kafka, batch file processing and even via MQTT for IoT devices! This makes the framework unique. We would call it as a happy amalgamation of a domain model and a message model. You come up with the domain model for your field of work. Chenile comes up with a message model that is truly transport agnostic. Now - that is teamwork!
Chenile is like a fabric. You can use it to stitch Micro services. You can write services without worrying about transports, middlewares, horizontal services, transformations etc. Chenile allows these to be seamlessly incorporated by framework architects whilst allowing developers to write functional code. Chenile de-couples deployment packages from code modules. (See [Chenile Development Model](/chenile-development.html) for more details)
Chenile is a Java Library that contains framework code. But the framework code is just the tip of the iceberg. Chenile comes bundled with a code generator that generates typical boiler plate code that conforms to a blue print. (such as a HTTP over JSON Micro Service for example). This juxtaposition of blue prints makes it incredibly powerful and productive.
Chenile separates the developers from architects. It allows architects to focus on central concerns such as:
- Standardization - standardize tech stacks (both the framework and the version to be used)
- Enforcing modular development
- De-couple horizontal concerns from functionality
- Design test harnesses to enable extensive testing
- Enable automatic logging, observability, caching etc. for some or all services without touching service code!
- Enable internationalization from day One
- Introduce a service registry where all the service metadata is stored in one place. Chenile needs to know about all the services since it knows how to intercept them and invoke them.
- Design message formats, generic responses, exception handling etc.
- Design the structure of code repositories, devOps and build practices etc.
Users
Are you an early stage startup who wants to focus on developing industrial strength services using well established patterns without wasting time to research on the optimal tech stack or browsing through reams of documentation? If yes, Chenile can help you there
Are you a Spring Boot developer who is able to write code but struggle with best practices? Chenile can recommend specific frameworks and tell you to integrate them into your application. It generates stub code that you can use to write your functionality.
Are you a big enterprise who finds it hard to standardize the tech stack or patterns? Chenile can help you with that. Chenile can be completely customized and made to integrate seamlessly with in-house frameworks as well which makes it a great framework to build all standardization efforts.
Are you a software developer who would like to leverage multi-module maven builds? Chenile has you covered!
Are you looking for an offline solution - for example an ecommerce POS(Point of Sale)? Chenile has patterns to develop this solution.
Patterns & Blue Prints
Chenile encapsulates our learning from multiple projects from many years. It distills this knowledge into established patterns. We wrote supporting code to allow developers to implement these patterns. We wrote code generators that create stubs that developers can then use to implement functionality. By using Chenile documentation, libraries, patterns and code generators, developers can produce industrial strength code on day one. Not on day 180!
Chenile identifies common usecases that can be solved - eg. developing microservices, creating 'mini-monoliths' (more on this later) etc. These use cases become Chenile blue prints. Code generators help in generating code that conforms to these blue prints. Chenile is first and foremost an accelerator to design a complete micro services ecosystem using Modulith principles.
Do you want to use CQRS? Chenile has its own blue print to develop modulith services using the CQRS pattern.
Our workflow , query and interceptor blue prints are easy to understand and ship with documentation. These are generated by the code generator
Extensible
The central core of Chenile is tiny. All the features are created as a customization of the tiny core. An org can override any part of Chenile for its specific needs. Chenile provides multiple extension points - at the org level, at the service level and even at the service method (operation) level.
We love SOLID principles. The framework is built to be extensible. Every part of Chenile is designed to be extensible. It is possible to change the request processing of Chenile. It is trivial to write new blue prints and integrate with chenile. It is easy to introduce new transports. It is the simplest to write new interceptors. Best of all, the code generator can be customized to generate code compliant to these blue prints.
Chenile also ships with configurable options for most of its features. These can be used to extend the framework and customize the services. The whole of the framework is metadata driven. The metadata model is extensible. This means that you can add to the metadata without tampering with chenile-core.
Lightweight ESB (Enterprise Service Bus)
Chenile started out as an embedded Enterprise Service Bus (ESB). The idea was to de-couple service functionality from transports. Services implement functionality. Trasports merely expose the services to the outside world. Our services can be invoked via HTTP, Kafka, MQ, MQ-TT etc. without any changes to the central infrastructure code. Chenile provides an ability to do last-mile interception. This de-couples horizontal concerns from functionality. Last mile interception allows orgs to push a lot of horizontal functionality (such as routing, caching, logging, auditing etc.) out of services without needing to invest in expensive customization in the API Gateway layer. Chenile does recommend a robust API Gateway as an excellent upstream interception layer for HTTP requests to access the services. However, it is hard to customize API Gateways. Further, API Gatewys are mostly fine-tuned for HTTP. What if you want to implement caching across transports? In addition to that, certain concerns such as transformation must be handled close to the services and therefore make an excellent concern that could be implemented in the last mile.We wanted to make this last-mile interception work in a transport agnostic manner i.e. it should work across HTTP, KAFKA, message queues etc. By doing so, we wanted to re-use the pipeline across transports.
Chenile ships with interceptors that could implement important horizontal concerns such as transformation, caching, exception handling etc. Integrting new frameworks is a cinch. It is completely modularized and is true plug and play. So it becomes trivial to introduce Chenile extensions to integrate with any in-house or open source or even COTS (Commercial off the Shelf) offerings.
The pipeline code is super extensible. Chenile supports a Domain Specific Language (DSL) to customize the pipeline.
Chenile also supports its own super-flexible exchange object. It also introduces a Generic Response object that could communicate errors, warnings etc. back from the service layer
Chenile State Machine
Chenile supports a state machine to automate workflows and event sourcing
State machines can be attached to stateful entities i.e. entities that contain a state field. The state field determines what events (which often translate into UI actions) are applicable to these entities in that state.It is possible to store additional metadata for the state. This can be used in the program.
For example, an order can transition from an Opened to "In Process" to "Fulfilled" to "Closed" states. As it marches through these states, the order can be mutated in interesting ways using "events". These events depend on the state of the order. Upon receipt of an event, the order can transition to another state or stay in the same state.
The Chenile state transition machine (STM) allows these states and transitions to be configured externally using a State Transition Diagram (STD). A workflow engine navigates through the STD and calls registered handlers for every event that occurs to the state entity. In the Order example, the STM calls appropriate handlers when the order transitions from the Opened to the the "In Process" state for example.
The STM supports event sourcing as well.
See state transition machine for more information.
Features
Last Mile
Implement horizontal services in the last mile.
i18n
Integrated and enforced out of the box.
Chain of Responsibility
Flexible, highly configurable, modular command framework that implements a chain of responsibility
Error Handling
Internationalized error messages. Support for Warnings.
Transport Agnostic
Introducing a new transport for Chenile is trivial. Enabling a service for a new transport needs nothing more than a configuration update!
Externalized Service Configuration
Chenile acts like a service registry.It stores service metadata that drives behavior.
Builds + Version Management
Version control management, Docker builds. Default makefiles
Message Model
Generic response. Transport agnostic exchange object
BDD
Cucumber integrated. BDD & full HTTP black box testing supported out of the box. Customized Gherkin.
Why another framework?
This is all cool.. but doesn't Spring Boot already provide these ?
We agree that Spring Boot is an awesome ecosystem. In fact, we like it so much that we built Chenile on top of Spring Boot! Spring Boot is not opinionated. This is good because it caters to different use cases. Chenile seeks to impose certain opinionated standards on Spring Boot development. These standards cover a gamut of things - from simple naming conventions to recommending certain design paradigms to standardizing how Maven must be used etc.
These standards are automatically incorporated in Chenile Micro services if the Chenile code generator is used. For example, it takes less than 5 minutes to generate a Spring Boot micro service that does the following:
- Have a multi module Maven project which separates development concerns from deployment and implements the Dependency inversion principle (DIP) of SOLID
- Supports multiple transports - HTTP being one of them
- Adheres to established naming conventions
- Generates Swagger docs and other files that allow us to document this service in a service registry
- Adheres to established ways of implementing a work flow or CQRS or any of the other Chenile blue prints
- Incorporates horizontal concerns seamlessly
- Uses standardized exception handling
- emits a response in one standard format with provision to return exceptions, errors and warnings
- Uses international message bundles
- Implements test cases with a sophisticated Cucumber test harness and a standardized Gherkin language
- Facilitates versioning strategies and builds a CI/CD pipeline
- incorporates observability
- and much much more.
This obviates the need for developers to wade through endless documentation, stack overflow pages and sift through multiple opinions. In short, you have more time to implement functionality without worrying about semantics, best practices etc. (which you will also eventually learn by looking at Chenile's documentation)
In short, Chenile makes you productive on day one instead of waiting for months!
<EOF> END of hard sell. Phew! Now let us take a deep breath and get back to writing some cool programs using Chenile!