This section describes the layers of the back-end of the generated application. fastCode takes a pragmatic approach to code generation. In the back-end, all entities have CRUD operations (create, read, update, delete) and the boilerplate code associated with these CRUD operations repeats itself. We could have taken the approach of templatizing the entire generated application using Java Generics in order to reduce the amount of code that is generated, but the application code then becomes difficult to understand, debug, and extend because of abstraction. Therefore, for now, we have decided not to use Java Generics.
Under the domain package in the generated application, we have a package for abstractentity. In this abstractentity package, we have defined a base class for domain entities named AbstractEntity. All the domain entities extend this abstract entity.
We also have packages for each of the domain entities. Each entity either represents an independent table or a join table in a many-to-many relationship. For each domain entity, the entity class, the repository interface, and any associated artifacts such as the JPA @IdClass are created in the package for the entity.
Each entity repository interface extends the JpaRepository and QuerydslPredicateExecutor. The specific operations provided by JpaRepository are described on this page. fastCode uses Query DSL in order to support entity search operation. Details about Query DSL can be found on this page.
The application layer serves three purposes: (a) implementing the business logic (b) providing transaction support and (c) converting data transfer objects (DTOs) to entities and vice versa.
The application generator generates at least five DTOs in the application services layer of each entity. For example, for an Address entity, the following DTOs are generated.
There may be additional DTOs generated if there are additional relationship methods. For example, we have the following relationship method in the Application service for Address:
- GetCityOutput getCity(Integer addressid);
As we can see, we have an additional DTO, GetCityOutput, that is also generated.
The DTOs are mapped to entities and vice versa automatically by using a mapper. fastCode uses MapStruct, an open-source mapper product, to perform the mapping.
In addition to the DTOs, we also have three additional artifacts. An Application Service Interface, the corresponding implementation class, and a MapStruct mapper interface.
The standard set of methods in the Application Service Interface that are implemented by the implementation class for an Address entity are as follows:
public CreateAddressOutput create (CreateAddressInput actor);
public void delete (Integer id);
public UpdateAddressOutput update (Integer id, UpdateAddressInput input);
public FindAddressByIdOutput findById (Integer id);
public List<FindAddressByIdOutput> find (SearchCriteria search, Pageable
pageable) throws Exception;
There could be additional methods based on the relationship of the entity with other entities.
The mapper class defines the mappings from the Address entity to DTOs and vice-versa. We need to provide an interface and MapStruct automatically generates an implementation class.
The ReST controller layer is used to provide services to clients through HTTP URLs. A client invokes an exposed service on this layer, which then invokes the appropriate Application Layer service to process the request and return a response to the client.
In the generated application, for each entity, there is a corresponding ReST controller. Each RestController for an entity has at least the following API methods:
Create an entity
Update an entity
Delete an entity
Find an entity by Id
Boolean Search for entities
Updated 7 months ago