Valid patterns
A pattern must:- be non-empty; and
- start with
/.
/ when you want to match a path subtree:
* or ? do not create wildcard behavior. Unless the
pattern ends in /, the entire pattern is compared as a literal path.
Matching rules
Exact paths
A pattern that does not end in/ matches only the same path:
The trailing slash is significant.
/api/items and /api/items/ are
different exact paths.
Subtrees
A pattern ending in/ matches paths that begin with that pattern:
/api and its children, define separate patterns.
The root path
/ is handled specially because different resource types use it differently:
Most callers use
RootPathExact. A directory-backed static route and a proxy
route both use RootPathSubtree, so either one mounted at / can serve or
forward paths below the root — useful when a proxy should own the whole
application, or a static directory should provide its general content.
Choosing between matching patterns
When several patterns match a path, Arupa selects the longest matching pattern. It does not merge the rules or group lists from all matching patterns. For example, given these host access rules:/api/admin/users matches both patterns, but /api/admin/ wins because it is
longer. Only the root group rule is evaluated for that request.
This same longest-pattern rule is used when the service router selects an HTTP
route, whether that route serves packaged files through a static transport or
is handled dynamically.
Host access rules
Route.Allow matches the request’s URL path before the request reaches a host
handler or service handler. Configuration validation applies the same pattern
rules described above. See Access control
for how the selected route’s group list is evaluated against the authenticated
user.
The query string is not part of path matching. For example, a request for
/api/items?limit=10 is matched using /api/items.
Service HTTP routes
Services use the same path patterns when they register HTTP routes. After the router selects the longest matching path pattern, it selects a handler by HTTP method:- an explicitly declared method such as
GETorPOSTis matched case-insensitively after normalization; - an empty method is a handler for any method; and
- an explicit method takes precedence over an empty-method handler for the selected path.
405 Method Not Allowed and includes the available methods in the Allow response header.
Routes with the same path and conflicting methods cannot be registered by
different services. A methodless route conflicts with every method at that same
path.
This section covers how a path is matched once a route exists. For how a
route is declared and bound to a transport — including the static transport
that serves packaged files without running service code — see Routes and
transports.
Reserved paths
Before any service registers a route, the Kernel reserves a fixed set of HTTP paths for itself — the paths behind login and the whole Management API:GET /api/user,
GET /api/service, and so on). A path ending in / reserves that pattern
as a subtree route, covering the nested per-resource endpoints under it
(/api/user/{name}, /api/service/config/{name}, and so on) — see
Subtrees for what that pattern shape means. These reservations
go through the same router services use, so a service cannot register an
HTTP route at exactly one of these patterns; the attempt fails the same way
it would against a path another service already owns. Only paths
implemented directly by the Kernel are reserved this way — everything else,
including the pages a core service such as login serves, competes for path
ownership like any other service route.
A capability being reserved has nothing to do with whether it’s enabled.
The Kernel claims these paths at startup regardless of the [API] table,
so a service can never register a route that would collide with a
capability’s endpoints even while that capability is turned off; see
Management API for how the enabled/disabled state itself is
enforced.
This list is defined by the Kernel and may grow in future versions; treat it
as the set of paths no service can claim, rather than a fixed, permanent
list.
Static routes
A route bound to a static transport uses the same path-pattern rules as any other HTTP route, with one addition: whether it matches as an exact path or a subtree depends on whether its source is a single file or a directory.- A route backed by a directory source uses subtree matching. The Kernel
normalizes it to a pattern ending in
/, so a route configured at/assetsserves the/assets/subtree. - A route backed by a single-file source uses exact matching and must not end
in
/. A route at/favicon.icotherefore serves that path only.