How to create OData Services with Mobile Application Integration Framework (MAIF)
Creating OData Services is such a trivial task in SAP. One can do it in a classic way with SAP Gateway Projects (tcode SEGW), using a more modern approach with CDS View Annotations (@OData.publish: true) or like a savage (manually creating models and services ABAP classes).
There’s another way which seems to be not so famous, probably because it’s focused on mobile applications: SAP Mobile Application Integration Framework (MAIF).
In this blog, I’m not going to dive into all configuration details nor into the mobile app code. This’ll be quite extensive just covering the basic stuff. Further details can be found in the links provided at the end. The focus here’s to create a simple OData Service with Header/Item entities and expose it with MAIF. The idea is to cover advanced features in future blogs: CRUD operations, delta tokens, offline capabilities, etc.
MAIF, as the name suggests, is used to provide APIs for communication between SAP mobile apps and SAP backends. It’s a framework which helps when creating mobile apps with special use cases such as offline data syncronization. MAIF is the tecnology behind SAP Asset Manager and SAP Inventory Manager.
Coding and configuring happen in the SAP backend server. The whole process is very similar to tcode SEGW, however, not so central and intuitive. In SEGW, one defines everything for the service (entities, properties, associations, navigation…) in the same screen and write the ABAP code afterwards. With MAIF, one could write the whole code first and do the configuration later.
What I’ll cover here:
- Create OData Model
- Create OData Service
- Create OData Mobile Data Object (oMDO) handler class
- oMDO define entities (method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL)
- MAIF Configuration Panel
- Mobile Application Configuration
- OData Service Assignment
- OData Mobile Data Object Configuration
- OData Model Configuration
- oMDO select entity keys (method GET_OBJKEYS_BY_DISTRIB_RULES)
- oMDO select entity data (method LOAD_ENTITY_DETAILS)
- Publish OData Service
Creating OData Model and Service
We’ll start creating the OData model and service. Both would be generated by SEGW, but with MAIF we need to manually create it (like a savage). From the SAP backend, run tcode SPRO and navigate to SAP Netweaver > SAP Gateway Service Enablement > Backend OData Channel > Service Development for Backend OData Channel. Maintain Models and Maintain Services will be displayed.
Go to Maintain Models (tcode /IWBEP/REG_MODEL), enter a model name (YLAUFFER_TEST_MAIF_MODEL) and version, click on Create button. Enter a Model Provider Class (MPC) and Description. You may be used to see a *_MPC_EXT class here, but that won’t be the case. Use the standard class /MFND/CL_CORE_ODATA_V2_MPC. Save it.
Go to Maintain Service (tcode /IWBEP/REG_SERVICE), enter a service name (YLAUFFER_TEST_MAIF_SRV) and version, click on Create button. Enter Data Provider Class (DPC) and Description. You may be used to see a *_DPC_EXT class here, but that won’t be the case as well. Use the standard class /MFND/CL_CORE_ODATA_V2_DPC. Save it.
After saving the service, you have to assign the model created (YLAUFFER_TEST_MAIF_MODEL) to it. Click on Assign button. A popup will show up, enter your OData model name and version. Save it.
So far so good, nothing new, except for the MPC and DPC classes.
Creating OData Mobile Data Object handler class
Next step will show how to create an OData Mobile Data Object (oMDO) handler class. Run tcode SE24 (or Eclipse, if it’s your IDE of choice) and create a new ABAP class (YCL_LAUFFER_TEST_MAIF_OD).
Click on Properties tab, click on Superclass button and enter the parent class /MFND/CL_CORE_OMDO_HNDLER_BASE. Click on Methods tab and redefine the method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL
Populate the parameter ET_BO_ENTITIES with the OData entities your class will handle. This will be used later on during MAIF configuration. Field TECH_ENTITY_TYPE is the entity name, REF_STRUCT is the DDIC Structure which contains the entity properties. Note the DDIC structure was optional in SEGW, in MAIF it’s mandatory. If your class handles parent > child entities, use the field FLAG_LEAD_ENTITY to set who is the parent entity. In this example, we’re using header and item entities. Save and activate.
Comparing with SEGW (again), one must have 1 MPC/DPC class to handle all entities in the OData Service. In MAIF, you can have multiple classes per OData Service. Actually, it’s recommended to split your entities in multiple classes. It’s easier to maintain and you’ll have more granularity when configuring them.
Note that so far the class has no relationship to the model and service created. They’re disconnected, not aware of each other.
Mobile Application Integration Framework Configuration
After creating the OData Model and Service, the oMDO handler class and exposing the entities in the method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL, you have everything needed to start configuring the OData Service in MAIF.
From SAP backend server, execute tcode /SYCLO/CONFIGPANEL to open a WebDynpro application in the browser (/sap/bc/webdynpro/syclo/core_config_wb). This’ MAIF Configuration Panel, one can say this’ pretty much the same as SEGW, but weirder.
Mobile Application Configuration
Let’s start by creating the Mobile Application which will describe your app and contain all OData Services. Click on Mobile Application Configuration link. On the left side you have all apps already available in the system (standard and custom). Click on the Create button.
Give a name to your mobile application and select type OData Application. Enter a description and the release version, if you want to. As you can see on the screenshot, there’re heaps of options to configure the application. We’ll create a simple application with OData Services, therefore everything else can be ignored. Save it. A popup will show-up asking for a Transport Request. Select one and save.
Go back to MAIF Configuration Panel.
OData Service Assignment
Now, you’ll link the mobile application to the OData Service. An application may have multiple OData Services, each service will be translated to a data storage in the mobile app. Click on OData Service Assignment link. At the left side, the Mobile Application List shows all mobile apps available in the system. Select yours and click on Change button.
Click on Assign OData Service button. Set OData Version 2.0, select the OData Service created (YLAUFFER_TEST_MAIF_SRV 0001) and flag Active. In case you want to process all of the CHANGESET operations at once ($batch), flag Defer Batch Resp. Save it.
Go back to MAIF Configuration Panel.
OData Mobile Data Object Configuration
It’s time to link the mobile application to the oMDO handler class created (YCL_LAUFFER_TEST_MAIF_OD). Click on OData Mobile Data Object Configuration link. Click on Create button.
Enter oMDO ID (YLAUFFER_TEST_MAIF) and description. Select the Mobile Application and the oMDO handler class created (YCL_LAUFFER_TEST_MAIF_OD). Because the superclass of our oMDO handler class is /MFND/CL_CORE_OMDO_HNDLER_BASE, the Process Flow has to be Standard Flow using Key List. If it was /MFND/CL_CORE_OMDO_BASIC_HNDLER, Process Flow would be Basic Flow without Key List. Process Flow determines how data is selected in the ABAP class, which methods should be used for it. Flag Enable Paging and set Paging Package Size to have pagination. Save it.
Repeat these steps to create all entities needed.
Clicking on Technical Model Info tab, it’s possible to see the entities handled by the oMDO class. The ones defined in method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL, remember?
Go back to MAIF Configuration Panel.
OData Model Configuration
Finally, everything’ll come together now. Mobile Application + OData Service + oMDO handler class. Whoever is used to SEGW will feel at home here. Click on OData Model Configuration link. Click on Create button.
Enter Entity Type Name and set the Active Flag. Select the Mobile Application, select the OData Service assigned to the Mobile Application (YLAUFFER_TEST_MAIF_SRV 0001). Select the oMDO ID which’ll handle the entity you’re configuring (YLAUFFER_TEST_MAIF) and select its oMDO Entity Type (should be the same as Entity Type Name). Enter an EntitySet Name.
Click on Property List tab, then click on Propose Properties button. A popup will open listing all fields available in the DDIC structure assigned to the entity (from method /MFND/IF_CORE_OMDO_BO_MODEL~DEFINE_BO_ENTITY_MODEL again). Just like SEGW when importing from DDIC structures. Pick the fields you want, do the changes you wish and click on Accept button. The fields listed on Property List tab are the ones that are going to be available in the service. Save it.
Click on Association & Set List tab, then click on Add Association button. Enter Association Name and the Principle Cardinality. Select the Dependent Entity Type Id and Dependent Cardinality. Enter the Association Set Name. Save it.
Unlike SEGW, associations don’t require the referential keys to be set which gives more flexibility for developers. If you want to set the referential keys, click on Referential Constraints tab, then click on Add Constraint button. Enter the keys to create the relashionship between the entities. Save it.
Click on Navigation Property List tab, then click on Add Navigation Property button. Enter Navigation Property Name and Technical Name. Select the Association just created. Save it.
All set! MAIF configuration has been completed! You “just” need to write the ABAP code to make the service relevant…
Back to the OData Mobile Data Object (oMDO) handler class
Run tcode SE24 (or Eclipse, if it’s your IDE of choice). Enter the ABAP class created (YCL_LAUFFER_TEST_MAIF_OD) and edit the class.
Because our Process Flow is Standard Flow using Key List, we have one method to select just the entity keys and another one to select the data using the preselected keys. The method to select entity keys is GET_OBJKEYS_BY_DISTRIB_RULES, this’ called in READ/GET operations. Redefine it.
Parameter IS_ENTITY_INPUT_INFO is a structure which contains the request context: entity name, filters, data payload, delta token, operation type (CRUD), etc. Parameter CREF_OMDO_DATA is an object which contains the data context, it’s responsible for the response data and error. If you have multiple entities, you may want to split the code to handle them in a cleaner way.
In this example, our custom method GET_HEADER_KEYS and GET_ITEM_KEYS will get the filters from IS_ENTITY_INPUT_INFO-FIELD_FILTERS and select only the keys from the source table. Afterwards, the selected keys will be inserted in the instance attribute TAB_BO_ENTITY_KEYS_DISTR_RULE-OBJECT_KEYLIST to be used later on. Save and activate. Repeat it for all entities the class handles.
Method LOAD_ENTITY_DETAILS is responsible for preparing the response data, this’ called in READ/GET operations. Redefine it. The parameters here are the same as in method GET_OBJKEYS_BY_DISTRIB_RULES. Therefore, we can use the same approach.
Custom method GET_HEADER_DETAILS and GET_ITEM_DETAILS will get the preselected keys from instance attribute TAB_BO_ENTITY_KEYS_DISTR_RULE. Because its data type is string, we move it to a proper variable with the correct data type for the keys. A SELECT statement will fetch data from a table using the proper keys. Last step, populate the output table with the selected data. Call method CREF_OMDO_DATA->ADD_OMDO_OUTPUT_SINGLE passing the current request entity (IS_ENTITY_INPUT_INFO-TECH_ENTITY_TYPE), request number (IS_ENTITY_INPUT_INFO-REQUEST_NO) and the reference of the selected data variable.
Publishing OData Service
The last step in this long process is to publish/activate the service in the frontend server. This is exactly the same as any other OData Service. Everybody has done, everyone has seen. From SAP frontend server, run tcode /IWFND/MAINT_SERVICE and do what you know.
Finally the OData Service can be tested. Open a browser, Postman, Gateway Client in /IWFND/GW_CLIENT or your tool of choice to test REST APIs. See the results.
My rant on MAIF
Before closing up this blog. I’d like to share my thoughts on what we’ve seen. OK, here we go. MAIF is SYCLO recycled. SAP missed a huge opportunity to build the framework on top of what they already have in SEGW. Sure it’d be a massive effort, but it’d be worth. It’d be much simpler to work with MAIF, it’d speed up the development process. MAIF configuration is way too spreadout and confusing. Look at all the steps to get a simple read only service up and running. We changed context a lot of times. From SPRO, to ABAP code to multiple WebDynpro applications and back to ABAP code… See why I didn’t want to get into advanced features and mobile SDK code?
Perhaps, it’s just myself thinking too much about DX or lacking some knowledge or missing better official documentation…
Don’t get me wrong, the end result is great! MAIF is powerful and delivery what it promises. One can build advanced and feature-rich mobile apps which wouldn’t be possible with SEGW only. And the way it handles $batch operations is much nicer 😊
SAP Mobile Add-On Developer Guide: Mobile Integration Framework for SAP
SAP Inventory Manager Configuration Guide: Accessing the Mobile Add-On for ERP ConfigPanel
SAP Asset Manager Configuration Guide: SAP Mobile Add-On for the SAP Configuration Panel
SAP Mobile Services Documentation
Great work Mauricio. This is going to be extremely helpful for anyone starting out on MAIF.
Hi, Could you please tell me how to publish a production version of Inventory manager with a new version? I am currently using Eclipse oxygen as a tool to work on Agentry editor.
Thank you Mauricio for a very details blog, this was helpful for a smooth start. Do you have any information on OData extensions in MAIF? I know we can add new entities but is it a good practice or even advisable to add new properties to STANDARD entities delivered by SAP? By using append on standard entity structures(SE11)?