Build a full-stack app
Build a full-stack app
This tutorial deploys the acme app end to end: a Vite front end (web) and a
Go API (api), joined by a mount so that /api/* on the front end forwards to
the API over in-process dispatch. One hyjal.toml
describes both Resources; one hyjal deploy ships them together.
Time: about twenty minutes. You need the hyjal CLI, a
logged-in session, Node.js, and TinyGo for the Go lane.
The shape
The front end is public. The API is private and reachable only through the
mount. A request to https://web--acme.hyjal.cloud/api/health lands on web,
matches the /api/* mount, and dispatches to api in-process: same origin, no
CORS, requests traced end to end.
1. Lay out the repository
2. Build the front end
Scaffold the front end under web/ and add a call to the mounted API.
The front end calls /api/health on its own origin. The mount handles routing;
the browser never sees a cross-origin request.
3. Build the Go API
Write the API under api/ as a wasi:http handler.
4. Write the manifest
Declare both Resources in one manifest. The mounts field on web forwards the
/api/* prefix to api. Marking api as public = false keeps it off the
public internet; it is reachable only through the mount.
The workdir field points each Resource at its subdirectory. See
Monorepos for larger layouts.
5. Deploy both Resources
hyjal deploy builds every Resource, uploads both artifacts, applies policy,
and flips routes atomically. The front end and API go live together.
6. Verify the mount
Call the front end, then the mounted API path on the same origin:
The API responds through the front-end origin. A direct request to the private
API endpoint is refused, because api is not public:
7. Trace a request end to end
Reload the front end and stream logs. The request to web and the dispatched
call to api are correlated.
Drawing an edge between web and api on the Board
configures the same mount visually.
What you built
- The
acmeapp: a publicwebfront end and a privateapiGo service. - A
/api/*mount joining them over same-origin in-process dispatch. - One manifest and one deploy that ship both Resources atomically.
Next steps
- Give the API a database: Connect Postgres
- Store app state without an external DB: Hyjal Tables tutorial
- Learn the mount model: Full-stack apps