Skip to Content

Create a Simple OData Service with Mobile Back-End Tools

0 %
Create a Simple OData Service with Mobile Back-End Tools

Create a Simple OData Service with Mobile Back-End Tools

July 30, 2021
Created by
March 31, 2021
Create and deploy a simple OData Service with SAP Mobile Services, mobile back-end tools (MBT) using the CSDL graphical modeler.

You will learn

  • How to use graphical editor to create your OData model
  • How to deploy an OData service with SAP Mobile Services, mobile back-end tools
  • How to create an app router and configure login
QR code

The mobile back-end tools is a set of tools that enable a developer to model an OData service and generate a Java EE web application to implement the OData service, along with automatic creation of the necessary database tables within a pre-existing database schema.

In this tutorial, you will rebuild a small part of the GWSAMPLE_BASIC OData service publicly available on the SAP Gateway Demo system (ES5), using the MBT graphical modeler in SAP Business Application Studio. In further tutorials you can therefore extend, connect and build an app on top of it.

Step 1: Create metadata file in SAP Business Application Studio
  1. Launch the Dev space in SAP Business Application Studio.

  2. Assuming you start from your projects folder, select FileNew Folder.

    Name the folder MBTEPMDemoService.

    Select FileOpen, select the folder, and click Open.

  3. Select ViewFind Command.

  4. Type MBT and select MBT: New OData CSDL document (metadata) and press Enter.

    Command selection
  5. Answer the prompts with the following values:

    Prompt Value
    Choose OData version 4.0
    Schema namespace
    Namespace alias name Self
    Metadata file name metadata.csdl.xml

The command creates a blank metadata file for you that you can now open and edit with the graphical editor.

Log on to answer question
Step 2: Add entities to the OData service

In the end of this step, the content of the CSDL file is linked, so you do not have to build all the properties. Anyway you are encouraged to create complex type, entities, some properties and especially the association yourself in Graphical Modeler.

  1. Having complex Types selected, click the + button to add a new complex type with name CT_Address

    New complex type
  2. From Complex Types, select the type CT_Address and click + to add the following properties:

    Name Type Max Length
    AddressType String 2
    Building String 10
    City String 40
    Country String 3
    PostalCode String 10
    Street String 60
    Complex type properties
  3. Having Entity Types selected, press the + button to add a new entity type with name BusinessPartner

    New entity
  4. Select the entity and click + to add the following properties:

    Name Type Max Length
    Address CT_Address
    BusinessPartnerRole String 3
    CompanyName String 80
    LegalForm String 10
    PhoneNumber String 30
    FaxNumber String 30
    EmailAddress String 255
  5. Repeat sub-step 3 and 4 for the entity SalesOrder and the following attributes. Tick the checkbox nullable for the marked properties.

    Name Type Max Length Nullable
    Note String 255 tick
    NoteLanguage String 2 tick
    CustomerID String 10 tick
    CustomerName String 80 tick
    CurrencyCode String 5 tick
    GrossAmount Decimal Precision: 16, Scale: 3 tick
    NetAmount Decimal Precision: 16, Scale: 3 tick
    TaxAmount Decimal Precision: 16, Scale: 3 tick
    LifecycleStatus String 1 tick
    LifecycleStatusDescription String 60 tick
    BillingStatus String 1 tick
    BillingStatusDescription String 60 tick
    DeliveryStatus String 1 tick
    DeliveryStatusDescription String 60 tick
    CreatedAt DateTimeOffset tick
    ChangedAt DateTimeOffset tick
  6. Having BusinessPartner selected, click + and add the Navigation to SalesOrders with the following properties:

    • Tick Navigation and Collection
    • Name: ToSalesOrders
    • Type: SalesOrder
    • Partner: ToBusinessPartner

    This will create the association as well as the bi-directional navigation properties.

    Animation create relationship

You can also open the CSDL file as XML document instead of the graphical editor - either by clicking Switch Editor (icon) button in the top left corner of the graphical modeler or by right-clicking the file → Open withCode Editor. This is especially helpful if you want to import parts of existing models or perform advanced changes which exceed the graphical modeler’s capabilities.

