Once the data model is established, the next step required to define a software-based business is the data processing model. The processing model defines the set of components that will interact together in order to accomplish various business goals.
Although CodePrimer can generate any artifact, its initial implementation is taking an opinionated view on how processing should be defined and structured. It lies somewhere between the monolithic and microservices trends by liberally borrowing from each into an approach called Business Bundle.
A Business Bundle is a set of components interacting together in predictable ways with clear boundaries in order to easily model and implement a business process using the following patterns:
- A Controller exposes Resources to the outside world and turn them into Messages and/or Events.
- A Consumer consumes asynchronous Messages and turn them into Events.
- A Cron produces either Messages or Events at periodic intervals.
- An Engine acts on Events to implement Business Processes.
- A DataClient exposes an Interface to the Engine to interact with a data persistence layer, such as a database, in order to retrieve and persist BusinessModels.
- An ApiClient exposes an Interface to the Engine to interact with external systems in synchronous fashion.
- A Publisher allows the Engine to trigger Messages that can be handled by the same or other Business Bundles to trigger their other business processes.
The figure below shows how the various components interact with each other:
More details about each component can be found in the links below:
This approach to process modeling allows architects and business analysts to clearly think about the set of triggers to consider in terms of data and sources without having to worry to much about the limitations and technicalities of the technology selected.
It allows architects and business analysts to design business processes around simple questions such as:
- Is this process synchronous, asynchronous or both?
- Synchronous:
- Expose it via a Controller
- Design a
Resource
to capture the input required by the process
- Asynchronous:
- Expose it via a Consumer
- Design a
Message
to capture the input required by the process - Can it support parallel processing ?
- Yes:
- Deploy it in autoscale mode
- No:
- Deploy it in single instance mode
- Yes:
- Both:
- Apply both methods above
- Synchronous:
- Is this process accessible to the outside world (including a web or mobile application)?
- Yes:
- Expose it via a Controller to enforce user authentication and access control.
- Design a
Resource
to capture the input required by the process
- Yes:
- Is this process triggered at known intervals?
- Yes:
- Expose it va a Cron
- Is it expected to process an increasing amount of data over time?
- Yes:
- Configure it to trigger processing by sending messages to a consumer.
- No:
- Configure it to invoke the engine directly.
- Yes:
- Yes:
- Where is the data located for this process?
- Database or filesystem:
- Design and implement a DataClient to retrieve it via a set of
Entity
elements
- Design and implement a DataClient to retrieve it via a set of
- External System:
- Design and implement an ApiClient to retrieve it via
ExternalResource
elements.
- Design and implement an ApiClient to retrieve it via
- Database or filesystem:
-
Does this process update data?
- Yes:
- See Data Location section above
- Yes:
-
Can this process be the starting point of another process?
Business requirements change all the time and so does the technological components used to implement them. Therefore, a software architecture should be designed with that in mind.
Given that the Engine implements the actual business logic, if the answer to the above question changes, the impact is simple and quick to manage as we simply need to change by selecting the appropriate pattern to expose it with very minimal risk.