Behavior Driven Development
At Apriko, we strive for a high degree of automation of customer processes, a fast market launch, and continuous improvement of our software. To ensure this in a demanding domain and complex software architecture, precise planning and consistent implementation from the outset are essential.
Reach your target faster and better: With automated code generation
Complexity is high in modern software development, especially in microservices architectures. But what do you do to avoid errors in simple and repetitive tasks? At Apriko, we rely on automated code generation to eliminate precisely these stumbling blocks. Our approach? A declarative approach that allows the developer to focus on the really essential and complex tasks.
All necessary definitions and configurations can be stored on functionally relevant entities with attributes without having to write code. All standard functions of a modern application are automatically generated by a specially developed algorithm. These include:
- CRUD operations (Create, Read, Update, Delete)
- Data Transfer Objects (DTOs)
- Registrations for Dependency Injection (DI)
- Controller including correct routes
- Additions to the Data Definition Language (DDL)
Code generation forms the basis of our REST API and enables us to implement new requirements error-free and within minutes. In this article, we will focus on automatic generation for the Order entity and show how advanced functionalities can be implemented by commands.
1. The foundation: The Order entity
This definition shows how the Order entity is structured:
- EntityCodeGeneration attribute: This attribute is the entry point for our code generator and contains the necessary information for the physical order structure and DI register.
- MutableState attribute: Defines the state in which the entity can be changed via CRUD operations.
- StrictRequired attribute: The fields OrderNumber, OrderDate and TotalAmount are mandatory fields and must always be filled in.
- UniqueKey attribute: OrderNumber field must be unique.
- NotSettableProperty attribute: The order status (State) is a read-only property that can only be changed by specific logic, e.g. commands.
2. Automatic generation of CRUD operations
Based on the Order entity defined above, the corresponding CRUD operations are generated automatically. This includes creating, reading, updating, and deleting orders in the database. In addition, the associated DTOs (Data Transfer Objects) and controller routes are created, which make it possible to integrate the entity directly into the microservice.
Automatic code generation ensures that CRUD operations are implemented consistently and according to best practices without the need for developers to spend time manually creating these standard functions.
3. Expansion by means of commands: Business logic beyond CRUD
While CRUD (Create, Read, Update, Delete) operations are at the core of many microservices applications, there are often requirements that go beyond these simple operations. Commands can be used to map such complex use cases. Commands are specific instructions that implement more complex business logic and do more than just manage data in a database. Commands are particularly useful when certain business rules or conditions must be met before an operation can be executed. Automating the generation of such commands not only reduces development effort but also ensures that implementation is consistent and error-free. The additional routes in the controller and the entries in the Dependency Injection (DI) registry are generated automatically.
Let’s take a simple example of a command confirming an order:
4. Explanation of the Command example
The OrderConfirmCommand is a simple example of expanding the business logic:
- CommandCodeGeneration attribute: This attribute defines the Confirm command called up via the route {id}/confirm. It also defines the base type of the target entity (Order) and the associated model (OrderConfirmModel).
- StatePrecondition attribute: This command can only be executed if the order is in the pending state.
- TargetState attribute: The target state after execution of the command is Confirmed.
- CheckPreconditions method: This checks whether the order has a valid TotalAmount before it is confirmed.
- ExecuteAsync method: This method sets the status of the order to confirmed.
5. Integration into the microservices architecture
The generation of commands expands the functionality of the entity and enables the implementation of specific business logic. At the same time, the necessary routes in the controller and the entries in the DI register are automatically added. This ensures that new functions can be seamlessly integrated into the existing architecture.
6. Benefits of combining the use of entities and commands
- Efficiency and consistency: Automatic generation saves time and ensures consistent implementations.
- Expandability: New business logic can be easily integrated by adding commands.
- Easier maintainability: The clear separation of standard CRUD operations and specific commands facilitates maintenance and further development of the application.
7. Conclusion
The combination of the automated generation of CRUD operations for entities and the expansion by commands provides a robust solution for developing microservices in .NET. These approaches allow us to implement both simple and complex business logic efficiently and scaleably, which allows developers to focus more on the core logic of their application. The time and consistency gained in this way contributes significantly to higher quality and maintainability of the entire code base.