Store state with Hyjal Tables

View as Markdown

This tutorial creates a Hyjal Table in the Console, reads and writes it from the api Resource through the Door, and watches Console edits appear live in your API responses. Hyjal Tables are per-Project relational tables stored in the Project Bucket, so you get app state without provisioning an external database.

Time: about fifteen minutes. You need the hyjal CLI, a logged-in session, and the acme Project with an api Resource.

1. Create a table in the Console

Open the Project in the Console and select the Tables tab. Create a table named notes with these columns:

ColumnTypeNotes
idintegerprimary key
bodytext
created_attimestampdefault now()

The grid appears empty, ready for rows. See Create tables for the full column-type reference.

2. Add a row in the grid

In the notes grid, add a row with body set to first note. The grid writes it immediately. Hyjal Tables use single-writer semantics per table group, so the Console edit and your API share one consistent view.

3. Query the table from your API

Read the table from the api Resource through the Door. The Door exposes scoped SQL over HTTP; the hyjal-db client handles the request.

1// api/main.go
2package main
3
4import (
5 "encoding/json"
6 "net/http"
7
8 "github.com/hyjal/hyjal-db-go"
9)
10
11func handler(w http.ResponseWriter, r *http.Request) {
12 db := hyjaldb.Tables() // Door client, no credentials to manage
13
14 rows, _ := db.Query(r.Context(),
15 "SELECT id, body, created_at FROM notes ORDER BY created_at DESC")
16
17 w.Header().Set("content-type", "application/json")
18 json.NewEncoder(w).Encode(rows)
19}

The Door is a host-provided capability, so there is no connection string to allowlist and no secret to set for Tables access: the platform scopes it to your Project.

4. Deploy and read the row

$$ hyjal deploy
$Building resource api (lane: go)...
$ tinygo build -target=wasip2
$Uploading artifact... digest sha256:c40a72…8db1
$Applying policy...
$Flipping route...
$
$Deployed acme/api

Call the endpoint. The row you added in the grid appears in the response:

$$ curl https://api--acme.hyjal.cloud
$[{"id":1,"body":"first note","created_at":"2026-07-13T17:10:22Z"}]

5. Watch edits appear live

Add a second row in the Console grid with body set to second note. Call the endpoint again, no redeploy:

$$ curl https://api--acme.hyjal.cloud
$[{"id":2,"body":"second note","created_at":"2026-07-13T17:12:41Z"},
> {"id":1,"body":"first note","created_at":"2026-07-13T17:10:22Z"}]

The Console grid and your API read the same table. Reads scale with the fleet, so every instance sees the write.

6. Write from the API

Writing back from the API shows up in the grid the same way. Add an insert path:

1db.Exec(r.Context(),
2 "INSERT INTO notes (body) VALUES ($1)", "note from the api")

After a request hits that path, the new row appears in the Console notes grid on the next refresh.

What you built

  • A notes Hyjal Table created and edited in the Console grid.
  • An api Resource that reads and writes the table through the Door.
  • A live loop where Console edits and API writes share one consistent view.

Next steps