10 Key points for designing robust NetWeaver OData services
Based on my experience in modelling and implementing NetWeaver OData services, I have felt that one should always keep in mind below pointers while undertaking the realization of any OData service.
Based on the catered use cases, Service design and implementation should scrutinize the below points –
1. How is the exception handling done.
Technical exceptions should be used for those methods which have been decided not to be implemented but some how the UI call invokes them & Business exceptions for Business Layer validation failures. We should create custom exception classes inheriting from the CX_DYNAMIC_CHECK and CX_STATIC_CHECK classes.
2.How is data layering done and separation of concerns done.
We should always deliver decoupled applications which interact with each other via a common agreed upon interface. Generally, a delegator or process manager class is used to funnel the UI calls which invokes OData methods to proper Business Layer classes. After that BL classes interact with the Database Layer classes.
3. Any explicit commit work, auth checks, changeset handling?
Special care should be taken to avoid any explicit commit work statement in changesets. Also all/none or partial processing should be designed after understanding the use case at hand. Generally, authorization checks are implemented in the constructor of the Process Manager or Delegator.
4. Using which oData parameters is the data extracted – latest or obsolete ones?
Always latest non-obsolete parameters should be used for data extraction and processing as they offer extensive capabilities and are getting improved continuously.
5.Modelling and supported operations?
Generally there are multiple approaches to achieve any functionality and best fit design is one which keeps in mind performance and message communication.
Example – When reading multilevel parent child data instead of relying on the default framework handling, redefinition of *Expanded_Entity/EntitySet should be done, In case of multiple operations messages should be communicated once for all to UI, etc.
6. Static code or dynamic code for navigations.
The implementation of Expanded Entity and Expanded Entityset should be generic to only trigger the associated data fetch which is invoked from UI at the current instance of time.
7. Adequate validations at oData and backend layers
Always and I mean always validations should be put in backend layers irrespective of the fact that whether UI layer has any. Also only necessary data should only be passed back to UI from backend via OData layers and nothing extra should be transmitted.
8. ETags and locks?
Based on implemented use cases and criticality of business process, only ETags (optimistic concurrency control), only SAP Locks (pessimistic concurrency control) or both should be used. Design should be evaluated from this perspective as well.
9. Performance and data size which is passed to backend.
The five golden principles aka five performance guidelines hold true here.
10. Don’t pass unnecessary parameters & check naming convention.
Care should be taken that any irrelevant parameters should not be modelled. The less the number of parameters the more likely the app is designed for specific role keeping the design guideline of 3-3-1 in mind. Any system parameters should never ever be passed from UI to backend.
Please comment if you need any detailed discussion on any of these. Also, would love to add your pointers to this collated list. Feedback as always is most welcome.
Thanks Ankit for the blog. I was thinking from the new application programming perspective where we talk about CDS,SADL,BOPF etc how does these guidelines fit in? CDS is the next level paradigm whoch everyone needs to understand in detail. I believe the points which you have highlighted are coming from your custom OData developments without using CDS etc.
Thanks for the feedback.
Yes, most of the points are applicable for custom OData implementations without CDS, SADL and BOPF. Still, the framework support for various use cases using out of box functionlaity of new programming model is limited (and evolving) and we mix some of these concepts with the new CDS based annotated OData services to achieve the solution. Also, in cases where we want to override the standard functionality we make use of these. Moreover, with advent of OData V4 model, some of these might be updated a bit but they still hold the guard with principally correct design (my thought).
Furthe I am yet to realize complex scenarios via new programming model so can't comment much on that for now.
Thanks for writing this blog.
However, I find it a little too generic (For the matter of fact, I could omit OData from the title and most of the sections would still be valid).
May you add some specific (and technical) details regarding each point?
Thanks for the feedback.
Below are some details for few pointers -
2. We usually model as below -
<.....DPC_EXT> ~> <......PROCESS_MGR> ~> <.....BL> ~> <.....DB>
3. Generally Commit work statement should not be used and if necessary only at changeset_end method. If used in between, it will dump.
4. Like IT_FILTER_SELECT_OPTIONS, etc. We should read data from IO_TECHNICAL_CONTEXT instead. ( I don't recollect exact names now, but in signature they are marked as Obsolete.)
5. As above
7. This is needed beacuse in case the security of apps is compromised, data does not get corrupted because validations are not only implemented on the frontend but in the backend as well.
10. This relates to the modelling of OData services. Fiori design guideline mentions that a good app should have 3(max) screens - 3 clicks(max) - (to achieve) 1 requirement. In cases where mass data needs to be transmitted, we can look into sending Htbrid OData or JSON-OData to backend.
Please let me know if you more details on any and would try to bring it.
Can I change filter value using IO_TECHNICAL_CONTEXT or other interfaces?
These parameters are just importing ones which propagate the front end data to the backend. They cannot be changed.
What's your use case ?
My task is to get the remains in stocks at the date. In backend i am using CDS for selecting all stocks and their descriptions. And then I added the empty field stockDate to CDS fields, to display stock date in ListReport template as smartFilterBar. IN SEGW i am using DataModel->Reference->DataSource(My CDS).
When user run ListReport and enter stockDate, this filter transmitted to GW and then to CDS, and data is not selected.
I need to clear an unnecessary filter.
You can try clearing the filters in SET_QUERY_OPTIONS method of DPC_EXT class.
Thanks, Ankit. I will try it