External API (xlyApi)
xlyApi is the API surface external integrators consume. It runs as
its own Spring Boot WAR (entry class
xlyApi/src/main/java/com/xly/ApiApplicationBoot.java) at context-path
/xlyApi, with its own application-*.yml files.
The defining design choice: most external endpoints are not hard-coded
in Java — they are rows in sysapi. New external APIs are registered
as data, like the rest of xly. The runtime's job is to look up the
sApiCode, validate the caller, and execute whatever the metadata says.
The data-driven dispatcher — /api/invoke/{sApiCode}
The single most important endpoint:
POST /xlyApi/api/invoke/{sApiCode}
Authorization: Bearer <token> (or query param ?authorizationt=<token>)
Content-Type: application/json
{ ...request body, passed through as `sBody` to the handler... }
Handler: ApiController.invoke() at
xlyApi/src/main/java/com/xly/api/web/ApiController.java.
The flow:
- Read the
Authorizationheader (fallback:authorizationtquery parameter). - Look up the
sysapirow keyed bysApiCode(viaApiServiceImpl.invoke→SELECT … FROM sysapi WHERE sApiCode = #{sApiCode}). - If the row's
bHasTokenflag is set, validate the token againstsysapithirdtoken(or the equivalent token store the row points at). - Run the SQL template stored in
sysapi.sDataSqlwith the request body merged into the parameter map. - Log the call to
sysapilog. - Return the result wrapped in
AjaxResult.
So adding a new external API is an admin/PM task: insert a row into
sysapi, supply the SQL template, set the flags, give the integrator
the sApiCode and a token. No Java code change.
sysapi columns of interest
| Column | Meaning |
|---|---|
sApiCode |
The path variable consumers send. Must be unique per tenant. |
sApiName |
Human label. |
sApiUrl / sApiUrlRef
|
Computed URL — sApiUrlRef + sApiCode — for outbound dispatches. |
sMethod |
The HTTP method this API expects (GET, POST, …). |
sHeader, sBody, sBodyNode, sBodyType
|
Templates describing the inbound request shape. |
sDataSql |
The SQL template the runtime executes. References to #{xxx} are filled from request params. |
sDataTest, sDataTestNode
|
Sample request/response used by the BACK API tester (POST /api/apiTest). |
bHasToken |
1 → require a token in Authorization; 0 → public. |
API administration endpoints
/api/list/..., /api/data/..., /api/add, /api/edit, /api/remove
are the admin surface for managing sysapi rows themselves (the BACK
"自定义接口" screen calls these). POST /api/getSqlTemple produces a
SQL skeleton for a given API name; POST /api/apiTest runs an end-to-end
dry-run against the test fixture in sDataTest.
Token endpoints — /token/*
| Endpoint | Method | Purpose |
|---|---|---|
/token/getToken?corpid=&corpsecret= |
POST | Issue a bearer token for an integrator's (corpid, corpsecret) pair. |
The token returned is what /api/invoke/{sApiCode} expects in
Authorization. The full implementation is in
xlyApi/src/main/java/com/xly/api/web/TokenController.java and its
service.
For third-party tokens that xly itself fetches (so it can call
out-of-cluster APIs on behalf of a customer), see /thirdtoken/*,
backed by sysapithirdtoken (table comment: 第三方token获取接口).
Other curated surfaces
These are smaller specialised APIs hosted in the same WAR:
| Endpoint root | Controller | Purpose |
|---|---|---|
/online/api/{sApiCode} |
OnlineController |
Read-only execution of a sysapi row (no write). Useful for public-data endpoints. |
/online/onlineword/{sApiCode} |
OnlineController |
Variant returning a "word"-style template payload. |
/online/onlinelist, /online/getToken
|
OnlineController |
Listing of online APIs and their token issuance. |
/pro/get/{sProName} |
ProContentController |
Fetch metadata about a stored procedure by name. |
/pro/getData/{sProName} |
ProContentController |
Execute the named stored procedure and return its result-set. |
/pro/alert/{redisId}, /pro/getAlertValue/{redisId}
|
ProContentController |
Read alert/notification values keyed by Redis id. |
/pro/executeSql |
ProContentController |
Execute a parameterised SQL template (admin-tier). |
/thirdparty/* |
ThirdPartyController |
CRUD over third-party-API definitions and the checkPartyApi validator. Backed by sysapithirdparty. |
/thirdtoken/* |
ThirdTokenController |
CRUD over outbound-token configs. Backed by sysapithirdtoken. |
/brand/* |
BrandController |
CRUD over the partner-supplier list (sysapibrand). |
/json/*, /json/jsonEdit/{sDomId}
|
JsonController |
JSON-tree edit helpers used by the BACK API editor. |
/interfaceDefine/callthirdparty/{interfaceInvoke} |
InterfaceController |
Dispatch an outbound call defined in sysapithirdparty. |
/gpt/chatGpt |
GptController |
Pass-through for the experimental GPT/chat surface — out-of-scope of the framework wiki. |
Backing tables (DB-level surface)
These tables hold the API metadata. All carry sBrandsId /
sSubsidiaryId for tenant scoping.
| Table | Role |
|---|---|
sysapi |
API definitions used by /api/invoke. |
sysapilog |
Per-call audit log. |
sysapibrand |
Partner / supplier directory. |
sysapithirdparty |
Outbound third-party endpoint definitions. |
sysapithirdtoken |
Outbound third-party token configs. |
sysapidbtodb |
DB-to-DB sync API definitions. |
sysapidbtodblog |
DB-to-DB sync run log. |
How an integrator uses this
A typical first integration:
-
Have an admin register your API. Insert a row into
sysapi(via the BACK self-service screen or directly): picksApiCode, writesDataSql, setbHasToken = 1if you want token auth, save. -
Get a token.
POST /xlyApi/token/getToken?corpid=<your_id>&corpsecret=<your_secret>. -
Call the API.
POST /xlyApi/api/invoke/<your_sApiCode>with the token inAuthorizationand your payload as the JSON body. -
Inspect the log.
sysapilogrecords every call, the responseiStatus, and the body. The BACK admin screen surfaces the same.
What this API is not
-
Not OpenAPI-described — the contract for any given
sApiCodeis whatever itssysapi.sDataSqlandsBodyrows say. Get the spec from the team that registered the API, not from a/swaggerendpoint here. -
Not a thin wrapper over
xlyEntry's internal API — these are intentionally separate surfaces. Calling/business/*onxlyEntryfrom outside is not supported. -
Not the inbound webhook receiver — push events from third
parties go through
xlyInterface.