Skip to content

HTTP Protocol ​

One endpoint, one POST per interaction, JSON both ways. The protocol is abap2UI5's own — cap2UI5 does not define it, translate it or version it independently, because the backend answering it is abap2UI5.

This page used to carry a warning. It no longer needs to.

It used to say that the page described what cap2UI5 emitted and not what abap2UI5 emitted — the two had drifted apart, and a hand-maintained port was still writing a superseded envelope. That cannot happen now: the backend and the frontend come from one upstream commit. The measurements below are from a running server rather than from a specification.

The endpoint ​

POST /rest/root/z2ui5a roundtrip
POST /sap/bc/z2ui5the same door, under its ABAP-side name
GET /rest/root/z2ui5?app_start=<APP>the HTML page that embeds the whole UI5 component — every module, view and stylesheet — boots UI5 and starts an app

There is no static frontend route: the browser needs no files from the server other than that page (UI5 itself comes from the CDN). Both paths are configurable — see Configuration.

Request ​

json
{
  "value": {
    "S_FRONT": {
      "ID": "<the draft id of the previous roundtrip, empty on a start>",
      "APP": "ZCL_JS_HELLO",
      "EVENT": "GO",
      "T_EVENT_ARG": ["red"],
      "SEARCH": "?app_start=ZCL_JS_HELLO",
      "PATHNAME": "/rest/root/z2ui5",
      "ORIGIN": "http://localhost:4004",
      "HASH": "",
      "CONFIG": {}
    },
    "XX": {},
    "MODEL": { "NAME": "Ada" }
  }
}
IDwhich draft to continue. Empty starts a new app
EVENT, T_EVENT_ARGwhat the user did, and the arguments the control carried — client.get_event() and client.get_event_arg(i)
MODELthe bound data as the browser has it; applied to the app instance before main runs

Response ​

Measured against the example, a start of ZCL_JS_HELLO:

json
{
  "S_FRONT": {
    "APP": "ZCL_JS_HELLO",
    "ID": "D46139087B1241DBBD701D4DC02F13AA",
    "PROTOCOL": 2,
    "S_ACTION": { "T_SYSTEM": [["VIEW_SLOTS", "display", "<mvc:View …>"]] }
  },
  "MODEL": { "NAME": "" }
}
IDthe new draft id — every roundtrip writes a new one and the browser carries it forward
PROTOCOLthe wire version, see below
S_ACTION.T_SYSTEMordered framework actions: render a view, open a popup, show a message box, navigate
S_ACTION.T_CUSTOMapp-issued frontend actions
MODELthe bound data as the server has it after main

S_ACTION is an ordered list, which is why two client.message_toast_display() calls arrive in the order you wrote them.

PROTOCOL — the wire carries its own version ​

S_FRONT.PROTOCOL is stamped from z2ui5_if_ui5_types=>c_protocol and the shell compares it against its own before reading anything else. It is not the product version and does not move with a release; it moves when a response can no longer be read by a frontend written for the previous number.

It exists because of exactly the failure this project hit: the S_ACTION envelope replaced an older S_FRONT.PARAMS shape, and a frontend written for the old one looked for a key the backend no longer wrote — then rendered its empty result, silently. A mismatch is now reported to the user.

A response without the field is let through: a backend older than the field cannot be told apart from one that is merely older.

For a cap2UI5 project the check is belt and braces — both halves come from one @abap2ui5/node-runtime — but it protects anyone pairing them by hand.

Errors ​

An unhandled error answers 500 with roundtrip failed (<cds.context.id>). The detail goes to the server log under the same id; see Configuration. An app module that fails to load does not get that far: it fails the server's start.

Authentication is decided before the body is read: an unauthenticated caller gets 401 with the auth strategy's login challenge, an authenticated user who lacks the configured role 403, both without the server buffering the payload. A body over the limit gets 413. These three are answered by CAP's error middleware, in CAP's error format.

Next ​

Released under the MIT License.