Relationships

Most mock servers hand you disconnected data. Akuma understands relationships, so a post's author is a real author that actually exists in the database.

Reference a schema as a type

Give a property the type of another schema and Akuma creates a relationship. It adds a foreign key column and seeds it with valid IDs from the referenced table.

schemas:
  Author:
    properties:
      id: number
      name: string
      email: string

  Post:
    properties:
      id: number
      title: string
      body: string
      author: Author      # creates authorId -> authors.id

What Akuma does

CREATE TABLE posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT,
  body TEXT,
  authorId INTEGER,
  FOREIGN KEY (authorId) REFERENCES authors(id)
);

Foreign key naming

By default a foreign key is camelCase (authorId). Set naming.foreignKeys to match your house style. This affects only the generated FK columns; your other columns keep the names you write.

naming:
  foreignKeys: snake_case    # camelCase (default) | snake_case | PascalCase
Styleauthor: Author becomes
camelCase (default)authorId
snake_caseauthor_id
PascalCaseAuthorId

Tip: tables are always snake_case (line_items), so snake_case foreign keys give a fully snake_case database.

Seeding order

Akuma seeds tables in dependency order: referenced tables first. Authors are created and seeded before posts, so by the time a post needs an authorId, real authors already exist to point at.

curl http://localhost:3000/posts
# => [{"id": 1, "title": "Example 1", "authorId": 2}, ...]

curl http://localhost:3000/authors/2
# => {"id": 2, "name": "Example 2", ...}   <- authorId 2 is real

A complete example

Authors, posts, and comments: two relationships, fully wired:

schemas:
  Author:
    properties:
      id: number
      name: string

  Post:
    properties:
      id: number
      title: string
      author: Author      # postId-side FK: authorId -> authors.id

  Comment:
    properties:
      id: number
      post: Post          # creates postId -> posts.id
      text: string

endpoints:
  - path: /authors
    method: GET
    response:
      type: array
      schema: Author

  - path: /posts
    method: GET
    response:
      type: array
      schema: Post

  - path: /comments
    method: GET
    response:
      type: array
      schema: Comment

Notes

See Data models for schema basics and Endpoints for serving them.

Common mistakes

A relationship column collides with a property

A relationship already adds an id column, so author: Author creates authorId. Declaring a separate authorId property collides, and Akuma refuses to start:

Error: Schema 'Post' produces a duplicate column 'authorId' from properties 'author' and 'authorId'. Relationship properties get an 'Id' suffix (e.g. `author` -> `authorId`), so rename one of them.

A typo in the type silently becomes text

A relationship is detected only when the type exactly matches a schema name. A typo (author: Auther) is not a relationship; it becomes a plain text column, with a warning:

Schema 'Post' property 'author' has unknown type 'Auther'; treating it as text.