Run the whole storefront
Across the last five chapters you built the storefront one piece at a time, usually starting a single
service in its own terminal. This final chapter zooms out: you run the entire my-shop/ — the
products service, the cart contract's consumers, the checkout saga, the shipping webhook, Postgres,
and the cache — as one coherent system under a single aspire start, and watch all of it from one
dashboard. This is NetScript's local topology: git clone → one command → a complete, observable
stack.
- 1 · Scaffold
- 2 · Catalog service
- 3 · Cart contracts
- 4 · Checkout saga
- 5 · Shipping webhook
- 6 · Deploy
What you will build
You will bring the complete storefront up under one orchestrator: aspire start translates your
appsettings.json plus the installed plugins into a single resource graph and boots all of it —
infrastructure, services, plugin APIs, and background processors — then gives you a dashboard over the
whole thing. You will read the live port map from the dashboard and confirm every resource is healthy.
Before you begin
You should have finished chapter 5, so my-shop/ has:
- The
productsservice and thecartcontract. - The
sagasplugin (withCheckoutSagaand theprocess-paymentjob) and thetriggersplugin (with the shipping webhook).
Confirm the full plugin set is installed:
netscript plugin list
You should see sagas, streams (its dependency), and triggers. If aspire start from earlier
chapters is still up, you can stop it now — this chapter starts the whole graph fresh.
Step 1 — Confirm the AppHost was scaffolded
The orchestrator's entry point is a small TypeScript/Node program (not C#) at
aspire/apphost.mts, configured by aspire/aspire.config.json. netscript init generated it back in
chapter 1; you never hand-write it. Verify it is on disk:
# From the workspace root — these two files are the orchestration entry point.
ls aspire/apphost.mts aspire/aspire.config.json
The graph inside the AppHost is derived from your installed plugins at boot — adding the sagas
and triggers plugins in chapters 4 and 5 is exactly why their APIs and background processors now
appear in the graph, with no edit to apphost.mts required.
Step 2 — Restore the AppHost SDK (once)
The AppHost runs on its own isolated Node runtime inside aspire/ so its dependency graph never leaks
into your Deno workspace. Restore that runtime once per machine (you did this in chapter 1; it is
idempotent):
cd aspire
aspire restore
Step 3 — Start the whole resource graph
A single aspire start translates appsettings.json plus the plugin contributions into a coherent
resource graph and boots all of it — infrastructure first, then services, plugin APIs, and background
processors, with cross-references resolved into injected environment variables:
# Still inside aspire/. Boots the whole graph; prints the dashboard URL + a login token.
aspire start
When boot finishes, aspire start prints the dashboard address and a one-time login token. Here is the
graph a single run stands up for the storefront:
| Name | Type | Description |
|---|---|---|
aspire (dashboard) |
https://localhost:18888 / http://localhost:18889 |
Live resource list, console logs, structured logs and traces. A login token is printed on start. |
OTLP collector |
http://localhost:4318 |
OpenTelemetry endpoint the dashboard runs; framework spans and structured logs land here automatically. |
postgres |
Container |
Provisioned via Docker. The database your products handlers and saga store target — reachable only while Aspire is up. |
redis |
Container (cache) |
Redis cache — the default --cache-backend; Redis-compatible. Backs KV/queue workloads for the runtime plugins. |
products (service) |
:3001 (SERVICE range, from :3000) |
Your catalog service. OpenAPI at /api/v1/products/* and RPC at /api/rpc/*. |
sagas API |
:8092 (PLUGIN_API range) |
Lists sagas and instances — where you watched CheckoutSaga in chapter 4. |
triggers API |
:8093 (PLUGIN_API range) |
The Hono webhook ingress from chapter 5 — /api/v1/webhooks/shipping/status. |
workers API |
:8091 (PLUGIN_API range) |
Lists job executions — where the enqueued shipping and payment jobs run. |
streams |
:4437 |
The durable streams transport that carries cross-plugin messages between the saga and the workers. |
background processors |
executables (no port) |
Each plugin's isolated runners (workers, sagas, triggers) — separate processes, not threads inside the API. |
Step 4 — Use the dashboard
Open https://localhost:18888, paste the login token aspire start printed, and you have a single pane
over the running storefront:
| Name | Type | Description |
|---|---|---|
Resources |
tab |
Every container and executable above with status, endpoints, and resolved environment. The authority for which port each resource bound. |
Console logs |
tab |
stdout/stderr per resource — a failing background processor is one click away, not buried in a terminal. |
Structured logs + Traces |
tab |
Spans and structured logs your handlers emit, correlated by traceparent across services. Collected via the OTLP endpoint at :4318. |
Because Aspire starts each resource with its OTEL_SERVICE_NAME and an OTLP endpoint, framework-level
spans — job dispatch, job execution, saga steps — surface here with no extra wiring. Driving a
checkout end to end (chapter 4) and firing the shipping webhook (chapter 5) now both show up as
correlated traces in one place.
Verify your progress
With the graph up, confirm the whole storefront is live from one terminal. The dashboard resource list
should show postgres, redis, products, and the workers / sagas / triggers APIs all
healthy. Spot-check a few endpoints:
# Catalog service
curl http://localhost:3001/health
# Saga registry lists your checkout saga
curl http://localhost:8092/api/v1/sagas/sagas
# Triggers ingress is alive
curl http://localhost:8093/health
- [ ]
ls aspire/apphost.mts aspire/aspire.config.jsonshows both files. - [ ]
aspire startboots and prints a dashboard URL + login token. - [ ] The dashboard at
https://localhost:18888listspostgres,redis,products, and theworkers/sagas/triggersplugin APIs, all healthy. - [ ]
curlagainst:3001,:8092, and:8093all answer. - [ ] A checkout and a webhook fire show up as correlated traces in the dashboard.
What you built
- The entire
my-shop/storefront running as one orchestrated resource graph under a singleaspire start— Postgres, Redis, theproductsservice, the streams transport, and the workers, sagas, and triggers plugin APIs plus their background processors. - A dashboard at
https://localhost:18888giving you the live port map, per-resource console logs, and correlated traces across the whole app. - A precise mental model: this is the local topology Aspire stands up for development, not a production deployer for your app.
You have built and run a complete NetScript storefront backend — contract-first throughout, durable where it counts, and verified at its edges.
Where to go next
- Ship it somewhere real → the Deploy how-to (production targets) and Deploy locally with Aspire (the full local recipe with every flag).
- Add observability → Add OpenTelemetry and the Observability explanation.
- Go deeper on the ideas → Durability model, Contracts & type flow, and The plugin system.
- Solve a specific task → the full How-to guides.