Skip to content

Endpoints

When building any connected application, eventually you’ll want to call an API endpoint:

  1. to read/write some data or subscribe to changes,
  2. to run some server-side application logic.

Especially for application logic, where and how it should run depends on your app, your environment, and external requirements.

For example, for rich client-side applications - such as mobile, desktop, and progressive web apps - it is often a good idea to run inside the user’s device. It is cheap, snappy, privacy-friendly and able to run offline or on a spotty connection. That said, there are very valid reasons to not run everything in an untrusted, resource and battery-limited, hard to update sandbox.

Generally, data APIs tend to be limited-scope APIs to perform common operations on your data: read/list, create, update and delete. TrailBase provides Record APIs, which let you no-code configure such APIs over your TABLEs and VIEWs. They even allow you to subscribe to data changes in realtime.

If you require more flexibility, the following provides an overview of ways to run arbitrary logic.

There are several ways to integrate custom logic into TrailBase, however you can also run logic outside in your own backend.

Within TrailBase you have the following options:

  1. JS & TS handlers,
  2. Stored database procedures,
  3. Native Rust handlers.

TrailBase’s built-in runtime enables wiring custom HTTP endpoints using full ES6 JavaScript and/or TypeScript. For more context, check out the dedicated docs.

Unlike Postgres or MySQL, SQLite does not support stored procedures out of the box. TrailBase makes Sqlean’s user-defined functions available to fill the gap. They can be accessed from Record APIs through VIEWs or custom handlers.

The Rust APIs aren’t yet stable and fairly undocumented. That said, similar to using PocketBase as a Go framework, you can build your own TrailBase binary and register custom axum HTTP handlers written in rust with the main application router, see /examples/custom-binary.

The most flexible and de-coupled way of running your own code is to deploy a separate service in front of or alongside TrailBase. This gives you full control over your destiny: language, runtime, scaling, deployment, etc.

TrailBase is designed with the explicit goal of running along a sea of other services. Its stateless tokens using asymmetric crypto make it easy for other resource servers to hermetically authenticate your users. TrailBase’s APIs can be accessed transitively, simply by forwarding users’ auth tokens 1.

Alternatively, for more of a side-car setup you can fall back to accessing the SQLite database directly, both for data access and schema alterations2.


  1. We would like to add service accounts in the future to authorize privileged services independent from user-provided tokens or using fake user-accounts for services.

  2. SQLite is running in WAL mode, which allows for parallel reads and concurrent writes. That said, when possible you should probably use the APIs since falling back to raw database access is a priviledge practically reserved to processes with access to a shared file-system.