Click to expand to see the full CSDL file.

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="4.0" xmlns:edmx="" xmlns:xsi="" xsi:schemaLocation="">
    <edmx:Reference Uri="">
        <edmx:Include Namespace="Org.OData.Core.V1" Alias="Core"/>
        <Schema Namespace="" Alias="Self" xmlns="">
            <ComplexType Name="CT_Address">
                <Property Name="AddressType" Type="Edm.String" Nullable="false" MaxLength="2"/>
                <Property Name="Building" Type="Edm.String" Nullable="false" MaxLength="10"/>
                <Property Name="City" Type="Edm.String" Nullable="false" MaxLength="40"/>
                <Property Name="Country" Type="Edm.String" Nullable="false" MaxLength="3"/>
                <Property Name="PostalCode" Type="Edm.String" Nullable="false" MaxLength="10"/>
                <Property Name="Street" Type="Edm.String" Nullable="false" MaxLength="60"/>
            <EntityType Name="BusinessPartner">
                    <PropertyRef Name="BusinessPartnerID"/>
                <Property Name="Address" Type="Self.CT_Address" Nullable="false"/>
                <Property Name="BusinessPartnerID" Type="Edm.Int64" Nullable="false"/>
                <Property Name="BusinessPartnerRole" Type="Edm.String" Nullable="false" MaxLength="3"/>
                <Property Name="CompanyName" Type="Edm.String" Nullable="false" MaxLength="80"/>
                <Property Name="FaxNumber" Type="Edm.String" Nullable="false" MaxLength="30"/>
                <Property Name="LegalForm" Type="Edm.String" Nullable="false" MaxLength="10"/>
                <Property Name="PhoneNumber" Type="Edm.String" Nullable="false" MaxLength="30"/>
                <NavigationProperty Name="ToSalesOrders" Type="Collection(Self.SalesOrder)" Partner="ToBusinessPartner"/>
            <EntityType Name="SalesOrder">
                    <PropertyRef Name="SalesOrderID"/>
                <Property Name="BillingStatus" Type="Edm.String" Nullable="true" MaxLength="1"/>
                <Property Name="BillingStatusDescription" Type="Edm.String" Nullable="true" MaxLength="60"/>
                <Property Name="BusinessPartnerID" Type="Edm.Int64" Nullable="false"/>
                <Property Name="ChangedAt" Type="Edm.DateTimeOffset" Nullable="true" Precision="7"/>
                <Property Name="CreatedAt" Type="Edm.DateTimeOffset" Nullable="true" Precision="7"/>
                <Property Name="CurrencyCode" Type="Edm.String" Nullable="true" MaxLength="5"/>
                <Property Name="CustomerID" Type="Edm.String" Nullable="false" MaxLength="10"/>
                <Property Name="CustomerName" Type="Edm.String" Nullable="true" MaxLength="80"/>
                <Property Name="DeliveryStatus" Type="Edm.String" Nullable="true" MaxLength="1"/>
                <Property Name="DeliveryStatusDescription" Type="Edm.String" Nullable="true" MaxLength="60"/>
                <Property Name="GrossAmount" Type="Edm.Decimal" Nullable="true" Precision="16" Scale="3"/>
                <Property Name="LifecycleStatus" Type="Edm.String" Nullable="true" MaxLength="1"/>
                <Property Name="LifecycleStatusDescription" Type="Edm.String" Nullable="true" MaxLength="60"/>
                <Property Name="NetAmount" Type="Edm.Decimal" Nullable="true" Precision="16" Scale="3"/>
                <Property Name="Note" Type="Edm.String" Nullable="true" MaxLength="255"/>
                <Property Name="NoteLanguage" Type="Edm.String" Nullable="true" MaxLength="2"/>
                <Property Name="SalesOrderID" Type="Edm.Int64" Nullable="false"/>
                <Property Name="TaxAmount" Type="Edm.Decimal" Nullable="true" Precision="16" Scale="3"/>
                <NavigationProperty Name="ToBusinessPartner" Type="Self.BusinessPartner" Nullable="false" Partner="ToSalesOrders">
                    <ReferentialConstraint Property="BusinessPartnerID" ReferencedProperty="BusinessPartnerID"/>
            <EntityContainer Name="Com_sap_mbtepmdemoService">
                <EntitySet Name="BusinessPartnerSet" EntityType="Self.BusinessPartner">
                    <NavigationPropertyBinding Path="ToSalesOrders" Target="SalesOrderSet"/>
                <EntitySet Name="SalesOrderSet" EntityType="Self.SalesOrder">
                    <NavigationPropertyBinding Path="ToBusinessPartner" Target="BusinessPartnerSet"/>


