-
Notifications
You must be signed in to change notification settings - Fork 9
architecture doing one thing well
NOTE: This page is still being written
DISCLAIMER: This documentation refers to milestone Boda, which is currently in early stages of development. Some or all of the features mentioned here may not yet exist, or be unstable.
NWheels aims to provide reusable solution to every typical problem in enterprise application development.
At first sight, this contradicts the Do One Thing Well principle, because instead of focusing on a single problem, NWheels seeks to handle too many of them (which also smells like Overly Complex Monolith).
Indeed, this is an issue which must be addressed in the heart of the architecture.
The architecture must comprise a set of pieces, each of which does one thing well, and knows little or nothing about the others.
The composition must be done in such a way that:
- every single piece handles only one problem
- every single problem is handled by only one piece, with the exception of polymorphism
- multiple polymorphic pieces can exist, which handle one problem in different ways
This approach complies with the DRY (Don't Repeat Yourself) principle.
In order to collaborate, the pieces need to share a common framework. The goal of a framework is provide developers with a clean, consistent, and easy-to-grasp programming model.
NWheels is not one monolith framework. Out of the box, it provides multiple layered frameworks, each solving a different kind of problem. The set of frameworks is not limited to those supplied out of the box: new frameworks can be developed.
Frameworks are just another composite kind of pieces. For this reason, everything said in Composition and simplicity applies to frameworks, too.
Each framework focuses on one problem. On one side, it provides API, through which the other pieces that rely on it can accomplish their tasks and collaborate. On the other side, it comprises set of pieces that implement the API, possibly relying on technology stack modules (explained later). Polymorphic frameworks can exist, which implement the same API in different ways.
Below is the list of frameworks that are provided out of the box, in the top-down order:
- Application Framework layer: DDD (domain-driven design); Workflow; UIDL (user interface definition language).
- Platform layer: Scalability & Availability; Authorization; Sessions; Endpoints; Messaging; Caching; Localization.
- Kernel layer: Process lifecycle; Dependency injection; Meta-type system; Late compilation; Diagnostics; Configuration; Aspectization.
Multiple frameworks approach complies with the Separation of Mechanism and Policy principle. When an upper-layer framework depends on a lower-layer framework, the lower-layer framework is a mechanism, and the upper-layer framework is a policy.
NWheels does not impose the one and the only policy on application developers. Instead, it provides a layered set of frameworks, where each framework is a potential branching point for a different set of policy frameworks applied on top, or a starting point for completely new frameworks.
Aspectization framework is a mechanism for plugging pieces of logic that handle cross-cutting concerns, into every execution path of the application. The out-of-the-box Authorization framework applies policy of claims-based access control specification, on top of the Aspectization mechanism.
In a case claims-based approach doesn't fit a specific application, a different framework can be used for specifying access control rules - but the Aspectization mechanism will be fully reused for invocation of access validation logic.
If claims-based authorization was hard-coded into Aspectization framework, the entire aspectization mechanism would have to be replaced, leading to violation of the DRY principle.
Even though circumstances in which replacing a framework would make sense should be rare, following the Separation of Mechanism and Policy principle is in itself beneficial to the architecture, because it:
- Improves design, leading to stronger decomposition into orthogonal and reusable pieces
- Allows experimentation and implementation of completely new ideas and approaches, which were not initially anticipated by the authors
While frameworks define programming models for upstream frameworks and application developers, they often require an underlying technology stack in order to fulfil their responsibilities. Following the terminology of Hexagonal Architecture, frameworks have ports, and those ports require adapters to concrete technologies to be attached.
Some frameworks have no dependencies on any technologies, like the Meta-Type System framework, which fulfils its responsibilities entirely in its code. Other frameworks do have dependencies, such as DDD framework, which depends on a data persistence (ORM/ODM) technology.
It is imperative that frameworks are abstracted from concrete technology adapters. This is done by a framework defining an API for a port, and technology adapters implementing that API.
Technology adapters are captured in pluggable NWheels modules (the concept of modules is discussed in Application structure topic). Adapters are attached to ports through dependency injection.
- Doing one thing well
- High-level overview
- Microservice anatomy
- Testability
- Authorization and access control
- Scalability and availability
- Containerization and deployment
- Monitoring and analysis
- Caching, local and distributed
- Event-driven processing and reliability
- Communication endpoints
- Unobtrusive customization
- Internationalization
- N-dimensional configuration
- Support of common architectural patterns
- Kernel Layer
- Platform Layer
- Scalability & Availability Layer
- Domain-Driven Design
- Processing Workflows
- User Interface
- Data representation
- Semantic Logging & Data Collection
- Testing
- Infrastructure Domains
- Business Domains
- Database
- User Interface
- Communication Endpoints
- Scalability
- Services/Libraries
- Developer Tools
- nwheels.org powered by NWheels
- Popular communities
- Books and videos