Sagar Gupta
ServiceNow Employee

When you build ERP-style extensions, it’s common to have data and logic running in SAP (or any OData-compatible backend) and workflows running on ServiceNow. In my case, I used SAP Cloud Application Programming (CAP) to expose an OData V2 service. Then I wired it to ServiceNow using a small SAPUI5 app that communicates with both the CAP OData endpoint and the ServiceNow Table API.


In this blog, I’ll walk through a simple end-to-end example so you can adapt it for your own ERP Canvas or custom apps.

Prerequisites

  • Basic familiarity with CAP (Node.js flavor).
  • A ServiceNow instance with a table you can write to (or a POC table).
  • SAPUI5 or Fiori tooling (Business Application Studio, VS Code with UI5 tooling, etc.).

Scenario Overview

The architecture has three main pieces:

  1. CAP service

   - Exposes an OData V2 endpoint

   - Contains an entity for CRUD example

  1. ServiceNow Table API

   - REST endpoint to insert records to ServiceNow table

  1. UI5 App (Bridge)

   - Uses CAP OData as default model

   - Uses JSON model to call ServiceNow REST API

Goal: Post records into CAP OData and ServiceNow from a single UI.

 

STEP 1 – Create and expose your CAP OData service

  • Initialise project:
    cds init cap-odata-servicenow
    cd cap-odata-servicenow
    
  • Define a simple data model in db/schema.cds:
    namespace demo;
    entity Products {
      key ID          : UUID;
      Name            : String(111);
      Description     : String(255);
      ReleaseDate     : Date;
      Price           : Decimal(9,2);
      Rating          : Integer;
    }
    
  • Expose it via service in srv/service.cds:
    using demo from '../db/schema';
    service CatalogService {
      entity Products as projection on demo.Products;
    }
    
  • Enable OData V2 compatibility (optional but useful when integrating with tools expecting V2):
    npm install /cds-odata-v2-adapter-proxy

 

Wire the adapter into your server.js (or equivalent) so that V2/OData/OData.svc serves the V2 endpoint.

  • Run the CAP app locally

    cds watch

URL generated (example): http://localhost:4004/V2/OData/OData.svc/

 

STEP 2 – Create UI5 app and consume both systems

Next, create a small SAPUI5/Fiori app. In my project, the manifest defines two data sources:

  •   serviceNowService – the CAP OData V2 endpoint.
  •   mainService – the ServiceNow Table API.

An excerpt from manifest.json looks like this:

"dataSources": {
  "serviceNowService": {
    "uri": "/V2/OData/OData.svc/",
    "type": "OData",
    "settings": {
      "annotations": [],
      "localUri": "localService/serviceNowService/metadata.xml",
      "odataVersion": "2.0"
    }
  },
  "mainService": {
    "uri": "/api/now/table/sn_hr_core_saps4hanapoc_import",
    "type": "REST"
  }
},
"models": {
  "": {
    "dataSource": "serviceNowService",
    "preload": true,
    "settings": {}
  },
  "serviceNowRest": {
    "type": "sap.ui.model.json.JSONModel",
    "uri": "/api/now/table/<table_name>"
  }
}

A few key points:

  • The default model ("") is an OData model bound to serviceNowService (your CAP OData service).
  • The serviceNowRest model is a JSONModel pointing to the ServiceNow Table API endpoint.
  • This lets the same app talk to both systems: OData via the default model and REST via the JSON model.

STEP 3 – Controller logic to POST data

In the main view controller (View1.controller.js), I implemented two handlers:

  1. onPostOData – Posts a new Products entry to the CAP OData service.
  2. onPostServiceNowRest – Posts an HR import row to the ServiceNow table via REST.

Here is the core logic (simplified) from View1.controller.js:

onPostOData: function () {
  var oModel = this.getView().getModel(); // default OData model
  var oEntry = {
    Name: "New Product",
    Description: "Sample Description",
    ReleaseDate: "/Date(1622505600000)/",
    Price: 99.99,
    Rating: 5
  };

  oModel.create("/Products", oEntry, {
    success: function (oData, response) {
      MessageToast.show("Product created successfully! (Status: " + response.statusCode + ")");
    },
    error: function (oError) {
      var statusCode = oError.statusCode || (oError.response && oError.response.statusCode) || "Unknown";
      MessageToast.show("Error creating Products. (Status: " + statusCode + ")");
    }
  });
},

 

This is enough for a working E2E proof of concept:

  • Click “Create Product” → data goes to CAP OData.
  • Click “Create HR Import Row” → data goes to ServiceNow Table API.

STEP 4 – Run UI and verify

  1. In your XML view, add two buttons and bind them to the controller methods:
    <Button text="Post to OData" press=".onPostOData" />
    <Button text="Post to ServiceNow" press=".onPostServiceNowRest" />
    ​
  2. Run the UI5 app (e.g. npm start or via ui5 serve depending on your tooling).
  3. Open the app in the browser and try both buttons:
    • Validate that CAP receives and persists the Products record.
    • Verify in ServiceNow that a new row was inserted into your table.

Once this works locally, you can deploy:

  • CAP service → SAP BTP (or another Node runtime).
  • UI5 app → wherever you host your Fiori/UI5 apps.
  • Ensure the URLs and destinations are adjusted accordingly.

STEP 5 – Extending into ERP Canvas

In more advanced scenarios, you can:

  • If you want to create/read/update data in SAP using an exposed OData v2 endpoint, use Zero Copy Connector for ERP to model operations over the CAP OData service (for example, using a “Model creation using OData Service” pattern similar to other ServiceNow guides). ServiceNow
  • Use the CAP OData service as your SAP-side abstraction and the ServiceNow Table API as your workflow/case-management side.
  • Keep your CAP logic focused on data & business rules, and let ServiceNow handle approvals, tasks, and notifications.

The simple UI5 bridge shown here is mainly for:

  • Prototyping end-to-end flows.
  • Testing connectivity and payloads.
  • Providing a reference for how CAP OData and ServiceNow REST can be used together.

Tips:

  • Use OAuth/credentials for ServiceNow securely
  • Add error logging when scaling production use
  • Maintain consistent field mapping between SAP ⇆ SNOW

 

Conclusion

We successfully connected the CAP OData service with ServiceNow using a UI5 application.  This flexible architecture enables bi-directional integration, real-time data operations, and plug-in to ERP Canvas or automation frameworks. This serves as an excellent boilerplate for larger projects.

Version history
Last update:
a month ago
Updated by:
Contributors