Skip to main content
Alpha

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. 1 · Scaffold
  2. 2 · Catalog service
  3. 3 · Cart contracts
  4. 4 · Checkout saga
  5. 5 · Shipping webhook
  6. 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 products service and the cart contract.
  • The sagas plugin (with CheckoutSaga and the process-payment job) and the triggers plugin (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:

What aspire start brings up for my-shop/
NameTypeDescription
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:

Aspire dashboard surfaces
NameTypeDescription
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.json shows both files.
  • [ ] aspire start boots and prints a dashboard URL + login token.
  • [ ] The dashboard at https://localhost:18888 lists postgres, redis, products, and the workers / sagas / triggers plugin APIs, all healthy.
  • [ ] curl against :3001, :8092, and :8093 all 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 single aspire start — Postgres, Redis, the products service, the streams transport, and the workers, sagas, and triggers plugin APIs plus their background processors.
  • A dashboard at https://localhost:18888 giving 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