This post is just a high-level view of the current hyper architecture for anyone interested. The diagram shows the separation of concerns at a module level.
Starting from the left, we have the connect module that exists on the business logic boundary, this module gives clients a couple of simple methods to establish connectivity to the hyper service.
Moving from left to right and top to bottom we come accross the API modules, express, graphql and architect. These modules focus on the api protocol to interact with the hyper meta-service framework, each module uses a different protocol, REST/JSON (stateless server), GraphQL (stateless server), and AWS Lambda (serverless architecture). Currently, the most stable module is the app-express module.
The core contains the composing of adapters by validating the adapter interface with the port schemas, using a plugin manager and providing a internal message bus so messages can be dispatched from one service to another or to our hooks service for logging and tracing.
hyper follows the ports and adapters architecture pattern, a port is a general definition or interface for a specific service. For example, a data port contains all the general methods to manage data with a service. These method are specified in the port and implemented in a given adapter. This pattern enables hyper to have many different adapters for the same port which creates flexibility as well as testability and maintainability.
Moving from left to right, we have five ports, Data, Search, Cache, Storage, and Queue ports. These ports provide the core specifications for each adapter. It should be pretty clear what each port is trying to specify.
Finally, we have adapters, these adapters or the implementation of a given port using a specific technology. We want to add more adapters over time, the more adapters the more flexibility and agility to migrate from one service to another.
“The primary feature for easy maintenance is locality: Locality is that characteristic of source code that enables a programmer to understand that source by looking at only a small portion of it.” — Richard Gabriel
hyper embraces LoB principle by separating business logic from general service functions.
Straight from the Structure of Interpretation of Computer Programs comes the concept of code separation by layers or strata. Organize your dependency chain from specialized functions to generic functions and align your use cases with a set of layers and you will create components that are cleanly organized from pieces that change most often to pieces that change least often and push the least often changes into stable modules.
(some background on stratified design — https://lispcast.com/more-about-stratified-design/)
hyper is designed to separate business logic from your backend services which results in highly maintainable and scalable applications that can go from prototype to product to future proof with an effortless transition. The result is the closest design that comes close to my favorite goal of software architecture:
The goal of software architecture is to minimize the human resources required to build and maintain the required system.
hyper through the life cycle of the product should constantly minimize the human resources required to not only build but to also maintain the application.