Skip to main content
A service exposes its features to the rest of the application through two related declarations: transports and routes. Understanding how they relate makes the individual transport pages easier to follow.

Transport: the endpoint

A transport is something a service owns that can serve traffic. Each transport has:
  • an id, chosen by the service and unique within that service;
  • a type, one of static, http, or proxy; and
  • type-specific configuration — for example, a static transport names the file or directory it serves, and a proxy transport names the upstream it forwards to.
Registering a transport makes the endpoint exist, but it does not by itself make the endpoint reachable at a URL or namespace. That binding is the route’s job.

Route: the binding

A route connects a URL pattern to one transport, identified by the transport’s id. A route has:
  • an id, chosen by the service and unique within that service;
  • the id of the transport it binds to; and
  • an HTTP declaration (method, pattern, access).
An HTTP route can bind to a static, http, or proxy transport — whichever one should handle requests at that pattern. The access policy lives on the route, not the transport, so the same transport type is configured identically regardless of who can reach it; what changes per route is who can reach it and at what URL.

Why they’re separate

Splitting the endpoint from the binding lets you:
  • expose the same transport at more than one route — for example, one static file source reachable at two different URL prefixes;
  • change which paths point at a feature without recreating the underlying connection, which matters most for a proxy transport, where the upstream connection is comparatively expensive to set up; and
  • reason about ownership and cleanup independently: transports and routes are two registries, and the Kernel is the only thing allowed to coordinate between them.

Registering and removing resources

A wasm or grpc service can register and unregister transports and routes at any point while it is running, not only at startup — see Protocol for where this fits in the service lifecycle. A static service instead declares its transports and routes once, up front, in its package manifest; see Static services. A few rules apply consistently:
  • A transport cannot be removed while a route still references it. Remove the route first.
  • When a batch of routes is registered together, successful items stay registered even if others in the same batch fail; a failure marks the service degraded rather than rejecting the whole batch.
  • When a service session ends — the process exits, the WASM instance is unloaded, or the service is stopped through the management API — the Kernel removes all of that service’s routes and then its transports, so a dead service session can never leave a reachable but unowned binding.

Conflicts

Routes from different services share the same URL space, so the Kernel rejects a conflicting registration rather than silently overwriting one service’s route with another’s:
  • The same path cannot be owned by two different services, even for different HTTP methods.
  • A route with no method (matching every method) conflicts with every method-specific route at the same path.
  • A route backed by a static transport and a route backed by a non-static transport conflict at the same path, even if the methods would otherwise be compatible — a path is either served as static content or handled dynamically, not both.
See Kernel routing for the path-pattern language itself — exact versus subtree matching, the root path, and how the longest matching pattern is chosen — and the transport-specific pages for what each transport type needs from its route.