api-surface.md 3.2 KB

The three API tiers

xly does not have one API — it has three, hosted in three independent Spring Boot services with different audiences and different operational contracts. Knowing which one you're talking to is the first step in any integration conversation.

Tier Service Context path Audience
Internal xlyEntry /xlyEntry The xly SPA itself (BACK + FROUNT). Not a stable contract for external callers.
External xlyApi /xlyApi Tenants and integrators calling xly from outside. The data-driven public API.
Inbound webhooks xlyInterface /xlyInterface Third-party systems pushing events into xly. Carries Swagger.

Each service builds to its own WAR and runs in its own JVM. They share nothing in process; they share the database, and that shared database is what makes their separation work — internal-API writes show up to external-API reads automatically because both run against the same schema.

Why three tiers, not one

Each tier answers a different question, and bundling them would sacrifice clarity:

  • Internal is large (universal CRUD over all metadata-driven modules), volatile (changes when the framework changes), and intentionally untyped (the SPA decides what to ask for, server obeys).
  • External is curated (only the endpoints integrators are allowed to use), versioned by sApiCode, and authenticated with bearer tokens — it survives across framework changes precisely because it's small and explicit.
  • Inbound webhooks receive untrusted bodies from third-party systems and route them to xly handlers. The Swagger UI lives here because that audience benefits most from interactive documentation.

What each tier looks like at runtime

  • Internal — see the five-key read. One endpoint (/business/getModelBysId) returns the entire form layout; another (/business/addUpdateDelBusinessData) writes any row in any table the metadata names. Few endpoints, generic shapes.
  • External — most calls go through /api/invoke/{sApiCode}. The sApiCode is a row in the sysapi metadata table that names the SQL template, parameters, auth requirement, and target. New external APIs are registered as data, not as code — the same data-driven thesis the framework applies to its own forms.
  • Inbound webhooks/interfaceDefine/invoke/{interfaceInvoke} receives a payload, looks up the matching handler in metadata, runs the configured SQL or stored procedure. Plus a few hard-coded receivers (/Push, /Pull, /send/sendQw) for specific partners.

Where to look next