8. Run and verify
This chapter brings the service up and walks through a checklist that proves each earlier chapter works.
Environment
export RIVERBASE_DB_URL="postgres://riverbase:<password>@127.0.0.1:5432/riverbase"
export RIVERBASE_BUS_URL=$RIVERBASE_DB_URL # Postgres LISTEN/NOTIFY; use NATS in production
cargo build --workspace
Migrate only
Apply framework and domain migrations without starting the server:
cargo run -p todo-service -- --migrate-only
DomainRuntime::from_config runs the framework migrations (riverbase_audit and friends), and the
domain's spawn runs its own through the store spec. Each crate tracks its migrations in its own
schema, so domain and framework migrations never collide.
Run
cargo run -p todo-service
The service listens on bind_addr (default 0.0.0.0:8080).
The fully wired service
Putting chapters 2 to 7 together:
let mut app = RiverbaseApp::init("Todo Service", "Todo command and query API")?;
let runtime = DomainRuntime::from_config(app.config()).await?;
let domain = TodoDomain::<PgDataStore>::spawn(&runtime).await?.into_arc();
if RiverbaseApp::migrate_only() {
return Ok(());
}
app.with_casbin_known_roles(["todo-admin", "todo-user"]); // policy from [riverbase.casbin]
app.mount_domain(domain).await?;
app.mount_auth_routes().await?;
app.mount_auth().await?;
app.serve().await?;
Checklist
1. Command
curl -s -X POST "http://127.0.0.1:8080/api/riverbase.todo/create-todo:post/todo" \
-H "content-type: application/json" \
-d '{"payload":{"title":"Getting started"}}'
Expect JSON with an id.
2. List and item
curl -s "http://127.0.0.1:8080/api/riverbase.todo/todo.list"
curl -s "http://127.0.0.1:8080/api/riverbase.todo/todo.item/<id>"
Expect the new row in the list envelope, then on its own.
3. Custom route
curl -s "http://127.0.0.1:8080/api/riverbase.todo/health~probe"
Expect ok. A 404 means the domain was mounted with mount_coupled.
4. Auth
curl -s "http://127.0.0.1:8080/api/auth/info" # 401 anonymous
curl -s -H "Authorization: MockAuth-$CLAIMS" "http://127.0.0.1:8080/api/auth/info"
5. Casbin
As alice (todo-admin), create and list succeed. As an unprivileged user, command routes return
403 AUT-003.
6. OpenAPI
curl -s "http://127.0.0.1:8080/api/openapi.json" | head -c 400
The document lists every command, query, and merged OpenAPI route. GET / redirects there.
7. Automated tests
Turn this checklist into tests that drive the service against a real Postgres database. In-memory backends were removed, so tests need one too. See Testing.
Troubleshooting
| Symptom | Likely cause |
|---|---|
Custom route 404 | Domain mounted with mount_coupled, or into_arc() was skipped |
/api/auth/* 404 | mount_auth_routes not called, or provider None with auth disabled |
Every request 403 with Casbin on | Empty policy, or rows use audit names (todo.create) instead of create-todo.execute / todo.query |
403 CAS-011 on a custom route | The route is not mapped to an activity; register it as public with a reason, or add policy |
| Migration errors | Wrong RIVERBASE_DB_URL or the database does not exist |
relation "todo_items" does not exist | A stale migration row; rerun with --migrate-only |
| Connection refused | Service not running, or a different bind_addr |
More in Troubleshooting.
Next: 9. Secure defaults.