RAP - Projection
In this article, we'll rebuild our example a bit and add the typical projection layer used to render the app.
Table of contents
To keep things simple, we had previously worked without a projection layer, instead working directly with the RAP Business Object so you could see the impact and usage. EML uses the level of the interface layer for access, but the projection plays an important role for the app.
Background
Why do we need another projection on our actual data model? The projection makes the actual business object available to the outside for a special case or an app. It is possible to further restrict the functions, since the full range of functions may not be required for the app or API. Different projections can thus be built on a RAP business object and made available to the user.
Consumption View
In this step we create the consumption view above the interface view. To do this, you can right-click on the Core Data Service "ZBS_I_RAPPartner" to create a new data definition. This automatically prefills the reference object. We'll use the Define Projection View pattern for this, so we only need to adjust minimal parts:
In the new view we again allow the extension via annotation (@Metadata.allowExtensions: true) and activate the Core Data Service. You will notice that there is still a warning message that refers to an addition. We still need an optional PROVIDER CONTRACT, which defines the behavior of the projection and offers various functions for the different scenarios. For our simple case "transactional_query" is sufficient, this describes the simple app for editing. The full view now looks like this:
@EndUserText.label: 'RAP consumption for partner'
@AccessControl.authorizationCheck: #NOT_REQUIRED
@Metadata.allowExtensions: true
define root view entity ZBS_C_RAPPartner
provider contract transactional_query
as projection on ZBS_I_RAPPartner
{
key PartnerNumber,
PartnerName,
Street,
City,
Country,
PaymentCurrency
}
Metadata Extension
In the next step we now move the metadata extension from the interface view to the consumption layer. To do this, you simply create a metadata extension by right-clicking on the consumption view. After moving the content, the old extension can be deleted and the addition can be deleted from the interface view. We add a UI annotation to the new extension at the very beginning:
@UI: {
headerInfo: {
typeName: 'Partner',
typeNamePlural: 'Partners'
}
}
The additional "HeaderInfo" provides a corresponding text in the list and on the detail screen so that the user receives information about the data. Whether singular or plural is decided and output based on the data after the selection.
Behavior
In addition to the projection layer on the Core Data Service level, a projection for the behavior definition must now also be created. Again, this is very easy to do by right-clicking on the model's Consumption View and creating a new behavior implementation.
The fields and texts are pre-assigned accordingly and you do not have to enter any further information. It is particularly important that Projection is preselected in the lower part. After completion of the generation, the most important elements have already been adopted:
projection;
strict;
define behavior for ZBS_C_RAPPartner alias Partner
{
use create;
use update;
use delete;
}
Less information needs to be stored in the projection of the behavior definition than in the interface; this is primarily about the inheritance of the CRUD operations and actions to the outside. For example, if you delete the DELETE operation, then the service generated from it cannot be deleted.
Service
We then swap the interface for the projection in the service definition and use the same alias. In addition, we generate an OData v2 service with the corresponding UI annotation and test the app using the Elements Preview. The OData v4 was able to display the app, but the change or create actions did not work and we would have to prepare a lot more.
Let's now create a new data record by jumping to the detail display via the Create button:
At the end we filter the result using the search fields and see the newly created data record in the list:
Conclusion
The projection layer enables further limitations of the functions and information that we want to give to the outside with the app. If we need an app for the clerk (creating, changing) and one for the admin (with deleting), we can do this using two projections on the RAP business object.