Skip to Content
Technical Articles
Author's profile photo Martin Grasshoff

How to enable RESTful services for offline synchronization – Part 2


recently, around February 2019, I published a blog post about how to wrap any RESTful service into an OData service that can be used in an offline mobile use case. (Link to Part 1).

Now, after a couple of month, it’s time for an update. We released a new version of our Mobile Back-end Tools which renders the explained approach obsolete. You can now achieve the same much easier.

The idea is that you can now map any RESTful services (it may also be another OData service) in a declarative way instead of a pure coding approach. In addition, the new approach is also offering a data-staging area.

This is how the solution architecture will look like:

In this picture the petstore API would be on the “REST” service on left-hand side. You see that also JCO/RFC connections can be called from your OData Service as well as JDBC to relational Databases. Some limitation apply when doing this through Cloud Connector, but if you deploy your OData service locally you can directly connect to a database.

To build such an architecture you need to define:

  • OData Service Model (via CSDL) using the Mobile Back-end tools
  • Provide a DB and define it’s connection properties in the project
  • Define a destination (in this case the Swagger petstore API)
  • Annotate the Service Model with information about the petstore API – this is the “mapping”)

Here’s a complete example:

<?xml version="1.0" encoding="utf-8" ?>
<edmx:Edmx xmlns:edmx="" xmlns:edmx4="" xmlns:m="">
    <edmx:Reference Uri="vocabularies/">
        <edmx:Include Namespace="" Alias="SQL" />
    <edmx:Reference Uri="vocabularies/">
        <edmx:Include Namespace="" Alias="Cache" />
    <edmx:Reference Uri="vocabularies/">
        <edmx:Include Namespace="" Alias="HTTP" />
    <edmx:DataServices m:DataServiceVersion="2.0">
        <Schema Namespace="mbtdemo" xmlns="">
            <EntityType Name="Pet">
                <Annotation Term="Cache.RefreshBy" String="loadAll" />
                <Annotation Term="HTTP.Destination" String="petstore" />
                <Annotation Term="HTTP.Request" Qualifier="loadAll" String="GET /findByStatus?status=available">
                    <Annotation Term="HTTP.ResponseBody">
                        "id": "${entity.PetID}",
                        "name": "${entity.PetName}",
                        "status": "${entity.Status}"
                    <PropertyRef Name="PetID" />
                <Property Name="PetName" Type="Edm.String" Nullable="true" MaxLength="200" />
                <Property Name="PetID" Type="Edm.Int64" Nullable="false" />
                <Property Name="Status" Type="Edm.String" Nullable="true" MaxLength="20" />
                <Property Name="NewColumn" Type="Edm.Int32" Nullable="true" />
            <EntityContainer Name="MbtdemoService" m:IsDefaultEntityContainer="true">
                <Annotation Term="SQL.CacheDatabase" />
                <Annotation Term="SQL.TrackChanges" />
                <EntitySet Name="Pets" EntityType="mbtdemo.Pet" />


On the top you can see that I have added some vocabularies. This is to define the namespace of available annotations.

In the next step “Pet” entity was annotated with additional information:

  • Cache Refresh
    Here we define the how and when Pets should be loaded. “loadAll” says that this cache is updated for all entities of Pets. Other option would be “loadPartition” which enables to load the cache on a subset of Pets
  • Http.destination defines where the back-end is located. In our case it is
  • Http.Request is where it gets interested. Here we map the “loadAll” to a specific HTTP GET request GET /findByStatus?status=available
  • The http.ResponseBody is now mapping the API response to the Pet OData entity

Later in the service definition I also annotated the EntityContainer with:

  • SQL.CacheDatabase¬†which enables the whole architecture
  • SQL.TrackChanges which enables OData Delta tracking

Prerequisite is for this to work is that you use a real database and do not use the InMemory DB of Mobile Back-end Tools.


Once you deploy this model into action you will be able to access the petstore through your own, cached back-end with the complete OData feature set like:

  • /Pets?$filter=PetName eq ‘Dog’

I think this is a significant improvement of what I have done in Part 1 of this blog.


Have fun,


Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Javier Andres Caceres Moreno
      Javier Andres Caceres Moreno

      Good article

      Author's profile photo rihab ouaslati
      rihab ouaslati

      Hello Martin,

      First of all thank you for this article (and the previous one) .

      I actually have a question concerning the annotation of the HTTP.Destination.

      in that annotation do you have the put the url link or can you define a global destination in your SCP

      connectivity-> destinations and only put its name in the annotation ?

      If that's the case if i'm using a "OAuth2ClientCredentials" authentification type , does it have

      reprecussions on my data ?


      Thank you,