Skip to main content

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:

service/src/main.rs
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​

SymptomLikely cause
Custom route 404Domain mounted with mount_coupled, or into_arc() was skipped
/api/auth/* 404mount_auth_routes not called, or provider None with auth disabled
Every request 403 with Casbin onEmpty policy, or rows use audit names (todo.create) instead of create-todo.execute / todo.query
403 CAS-011 on a custom routeThe route is not mapped to an activity; register it as public with a reason, or add policy
Migration errorsWrong RIVERBASE_DB_URL or the database does not exist
relation "todo_items" does not existA stale migration row; rerun with --migrate-only
Connection refusedService not running, or a different bind_addr

More in Troubleshooting.

Next: 9. Secure defaults.