Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Sagar Gupta
ServiceNow Employee
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:
Wednesday
Updated by:
Contributors