Log on to answer question
Step 3: Generate and run the service
  1. Log in to Cloud Foundry and follow the prompts to select your organization and space by clicking on the home button in the lower-left corner.

    CF Login
  2. Select ViewFind Command (or press Shift + CTRL/CMD + P).

  3. Type MBT and select MBT: Create tasks.json file.

  4. In the input dialog, confirm the options as given in the following table:

    Important: Replace the application name <subaccount><space> with a string actually representing your BTP sub account and space, e.g. d00xxxxxtrialdev:

    Prompt Value
    Generate odata service for Cloud Foundry Yes, Cloud Foundry
    applicationName <subaccount><space>MbtEpmDemoService
    application version 1.0.0
    Generate odata service with Spring Boot style No (Java EE style)
    Select database type H2 Database
    Target folder where generate odata service Keep Default
    Do you want to add MTA support No

    Make sure to not use underscores in the application name

    The selected database type will be corresponding, explicit database for the MBT OData service. For the sake of simplicity, for this tutorial’s purpose an embedded H2 database type is used, which is not supported for productive use.

  5. In the last step of the wizard, an Open File dialog comes up. Locate metadata.csdl.xml file from your workspace and click Open Metadata.

    SAP Business Application Studio Wizard
  6. Select TerminalRun Task and select the task csdl-to-war to generate, deploy and run the service to your space. You can observe in the Terminal if the run was successful.

    Deployment log
  7. If you want your service to load test data, you can switch TEST_MODE to true. Therefore you execute task csdl-to-war-test or edit the variable in file from your workspace at the path

    You can also edit the generated test data inside the folder srcmainresourcestest-data. The test data is stored in the .json files. You will have to re-run the build task csdl-to-war again to reflect this change.

    Test Mode and Test Data

In case you struggle on generating the service, you might find the documentation helpful.

Log on to answer question
Step 4: Configure authentication and app router

