Service Bindings Part 1: From Business Object to OData Service
Understand where a service binding fits in RAP: projection views, service definition and service binding, what each one decides, the binding types available, and how the binding turns your business object into a callable OData endpoint.
What this complete series covers
Expose the Purchase Request business object as an OData V4 service and Fiori Elements app: service definition, binding types, publishing, landscape transport, UI vs Web API, troubleshooting and UI annotations.
- Who it is for
- Best for SAP consultants, developers, and learners who want a practical understanding of Service Bindings.
- Prerequisites
- A RAP business object with a projection layer — ideally from the Managed RAP Tutorial (Parts 1–5). Basic idea of HTTP and OData helps.
- Final outcome
- You will be able to publish and test RAP services, move them safely through DEV/QAS/PRD, choose UI or Web API bindings, diagnose 404/403/metadata problems quickly, and build a Fiori Elements app with annotations.
- Part 1: Service Bindings Part 1: From Business Object to OData Service
Understand where a service binding fits in RAP: projection views, service definition and service binding, what each one decides, the binding types available, and how the binding turns your business object into a callable OData endpoint.
- Part 2: Service Bindings Part 2: Create, Activate, Publish and Test in ADT
Walk through the full hands-on flow: create and activate the binding, publish the local service endpoint, check it in the Gateway administration, and test $metadata, reads and a create — in on-premise S/4HANA and in the ABAP cloud environment.
- Part 3: Service Bindings Part 3: Moving Bindings Through DEV, QAS and PRD
Learn what is and is not transported with a service binding, the post-import steps needed in QAS and PRD, how access is granted on-premise and in the cloud, and a checklist that makes every deployment repeatable.
- Part 4: Service Bindings Part 4: UI vs Web API, OData V4 vs V2
Choose the right binding for each consumer: what really differs between UI and Web API bindings, when OData V2 is still justified, and how to build a separate non-draft API service on the same business object.
- Part 5: Service Bindings Part 5: Troubleshooting 404, 403, Metadata and Cache
Diagnose RAP service problems systematically: read the HTTP status first, then go to the right layer — publication, authorization, metadata, business logic or cache — using the right transaction for each.
- Part 6: Service Bindings Part 6: Preview, $metadata and Fiori Elements Annotations
Turn the published service into a real Fiori Elements app: add UI annotations in metadata extensions, verify them in the binding preview, read $metadata to see exactly what the UI receives, and generate and deploy the app.
System and release assumptions: Examples target recent SAP S/4HANA / ABAP Cloud capabilities. RAP, CDS, OData, and Fiori Elements syntax and tooling can differ by ABAP platform release.
Explanation
📌 KEY POINTS
✅ Chain: BO → projection → service definition → service binding → OData service.
✅ Service definition = WHAT is exposed; binding = HOW (protocol, UI/API).
✅ Expose projections (ZC_/ZA_), never base R_ views.
⚠️ One binding per protocol and consumer type.
▶ WHAT THIS SERIES COVERS
This series exposes the Purchase Request business object built in the Managed RAP series as an OData V4 service and a Fiori Elements app. You can follow it with any RAP business object, but the examples use ZR_PurchReq and its projection ZC_PurchReq (Managed RAP Part 5).
- Part 1 — the exposure chain and what a binding is
- Part 2 — create, activate, publish and test a binding in ADT
- Part 3 — moving bindings through DEV, QAS and PRD
- Part 4 — UI vs Web API bindings, OData V2 vs V4
- Part 5 — troubleshooting 404, 403, metadata and cache problems
- Part 6 — preview, metadata and Fiori Elements annotations
━━━━━━━━━━━━━━━━━━━━
▶ THE PROBLEM A SERVICE BINDING SOLVES
A RAP business object is ABAP: CDS views, a behavior definition and classes. A browser, a Fiori app or another system cannot call ABAP directly — they speak HTTP and OData. Something must decide which entities are visible, which protocol is used, and at which URL. That is the job of the last two objects in the RAP stack.
━━━━━━━━━━━━━━━━━━━━
▶ THE EXPOSURE CHAIN — FOUR OBJECTS, FOUR DECISIONS
- Business object (ZR_PurchReq + BDEF) — WHAT the data is and what can happen to it. Built once, reused by all consumers.
- Projection (ZC_PurchReq + projection BDEF) — WHICH fields and operations one consumer gets, plus UI annotations.
- Service definition (ZUI_PURCHREQ) — WHICH entities form one service, and under which names. It is protocol-neutral: it lists "expose ZC_PurchReq as PurchaseRequest" and nothing about OData.
- Service binding (ZUI_PURCHREQ_O4) — HOW and for WHOM the service is offered: the protocol (OData V2 or V4, and some other types), the purpose (UI or Web API), and the runtime registration that produces a URL.
The chain is one-directional: a binding points to exactly one service definition; one service definition can have several bindings (e.g. a V4 UI binding and a V2 UI binding during a migration).
━━━━━━━━━━━━━━━━━━━━
▶ WHAT THE SERVICE DEFINITION DOES
- Groups the root and child projections into one service. Everything the consumer navigates to must be exposed here — if ZC_PurchReqItem is not exposed, the Items navigation will not work.
- Gives each entity its external name (the entity set name in OData). Choose business-readable names; they appear in URLs and in client code.
- Contains no logic and no protocol settings.
━━━━━━━━━━━━━━━━━━━━
▶ WHAT THE SERVICE BINDING DOES
- Binds the service definition to a protocol and binding type.
- After activation, shows in ADT: the service version, the entity sets and their associations, and a Preview button per entity.
- After publishing (Part 2), registers the service in the OData runtime (SAP Gateway) so it gets a real URL, e.g. …/sap/opu/odata4/sap/zui_purchreq_o4/srvd/sap/zui_purchreq/0001/. Always copy the URL from the binding editor rather than typing it.
━━━━━━━━━━━━━━━━━━━━
▶ BINDING TYPES
- OData V4 – UI: for Fiori Elements and SAPUI5 apps. Includes UI annotations and supports draft. The default choice for new transactional apps.
- OData V4 – Web API: for system-to-system integration. No UI annotations; meant for stable programmatic contracts.
- OData V2 – UI and OData V2 – Web API: the older protocol version. Use only when a consumer requires V2 (older apps, some tools, some integration adapters).
- Some releases offer further types (for example InA for analytical queries or SQL for SQL-based access); they are outside this series.
Part 4 explains the choice in detail.
━━━━━━━━━━━━━━━━━━━━
▶ NAMING CONVENTION
A consistent pattern avoids confusion later:
- Service definition: ZUI_<object> for UI services, ZAPI_<object> for APIs.
- Service binding: the service definition name plus a suffix for protocol: _O4 (OData V4) or _O2 (OData V2). Example: ZUI_PURCHREQ_O4.
━━━━━━━━━━━━━━━━━━━━
▶ STEP BY STEP
- Make sure the projection ZC_PurchReq, ZC_PurchReqItem and the projection BDEF are active (Managed RAP Part 5).
- Right-click ZC_PurchReq → New → Service Definition. Name ZUI_PURCHREQ. Add both entities as in the code example. Activate.
- Right-click ZUI_PURCHREQ → New Service Binding. Name ZUI_PURCHREQ_O4, binding type OData V4 – UI. Activate.
- Look at the editor: the service version 0001, entity sets PurchaseRequest and PurchaseRequestItem, and the navigation between them. You will publish and test it in Part 2.
━━━━━━━━━━━━━━━━━━━━
▶ WHAT YOU HAVE AFTER PART 1
A clear mental model of the four layers and an active service definition and binding. Activation alone does not make the service callable in an on-premise system — that is the publish step in Part 2.
Code example
// ===== Service definition ZUI_PURCHREQ =====@EndUserText.label: 'Purchase Request - UI service'define service ZUI_PURCHREQ { expose ZC_PurchReq as PurchaseRequest; expose ZC_PurchReqItem as PurchaseRequestItem;} // ===== The full exposure chain for this example =====//// ZPR_HEAD / ZPR_ITEM database tables// |// ZR_PurchReq / ZR_PurchReqItem business object (CDS + managed BDEF)// |// ZC_PurchReq / ZC_PurchReqItem projection (CDS + projection BDEF + UI annotations)// |// ZUI_PURCHREQ service definition -> WHICH entities, external names// |// ZUI_PURCHREQ_O4 service binding -> HOW: OData V4, UI, published URL// |// Fiori Elements app / API client//// Service binding editor (after activation + publish) shows e.g.:// Binding type : OData V4 - UI// Service : ZUI_PURCHREQ version 0001// Entity sets : PurchaseRequest -> _Item -> PurchaseRequestItem// Service URL : /sap/opu/odata4/sap/zui_purchreq_o4/srvd/sap/zui_purchreq/0001///// Typical calls against that URL:// GET .../0001/$metadata service description// GET .../0001/PurchaseRequest?$top=10 list// GET .../0001/PurchaseRequest(RequestUUID=...,IsActiveEntity=true)?$expand=_Item// one request with items (draft-enabled key)Real project scenario
A developer finished a RAP business object and created a service definition that exposed only the root projection ZC_PurchReq. The binding activated without error, and the list page worked in preview. But the object page showed no Items section, and adding an item failed. The team spent a day checking the behavior definition and draft tables.
The cause was one missing line: ZC_PurchReqItem was not exposed in the service definition, so the _Item navigation had no target entity set in the service. Adding "expose ZC_PurchReqItem as PurchaseRequestItem;" and reactivating the definition and binding fixed it immediately.
Afterwards the team added a checklist item: every entity reachable through a composition must be exposed in the service definition.
Common mistakes
- Thinking the service binding contains logic — it only publishes; behavior lives in the BDEF, fields in the projection.
- Exposing ZR_ base views instead of ZC_ projections.
- Forgetting to expose child entities, which breaks navigation and create-by-association.
- Using technical or cryptic external names in the service definition — they become part of every URL and client.
- Choosing OData V2 for a new app out of habit when V4 is the current standard.
- Assuming "activated" means "callable" — in on-premise systems the binding must also be published.
Best practices
- Keep the chain clean: tables → ZR_ BO → ZC_ projection → service definition → binding.
- One service definition per use case (one app or one API), not one giant service for everything.
- Expose every entity of the composition tree the consumer needs.
- Use business names in the service definition and a consistent binding naming pattern (_O4 / _O2).
- Default to OData V4 – UI for new Fiori Elements apps; use Web API bindings for integrations.
- Copy the service URL from the binding editor instead of constructing it by hand.
Interview angle
Very common question: "What is the difference between a service definition and a service binding?" Answer: the service definition decides which projected entities form a service and their external names, independent of protocol; the service binding binds that definition to a protocol and purpose (OData V2/V4, UI or Web API) and registers it so it gets an endpoint. One definition can have several bindings.
Follow-ups: "What are the RAP layers from table to app?" (tables, BO, projection, service definition, service binding, consumer), and "Which binding type for a Fiori Elements app?" (OData V4 – UI, because it supports draft and UI annotations). Mentioning that activation and publishing are separate steps on-premise shows hands-on experience.
Practice this lesson
Quick check
1. Which RAP object decides whether a service is offered as OData V4 or OData V2, and for UI or Web API use?
2. The list report works, but the object page shows no Items section and adding items fails. The BO supports items. What is most likely missing?
3. A field exists in the projection but the preview shows no column for it. What is the most likely cause?
Interview questions
1. What is the difference between a service definition and a service binding in RAP? Can one service definition have several bindings?
Answer it in your own words first, then compare.
2. Your RAP list report works in preview, but the object page shows no Items section and adding an item fails. The behavior definition supports items. What is the most likely cause?
Answer it in your own words first, then compare.
Reference-verified: the steps are checked against official SAP documentation and tutorials, and object and field names in the sample code are checked for consistency. The code has not been compiled or run on an SAP system by ERPClimb. Syntax marked release-dependent varies by SAP release, so check it in your own system.
More lessons in this topic
- Service Bindings Part 2: Create, Activate, Publish and Test in ADT
- Service Bindings Part 3: Moving Bindings Through DEV, QAS and PRD
- Service Bindings Part 4: UI vs Web API, OData V4 vs V2
- Service Bindings Part 5: Troubleshooting 404, 403, Metadata and Cache
- Service Bindings Part 6: Preview, $metadata and Fiori Elements Annotations