Skip to content
Snapshot of the v0.6 release. Fixes and additions since then are not in it. Current documentation →

Relations

A relation field is nested as the related model’s own Retrieve type by default — the full object, Preloaded automatically:

type Book struct {
    ID       string `gorm:"primaryKey;type:uuid" goninja:"list,retrieve"`
    AuthorID string `goninja:"list,retrieve,create,update,filter"`
    Author   Author `goninja:"retrieve"` // nested as {"author": {...full Author Retrieve...}}
}

Add byid to skip that — the field exposes only the related ID instead, and its Preload never runs:

Author Author `goninja:"retrieve,byid"` // {"author_id": "..."} — no nesting, no preload

Useful when a caller only ever needs the reference, not the full related object, and the extra join/preload would be wasted work.

List and retrieve do different work

Two views, deliberately different query shapes
GET/books
List view

Returns BookList rows.

SELECT id, title, author_id
No relation preload
One lean collection query. No N+1 path exists.
GET/books/{id}
Retrieve view

Returns BookRetrieve.

SELECT book
PRELOAD author
Loads the relation only when the detail response carries it.

The distinction is generated into the output types and queries, not left to a runtime option. A list response cannot accidentally trigger one relation query per row; a retrieve response only preloads fields it actually exposes.