If the service shall be accessible independently and authentication is required, an Authorization and Trust Management Service (XSUAA) service binding as well as an app router will be required for your OData service. If you are looking for more details of this service, you might want to go through Secure a Basic Node.js App with the Authorization and Trust Management Service (XSUAA) tutorial and its references, already covering the same for another application type.

  1. Open the file tasks.json from folder .vscode and uncomment the line "-login", "XSUAA", in every of the configurations as shown below.

    Uncomment for XSUAA security

    Due to this change, after generating the service again it will not only require XSUAA authentication, but also create a default xs-security.json file.

  2. To update the project and generate the file, select TerminalRun Task and select the task csdl-to-war.

    In your workspace a file xs-security.json will appear that contains two basic roles: Everyone (for users) and ViewMetrics (for administrators). Use this file to create a service instance via Terminal in the next sub-step.

    If you do not find the file, try to close and re-open tasks.json file. This will refresh the file system cache. Then re-run the task.

  3. Select TerminalNew Terminal and type the following after the $ character.

    Important: In the snippet below, replace <subaccount><space>MbtEpmDemoService with your actual application name which is defined in tasks.json or manifest.yml.

    This will be the service instance name and should look like e.g. d00xxxxxtrialdevMbtEpmDemoService-xsuaa.

    cf create-service xsuaa application <subaccount><space>MbtEpmDemoService-xsuaa -c xs-security.json
    Create XSUAA service instance from the console

    The service will require an app router to handle authentication for it. The following sub-steps will show you how.

  4. Select a file in project root – e.g. metadata.csdl.xml – then select FileNew Folder and name it approuter.

    The file selection is only intended to make sure the folder is created in the project root.

  5. Right-click the folder approuter in your workspace and select New File for two files package.json and xs-app.json with the content below.

      "name": "approuter",
      "dependencies": {
        "@sap/approuter": "*"
      "scripts": {
        "start": "node node_modules/@sap/approuter/approuter.js"
      "routes": [{
        "source": "^/",
        "target": "/",
        "destination": "odata"
    Create new files
  6. Find out application route for your deployment via deployment log. When scrolling up the terminal log after executing the task csdl-to-war, you can find the application route as in the screenshot below. Mark and copy it to your clipboard, then save it somewhere for later as it will be required for the next sub-step.

    Find application route in logs

    The application route is the same that you can also obtain when investigating on your application in SAP BTP Cockpit, within your space.

  7. Finally, the app router and XSUAA service binding need to be reflected for deployment. You can achieve this by adding them to the manifest.yml that was generated in your workspace.

    • Initially, your manifest.yml should look like this, just having a different application name instead of <subaccount><space>MbtEpmDemoService.

      - buildpack: sap_java_buildpack
        name: <subaccount><space>MbtEpmDemoService
        path: target/odata-service-1.0.0.war
          TARGET_RUNTIME: tomee7

    When inserting these snippets, pay attention to the indentation of the lines, as YAML is indentation-sensitive. Before pasting, make sure that your cursor is set to beginning of an empty line.

    Hint: You can indent multiple line back or forward by selecting them and pressing (Shift + TAB) or (TAB) on your keyboard.

    • To bind the XSUAA service instance, add the following lines, replacing <subaccount><space>MbtEpmDemoService with your own application name:
          - <subaccount><space>MbtEpmDemoService-xsuaa
    • To also reflect your app router, add the following lines, adjusting the URL path to what you copied in the last sub-step. Don’t forget to replace <subaccount><space>MbtEpmDemoService with your actual application name in all the instance names.
      - name: <subaccount><space>MbtEpmDemoService-approuter
        path: approuter
          - nodejs_buildpack
        memory: 128M
          - <subaccount><space>MbtEpmDemoService-xsuaa
          destinations: >
                "forwardAuthToken": true
    Animation - adjust manifest.yml

    Important: Temporarily, do not execute csdl-to-war tasks anymore, as those might remove the destination in manifest.yml. Instead use cf push from Terminal.

    Hint: Make sure that the service name bound to both application as well as app router exactly match the name you defined in sub-step 3 when you created the XSUAA service instance via terminal.

    Click to expand - for reference please see the following manifest file content.

    • Each occurrence of d00xxxxxtrialdevMbtEpmDemoService must be replaced with your application name

    • The URL must be changed to reflect your application route.

      - buildpack: sap_java_buildpack
        name: d00xxxxxtrialdevMbtEpmDemoService
        path: target/odata-service-1.0.0.war
          SET_LOGGING_LEVEL: '{odata: TRACE, sap.xs.console: TRACE, sap.xs.odata: TRACE}'
          TARGET_RUNTIME: tomee7
          - d00xxxxxtrialdevMbtEpmDemoService-xsuaa
      - name: d00xxxxxtrialdevMbtEpmDemoService-approuter
        path: approuter
          - nodejs_buildpack
        memory: 128M
          - d00xxxxxtrialdevMbtEpmDemoService-xsuaa
          destinations: >
                "forwardAuthToken": true

  8. Execute cf push from Terminal to deploy everything including the binding defined in manifest.yml


    Congratulations! You have successfully created a standalone OData service and are now ready for client development. Alternatively you can continue customizing it into a cache database.

Which statements about MBT-based OData service are correct?

Next Steps

Back to top