Using SAP Enterprise App Modeler to harness the capabilities of Offline OData
The SAP Enterprise App Modeler allows developers to define sophisticated applications without having to write any code. Business process experts can use the cloud-based editor to develop new applications and customize existing ones. The result is a flexible app with a beautiful user experience and powerful offline support. In this blog post, I’ll dig deeper into the last part of that description: App Modeler’s offline capabilities. I’ll give an overview of how App Modeler integrates with Offline OData to achieve constant availability and lightning-fast performance while making it simple for designers to interact with OData in their business logic.
App Modeler is designed to allow for dynamic updates while fully supporting offline use cases. Changes to the application-defining metadata are published from WebIDE to Cloud Platform Mobile Services. New versions of the metadata are deployed from Mobile Services to the client through the App Update service, which allows administrators to manage the application lifecycle without users having to reinstall. Mobile Services also provides a connection to the OData backend. The Offline OData SDK downloads some or all of the data from the backend and stores it in a local database. Users can perform local transactions, then send those changes to the backend by syncing.
App Modeler uses App Update to manage the lifecycle of application metadata and Offline OData to sync with an OData backend and facilitate offline use.
With Offline OData, the API consumer can construct OData queries just like they would for an online application. The Offline OData framework is also designed to be highly flexible and application-agnostic. Unfortunately for a business-centric user, this means there’s a good deal of complexity inherent to it. App Modeler takes care of Offline OData’s complexities so application designers can leverage its benefits easily. In what follows, I’ll focus on three problems that App Modeler solves:
- Displaying a large number of records
- Accessing fetched data in the application layer
- Grouping user transactions so they’re treated atomically
With lower-level implementation details stripped away, designers can more effectively reason about the data model, the user experience, and the relationship between the two. To illustrate, let’s take a closer look at each of these examples.
Displaying large entity sets with paging
One great benefit of offline support is that your data is not only available wherever your users go, but it’s also fetched more efficiently than in an online app. Rather than retrieving data over the network, the application can quickly get any record from the local store. Still, if your entity sets contain hundreds or thousands of records, your app has to be smart about how many records it retrieves at once. In these cases, attempting to retrieve an entire entity set could make the app sluggish or even unusable.
For example, consider a case in which a designer wants to display a list of sales orders, which are called SalesOrderHeaders in the data model. App Modeler makes this easy: Just use the editor to define a Section Page with an Object Table as its only section. Then specify the entity set to be retrieved:
The Object Table is defined to display properties of each sales order.
The SalesOrderHeaders entity set is specified using the Object Browser.
On the client, the naive solution for displaying this list would be to load all the records at once. However, if the entity set has too many records, the user experience will quickly degrade. All those records would consume too much memory and take a long time to load from the store. Luckily, OData provides a way around this: the $top and $skip query options can be used to load a subset of the entity set. For example, you can load 20 records starting with the 50th by specifying a $top value of 20 and a $skip value of 50. App Modeler makes use of this feature, which works as one would expect in Offline OData, to implement paginated lists by automatically using $top and $skip as appropriate. The result is a great scrolling experience even for massive entity sets, and without any additional effort by the designer.
An example of scrolling a large list of records in the App Modeler client. More records are loaded as the user scrolls further down the list.
Binding to fetched data using target paths
Displaying a huge number of records is an important problem to address in an offline app, but it’s not the only one that arises. We also have to consider how data from the store can be accessed and manipulated after it’s fetched. The approach has to be flexible enough that designers can express complex business logic, and it should be smart enough to only perform reads when necessary. App Modeler accomplishes this in a way that still reflects the data model with a feature called target paths. The basic idea is that once data is fetched, it’s bound to the page and can be referenced with a simple and intuitive syntax. In the list control from the previous section, the properties of each cell come from the result of a target path:
Cells are bound to entity properties using target paths.
The {…} syntax is a shorthand for the #Property target path segment, which gets properties from the entity in the current binding context. In this case, each cell is bound to a sales order entity, and each target path is accessing properties on that entity. We can also use target paths to pass values entered by the user into a create or update operation. By tapping the “+” button in the top right, we can create a new sales order.
The SalesOrderCreate page allows the user to specify properties on a new sales order.
The SalesOrderCreate page consists of a form cell container with two controls. If I make a change and tap “Save”, I’ll trigger a Create Entity Action which gets the data from those controls and uses them to add a new entity to the store. Notice how in the action definition below, each control is identified by its name, and the control’s value is assigned to the corresponding property of the created entity.
The SalesOrderCreate action scrapes the page for its values using target paths.
This simple example demonstrates how App Modeler allows designers to intuitively reason about connections between the UI and the data model. And this only scratches the surface of what can be accomplished with target paths. You can also use them to access data from other pages in the application, get the results of rules and actions, and index into records of a collection.
Group actions and fail them gracefully with change sets
OData allows backend developers to express multi-faceted relationships between entity types. Entities with an association defined can be linked according to their multiplicity, and these links are represented in the backend using referential constraint properties. For example, in the sample OData service used by our app, each sales order may have zero or many sales order items, but a sales order item must be linked to exactly one sales order.
OData Association between SalesOrderHeader and SalesOrderItem.
Developers should be able to build applications that obey the constraints from the data model: We shouldn’t be able to create an order item without an order, and it might not make sense to create an order without an item, either. Cancelling before both are created should cancel the entire operation. For cases like this, Offline OData provides a change set feature which allows users to perform multiple CRUD operations that will only be committed if they all succeed. This is useful from a data integrity perspective, but it can also lead to more complicated application logic. If the first Create Entity Action in an Offline OData change set succeeds but the second one fails, how does the application know to go back to the original page? The designer would have to carefully chain each action to the next and handle all the failure cases separately to ensure the right user experience.
Luckily, App Modeler provides its own concept of a change set which builds on the one from Offline OData. A Change Set Action is used to group several actions together. If any of them fail, the Change Set Action’s failure handler will be invoked and the chain will be short-circuited. This means that any data operations from inside the change set will be also be reverted.
Going back to the app, after we create a sales order entity, the page for creating a sales order item is displayed. This sequence is defined in a Change Set Action.
Change Set Action that combines sales order and sales order item creation.
If we cancel out of this second action, the change set is ended and the sales order we created is discarded. On the other hand, if we follow through with the item creation, both entities are created and linked. Again, App Modeler provides an intuitive way to connect the business logic with the data model itself.
As we’ve seen from these examples, App Modeler makes it easy to configure a highly performant list, to access data that’s been fetched or provided by the end user, and to define a chain of actions that’s atomic with respect to the data store and the business logic. App Modeler manages all the complexities of getting the most out of the Offline OData SDK and makes its benefits readily accessible. As you create your own apps using App Modeler, make sure to share your thoughts on how it uses Offline OData, as well as any challenges you run into along the way.
Interesting blog post Lucas. I’m wondering if SEAM is fully available for customers to use yet? Last time I tried it about a month ago the build process was failing...?
Hi Jason,
The first release of SEAM is for customizing SAP Asset Manager and early access for select customers and partners. App Modeler 2.0 is for building custom applications and is scheduled to be released for general availability in Q4 2017.
If you are looking for instructions to run SEAM on your Macbook for development and testing purposes only, please contact Sue Berry directly.
Hello Lucas Wonderley ,
Thanks for the great blog, you mentioned you were trying all the above action controls/page controls option by consuming sample mobile service, we are trying to consume the same mobile service, unable to get any data in SEAM client. when we checked in log we are getting error "retrieve of metadata failed because Odata server returned error code 403.
Please have a look at below thread which we have posted a detail log/destination configuration settings.
https://answers.sap.com/questions/353814/unable-to-add-any-new-seam-service-in-webide-full.html
Let me know if you could find any solution for this issue..
Thanks in advance,
Jana