Virtual URLs
Publish REST endpoints without code, with a generated OpenAPI document.
A Virtual URL maps an HTTP method and a path template to ordered steps on your entities:
- Kind: select, insert, update or delete.
- Criteria and Data use tokens from the path, query string, body or earlier steps, such as
{path.id}or{steps.vendor.Id}. - OutputTemplate shapes the response.
Calls run under the caller's own permissions, can be pinned to a release with X-Release-Id, and update or delete steps refuse to run without criteria. GET /api/virtualurls/openapi returns an OpenAPI 3.1 document for the app's endpoints.
See the Virtual URL API.
What a Virtual URL is
A Virtual URL is a named, versioned endpoint served under /vu/ on your TechAppForce environment. Each one maps a method (GET, POST, PUT or DELETE) and a path template, such as /companies/{id}, to a list of steps. Each step is a select, insert, update or delete on one of your app's objects, run through the platform's record layer (the same path workflows use), within the tenant and app of the request.
Use Virtual URLs when a bespoke frontend or an integration partner needs a small, stable API shaped for its job, rather than the platform's generic record endpoints.
Define an endpoint
A definition names the method, the path template and an operation id, lists the steps, and says how to build the output. This one creates a company from the request body and returns its new id:
{
"method": "POST",
"pathTemplate": "/companies",
"operationId": "create-company",
"steps": [
{
"kind": "insert",
"entity": "Companies",
"assignTo": "company",
"data": { "Name": "{body.name}", "HCode": "{body.hcode}" }
}
],
"outputTemplate": { "id": "{steps.company.Id}" },
"requestSchemaJson": "{\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\"},\"hcode\":{\"type\":\"string\"}}}",
"responseSchemaJson": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"}}}",
"isPublished": true
}Binding values
Any value in a step's criteria or data can be a binding token; anything else is a literal.
{path.x},{query.x}and{body.x}read from the request.{steps.<name>.<field>}reads the result of an earlier step, by the name given in itsassignTo.- A select step yields
data(the rows),totalandfirst; an insert yields the newId; an update or delete yields its criteria andok.
The optional request and response JSON Schemas describe the endpoint's contract; they are what the OpenAPI document is built from. Definitions can be authored through the platform's Virtual URL authoring API or by TAFI through its gateway.
Calling an endpoint
Callers authenticate with a TechAppForce bearer token, like any other platform call. Query-string values, path segments and a JSON body (for POST and PUT) all become inputs. Every response uses the same envelope:
// Success: HTTP 200
{ "success": true, "output": { "id": "..." }, "errors": [] }
// A step failed: HTTP 500
{ "success": false, "output": {}, "errors": ["..."] }
// No published endpoint for that method and path: HTTP 404
{ "error": "No published virtual URL for POST /companies" }From a TypeScript app, the client SDK's Virtual URL client wraps this: call returns the output and throws when the response reports success: false, and callRaw returns the whole envelope.
Versioning with releases
Each definition can belong to a release. A caller selects the version with the X-Release-Id header; without it, the development definitions answer. That lets a production client stay on the version it was built against while you change the endpoint in development, and move to the new version when the release is promoted. In the client SDK, setting releaseId in the configuration sends the header for you.
OpenAPI and a typed client
The platform generates an OpenAPI document from your published definitions, using each endpoint's operation id, parameters and schemas. Hand it to partners, load it into your API tooling, or generate a typed client from it with the SDK's taf-vu-codegen command:
taf-vu-codegen --in openapi.json --out src/api/client.tsThe generated file exports a createApiClient factory with one typed method per operation, named from the operation id, so create-company becomes createCompany:
// vu is a Virtual URL client created from the SDK core
const api = createApiClient(vu);
const { id } = await api.createCompany({ name: 'Northwind', hcode: 'NW-01' });
const companies = await api.listCompanies({ search: 'North', page: 1, limit: 20 });Before you start
Enable Virtual URLs on your environment. Virtual URLs are provisioned once per environment. Ask your TechAppForce contact to confirm they are enabled on the environments you plan to use before you build a frontend on them.
- Keep endpoints small and purpose-built. Business rules belong in the objects' hooks and lifecycles, so they apply however a record is changed.
- Publish a definition only when it is ready; unpublished definitions are not routed and return 404.