Skip to content

Relation Setup

Relations are defined in the service options using the relations property. The convention follows feathers-graph-populate.

Configuration

ts
const app = feathers().use(
  "users",
  new KyselyService<User>({
    Model: db,
    name: "users",
    id: "id",
    relations: {
      todos: {
        service: "todos",
        keyHere: "id",
        keyThere: "userId",
        asArray: true,
        databaseTableName: "todos",
      },
      manager: {
        service: "users",
        keyHere: "managerId",
        keyThere: "id",
        asArray: false,
        databaseTableName: "users",
      },
    },
  }),
);

Relation Options

OptionTypeDescription
servicestringThe name of the related Feathers service
keyHerestringThe local column that references the related table
keyTherestringThe column in the related table that matches keyHere
asArraybooleantrue for hasMany (one-to-many), false for belongsTo
databaseTableNamestringThe actual database table name of the related entity

Relation Types

belongsTo (asArray: false)

A record belongs to one related record. The foreign key is on the current table.

Example: A user belongs to a manager (another user).

users.managerId → users.id

See belongsTo for details.

hasMany (asArray: true)

A record has many related records. The foreign key is on the related table.

Example: A user has many todos.

users.id ← todos.userId

See hasMany for details.

App Setup

If you plan to query or sort by multi-level belongsTo chains (e.g. event.assignment.customer.fullName), the adapter needs a reference to the Feathers app so it can resolve relation definitions on other services. There are two ways to provide it:

1. Automatic (via app.setup())

Feathers calls service.setup(app, path) automatically when you start the server with app.listen(). In tests or programmatic usage without listen(), invoke it explicitly:

ts
await app.setup();

2. Explicit (via the constructor)

You can pass the app as a second constructor argument — useful in tests or when you want the adapter fully wired before the Feathers lifecycle runs:

ts
const events = new KyselyService<Event>(
  {
    Model: db,
    name: "events",
    relations: {
      /* ... */
    },
  },
  app,
);
app.use("events", events);

If both are provided, the constructor argument takes precedence. Single-level queries work without either.