Dynamic Code Paths
OBP offers several building blocks for defining API behaviour at runtime - stored in the OBP database as instance configuration rather than compiled into the source code. This item explains how they fit together.
The building blocks
At the API surface layer (what URL / verb exists, who may call it):
-
Dynamic Endpoint (here) - created from a Swagger / OpenAPI file. No code. Every operation in the file becomes a live endpoint with an auto-generated Role.
-
Dynamic Resource Doc (here) - one endpoint definition plus a Scala method body compiled at runtime. The code is the handler.
At the Connector layer (how a backend system is reached):
-
Method Routing (here) - a routing rule that selects which Connector implementation serves a given Connector method (per bank, per URL pattern etc.). Pure configuration, no code.
-
Connector Method (here) - a runtime-compiled body (Scala, Java or JavaScript) for one of the existing methods of the Connector trait (e.g. getBanks, makePaymentv210, dynamicEndpointProcess). Executed when a Method Routing rule routes that method to
connector = internal. -
Dynamic Message Doc (here) - a runtime-compiled function keyed by a process name, for logic that does not correspond to an existing Connector method. Invoked from other dynamic code (or by Dynamic Entity storage operations).
Related: Dynamic Entities (here) provide runtime-defined data storage, and Endpoint Mapping (here) maps Dynamic Endpoint JSON fields onto Dynamic Entity fields.
How they compose - the paths
+--> host=obp_mock ......... returns swagger example (mock)
|
Dynamic Endpoint (swagger) --+--> host=dynamic_entity ... Endpoint Mapping
no code | -> Dynamic Entity storage (data-backed)
|
+--> any other host ......... Method Routing:
connector=rest -> HTTP proxy to backend
connector=internal -> Connector Method (code)
Dynamic Resource Doc ------------> compiled Scala handler
code at the endpoint layer |-> Connector methods (routed by Method Routing)
|-> Dynamic Message Docs (by process name)
|-> any transformation / orchestration logic
Choosing a path
- Need a quick mock of an API from its spec? Dynamic Endpoint with
host = obp_mock. - Need a data-backed CRUD API with no code? Dynamic Endpoint with
host = dynamic_entity+ Endpoint Mapping + a Dynamic Entity. - Need to pass requests through to an existing backend unchanged? Dynamic Endpoint + Method Routing with a
urlparameter (transparent HTTP proxy - no payload transformation, no credential minting). - Need transformation, authentication against the backend, error mapping or orchestration? Use code: either a Dynamic Resource Doc (code at the endpoint layer - one self-contained artifact per endpoint) or a Connector Method (code at the connector seam - keeps backend integration reusable across endpoints and swappable via Method Routing). These combine well: Dynamic Resource Docs for the API surface, Connector Methods / Dynamic Message Docs for the backend calls.
Static vs Dynamic
Static endpoints (here) are Scala source code in Git, changed via release and restart. All the dynamic building blocks above live in the OBP database of the instance: they can be created and changed in real time over the management API (or via the API Manager UI) with no code deployment and no restart, and they never require instance-specific code in the public source repositories.
Guards
Runtime-compiled code (Dynamic Resource Docs, Connector Methods, Dynamic Message Docs) is disabled unless the allow_user_generated_scala_code prop is set to true, and every creation endpoint requires its corresponding Role. Dynamic Endpoints (swagger, no code) are not affected by that prop; each generated endpoint is protected by its own auto-generated Role.