Step 2 of 5 Beginner 9 min

OData V2 to V4: What Actually Changes

Lesson 2 — 'OData V2 to V4' gets said like a version bump. It isn't one — the data-access API, the HTTP verbs, the date types, and the query syntax all change underneath your app. Here's what actually breaks, and what doesn't.

S
s4ready.ai Team

Prerequisites

  • Lesson 1: Your Fiori apps have a technical debt problem too

“We’re moving from OData V2 to V4” gets said in planning meetings like it’s a version bump — patch the endpoint, done. It isn’t. The data-access API your controllers call, the HTTP verbs your batch requests use, and the query syntax your $expand calls rely on all change underneath the app. Treat it like the technical migration it actually is, not a configuration flag.

What actually changes

OData V2 model versus OData V4 model in SAPUI5OData V2: getData, getObject and getProperty methods; POST with an X-HTTP-Method MERGE header for updates; Edm.DateTime and Edm.Time types; flat $expand and $filter only at the top level. OData V4: Context API replaces the data-access methods; native PATCH for updates; Edm.DateTimeOffset, Edm.Duration and Edm.TimeOfDay types; nested $expand with $select and $filter inside it.ODATA V2 MODELgetData / getObject / getPropertyPOST + X-HTTP-Method: MERGEEdm.DateTime / Edm.Time$expand/$filter: top level onlyPairs with Smart ControlsODATA V4 MODELContext API (getData/getObject removed)Native PATCH for updatesEdm.DateTimeOffset / Edm.Duration$expand can nest $select/$filter insidePairs with Fiori Elements + macros
Same protocol family, different API contract — code written against v2.ODataModel does not run against v4.ODataModel unchanged.

The practical consequence: if a freestyle app’s controllers call getData(), getObject(), or getProperty() directly on the model, that code has to be rewritten against the Context API — those methods don’t exist on the V4 model. Anything relying on POST plus an X-HTTP-Method: MERGE header needs to become a native PATCH. Any $expand that assumed only top-level $select/$filter can now — and often should — nest those options inside the expand itself, which is new V4 syntax, not an extension of the old one.

The correction that matters here too

As in Lesson 1: there’s no confirmed, official SAP deadline forcing V2 out. RAP’s OData V2 service binding is a real, currently-documented option — restricted (no deep parameters on non-standard operations, and OData V2 bindings can’t combine with RAP’s draft + ETag handling the way V4 can), but not withdrawn. So the honest framing for a client isn’t “V2 is being killed on date X” — it’s “V4 is where SAP’s own tooling investment and the unrestricted feature set both point, and V2 is the option you keep only for a specific reason, not by default.”

Try it yourself

Take one real $expand call from an existing V2 freestyle app — ideally one with a nested $filter or $select need. Write out what that same intent looks like in V4 syntax, where the nested option lives inside the $expand clause itself instead of being bolted on separately. If the app also calls getData() or getObject() anywhere, note every call site — that’s your actual V4 rewrite surface, not just the service endpoint.

Go deeper

For a full V2/V4 capability comparison table and the CDS-based backend pattern SAP recommends for new V4 services, read UI5 and Fiori Modernisation: A Technical Roadmap. For the RAP-specific V2 restrictions, see SAP’s OData V2 service binding documentation, and for a practical side-by-side, DSAG’s UI5 Best Practice: OData V2 vs V4.

Key takeaways

  • The data-access API changes: getData/getObject/getProperty are gone in V4 — code moves to the Context API.
  • HTTP verbs, date types, and $expand syntax all change — this is a real rewrite of binding and query logic, not a service-URL swap.
  • There’s still no official V2 sunset date — frame this as “V4 is the default, V2 is the constrained exception,” not a deadline.

Next: once your OData is V4, the real decision is what to build the UI in — Fiori Elements or freestyle.