When writing applications, we often couple our valuable business logic with framework specific code. For example, when using Angular it is common to disperse business logic across services, controllers, and even directives.
This coupling generally leads to code that is difficult to reuse, scale, test, and adopt or migrate to new technologies.
In this article, I’ll show you how to use the peasy-js library to help structure your business logic in a way that makes it highly re-usable between the front and back-end parts of your app, and easily portable between different frameworks.
Disclosure: I am the author of peasy-js
Should We Stop Using Frameworks?
On the contrary, I believe these frameworks offer tremendous benefit, both on the client and server. What I am proposing, however, is to abstract our business logic into composable units by creating code that is completely agnostic of its consumers.
Separate Your Business Logic
peasy-js is a middle-tier framework that makes it trivial to whimsically swap out UI, back-end, and data access frameworks in our applications by creating business logic in a composable, reusable, scalable, and testable manner. In other words, peasy-js offers guidance in abstracting our business logic into composable units by authoring code that adheres to separation of concerns (SoC).
Wait, don’t go yet!
I know what you’re thinking, “ugh, another framework?”. Yes, peasy-js is indeed a microframework. However, chances are if we venture down the path of componentizing our business logic, we’ll end up writing our own micro framework anyhow.
Countless hours have been contributed to the design, development, and testing of peasy-js, supporting almost any workflow imaginable. With a low barrier to entry, I’m hopeful that you’ll find the small investment in learning to be well worth your time.
If however, you find that peasy-js isn’t quite for you, hopefully you’ll gain some insight into how you can implement your own business layer using some of the patterns in the framework.
The Main Concepts
Let’s check out what peasy-js offers us:
- Easy to use and flexible business and validation rules engine
- Scalability and reusability (decouples business and validation logic from consuming code and frameworks)
- Easy testability
peasy-js encompasses four main concepts. Each one is outlined below with a brief description and will be covered in more depth throughout the article.
A BusinessService implementation represents an entity (e.g. users, or projects) and is responsible for exposing business functionality via commands. These commands encapsulate CRUD and other business related functions.
The Command is responsible for orchestrating the execution of initialization logic, validation and business rule execution, and other logic (data proxy invocations, workflow logic, etc.), respectively, via the command execution pipeline.
A Rule can be created to represent a validation rule (field length or required) or a business rule (authorization, price validity, etc.). Rules are consumed by commands and can be chained, configured to execute based on a previous rule’s execution, etc. Rules can also be configured to run code based on the result of their execution.
The DataProxy is responsible for data storage and retrieval, and serves as an abstraction layer for data stores that encompass (but are not limited to) the following:
- Relational Databases – SQLite, MySQL, Oracle, SQL Server, etc.
- Document (NoSQL) Databases – MongoDB, VelocityDB, etc.
- Services – HTTP, SOAP, etc.
- Cache Stores – Redis, Azure, etc.
- Queues – RabbitMQ, MSMQ, etc.
- File System
- In-memory data stores for testing
Examples: Peasy-js in Action
Note: A simple browser example can be viewed on plnkr that covers everything discussed in this section.
Here is a sample of what it might look like to consume business logic written with peasy-js within an Angular service on the client: