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
    • EntitySet
    • Properties
    • Associations
    • Navigation
  • 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.

SAP%20Gateway%20Service%20Enablement

SAP Gateway Service Enablement

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.

Create%20Model%20%28MPC%29

Create Model (MPC)

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.

Create%20Service%20%28DPC%29

Create Service (DPC)

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.

Assign%20Model%20to%20Service

Assign Model to Service

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

/MFND/IF_CORE_OMDO_BO_MODEL%7EDEFINE_BO_ENTITY_MODEL

/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.

Define%20entities%20in%20the%20handler

Define entities in the handler class

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.

MAIF%20Config%20Panel

MAIF Config Panel – /sap/bc/webdynpro/syclo/core_config_wb

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.

Create%20mobile%20app

Create mobile app

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.

MAIF%20Transport%20Request

MAIF Transport Request

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%20Service%20Assignment

OData%20Service%20Assignment

OData Service Assignment

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.

OData%20Mobile%20Data%20Object%20Detail

OData Mobile Data Object Detail

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.

Technical%20Model%20Info

Technical Model Info

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.

Mobile%20Application%20OData%20Model%20Detail

Entity Definition

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.

Property%20List

Property Definition

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.

Associations%20Definition

Associations Definition

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.

Referential%20Constraints%20Definition

Referential Constraints Definition

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…

Navigations%20Definition

Navigation Definition

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.

xxxxx

Select Entity Keys

IO_CONTEXT

Just like IO_TECH_REQUEST_CONTEXT in *_DPC_EXT classes

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.

Who%20does%20not%20love%20new%20syntax%3F

Who does not love new syntax?

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.

xxxxxxx

Select Entity Details

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.

FOR%20ALL%20ENTRIES%20%28FAE%29%20who%3F

FOR ALL ENTRIES (FAE) who?

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.

Same%20old%2C%20same%20old...

Same old, same old…

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.

MAIF%20returning%20the%20data%20your%20app%20asked%20for

MAIF returning the data your app asked for

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  😊

References

SAP Mobile Add-On Developer Guide: Mobile Integration Framework for SAP
https://help.sap.com/viewer/d74a5d7168f3438ab1b33c9d3bbad281/6.2.0/en-US/b4b6a78e70a71014882be7f64e204223.html

SAP Inventory Manager Configuration Guide: Accessing the Mobile Add-On for ERP ConfigPanel
https://help.sap.com/viewer/3f02d437a7d94ec88ecb2f1f5b1d687d/4.4/en-US/96d12054bc824caa869b551d335b42f6.html

SAP Asset Manager Configuration Guide: SAP Mobile Add-On for the SAP Configuration Panel
https://help.sap.com/viewer/f15c174c3c3647088d38fb220e42c006/2110/en-US/5629175b49304549b724bc838c9a72ec.html