api-tour

command
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 8, 2026 License: MIT Imports: 7 Imported by: 0

README

api-tour

Live demo of the v2 API surface added to the framework. One file. One DB. A graph of users → profiles, users → posts → comments.

Run

go run ./examples/api-tour
# listening on :8080

The first run creates ./api-tour.db (SQLite) and seeds two users + two posts + two comments + one profile. Re-runs are idempotent.

Things to try

Eager loading (flat + nested)
# Single relation
curl 'http://localhost:8080/posts/post-1?include=comments'

# Nested — author and the author's profile in one response
curl 'http://localhost:8080/posts/post-1?include=author.profile,comments'

# On list — every row gets the same expansion, batched into one query per
# relation regardless of result size (no N+1).
curl 'http://localhost:8080/posts?include=author.profile'

Unknown segments return 400 with the bad name in the error body, e.g. ?include=author.bogusunknown include "author.bogus".

Cursor pagination
# First page (cursor= is the sentinel that switches to keyset mode)
curl 'http://localhost:8080/posts?cursor=&limit=2'
#  → {"data":[…],"cursor":"<opaque>","hasMore":true}

# Walk the next page using the returned cursor
curl 'http://localhost:8080/posts?cursor=<opaque>&limit=2'

This entity declares CursorField: "created_at" so pages walk by recency, not primary key.

Atomic batch endpoints
# Create three posts atomically — if any fails, all roll back
curl -X POST http://localhost:8080/posts/_batch \
  -H 'Content-Type: application/json' \
  -d '{"items":[
        {"title":"A","author_id":"u1"},
        {"title":"B","author_id":"u1"},
        {"title":"C","author_id":"u1"}
      ]}'

# Same shape for PATCH (each item must include "id") and DELETE (body is
# {"ids":[…]}).

Response is always {committed: bool, results: [{index, data|error|skipped}]}. Status is 200 on commit, 400 on rollback.

SSE event stream
curl -N http://localhost:8080/posts/_events &
# In another terminal:
curl -X POST http://localhost:8080/posts \
  -H 'Content-Type: application/json' \
  -d '{"title":"Live","author_id":"u1"}'
# The first curl prints:
# event: entity.created
# data: {"type":"entity.created","data":{...},"timestamp":"…"}

Disconnecting the listener cleans up the EventBus subscription automatically.

Multipart uploads
# `users.avatar` is an Image field; multipart parts named `avatar` get
# streamed through the configured Storage and persisted as a URL string
# on the user row.
curl -X POST http://localhost:8080/users \
  -F 'name=Carol' \
  -F 'avatar=@/path/to/photo.png'

Files land under ./api-tour-uploads/. Set WithFileStorage to swap this for any upload.Storage impl (S3 etc).

Foreign-key constraints

SQLite enforces FKs only with PRAGMA foreign_keys = ON, which the example's main.go sets at boot. Try inserting an orphan post:

curl -X POST http://localhost:8080/posts \
  -H 'Content-Type: application/json' \
  -d '{"title":"orphan","author_id":"ghost-user"}'
# → 400 {"error":"insert: ... FOREIGN KEY constraint failed"}
OpenAPI
http://localhost:8080/openapi.json
http://localhost:8080/docs/

The spec describes every new endpoint (cursor params, _batch bodies, _events stream, oneOf list response).

Documentation

Overview

Package main is a tour of the v2 API surface added to the framework:

  • ?include=author.profile,comments (eager-loading, nested)
  • ?cursor=...&limit=... (keyset pagination)
  • POST/PATCH/DELETE /{table}/_batch (atomic batches)
  • GET /{table}/_events (Server-Sent Events stream)
  • multipart/form-data uploads on Image fields
  • BelongsTo FK constraints (enforced at runtime under PRAGMA on SQLite)

Run with:

go run ./examples/api-tour

Then poke at:

curl http://localhost:8080/posts?include=author.profile,comments
curl 'http://localhost:8080/posts?cursor=&limit=2'
curl -X POST http://localhost:8080/posts/_batch -d '{"items":[{"title":"A","authorId":"u1"}]}'
curl http://localhost:8080/posts/_events

The OpenAPI spec lives at /openapi.json and Swagger UI at /api/docs/.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL