Documentation

How-to guides

Recipes for a task you already know you want done: the steps, the code, and nothing else.

  • Create a CRUD app

    The shortest path from an empty directory to seven working routes over a Postgres table. If you'd rather have each step explained, the two tutorials your first…

  • Write a handwritten route

    Mount a page or an endpoint from a file under app/, read what the request carries, and answer it.

  • Take over one of the seven derived routes

    Replace a derived page with one you wrote and keep the other six, or remove an action from a resource altogether.

  • Mount routes under a prefix

    Serve part of the table under /admin, with the pages' own links, forms and redirects moving with it.

  • Change the schema

    Add, rename or drop a column or a table, and get the change into every database the application runs against.

  • Configure the database connection

    Tell the application where its Postgres is, size the pool, and keep several applications apart in one database.

  • Add authentication

    Put a login page in front of routes, decide per action who may take it, and scope a model's rows to their owner. Adding sign in walks through the same steps…

  • Add a live component

    Embed server-held, self-updating state in an ordinary page with no JavaScript of your own. A live page, from nothing is the long version.

  • Share state between live pages

    Make two browsers converge on one value with a Topic, and keep handle honest while they do.

  • Call an external API from a live component

    Do slow work off the page thread and patch the outcome in when it lands.

  • Refuse a request, recover from one, answer your own errors

    Three things a handler does with a failure: throw a refusal, map its own exception to a status, or recover inside a transaction. Failures is the one-page model…

  • Test an application

    Drive the route table in a unit test, boot against a real Postgres, and test a live component as plain functions.

  • Run a job instead of a server

    An application on the database layer alone, whose boot is a unit of work over rows: run once, on a schedule, or by a cron.

  • Log through Logback instead of java.util.logging

    Swap the logging backend eezo, Jetty and HikariCP share by default for Logback, without ending up with two providers on the classpath.

  • Deploy

    Ship an application to Fly.io with one command, from a laptop or from CI, and what to change for a live application, a custom domain, or another host. The…