Routing

SpaceNode uses a Trie (radix tree) based router. Routes are defined in module.js and automatically prefixed with the module's prefix.

URL Parameters

// module.js
routes: [
  ['GET', '/users/:id',           'getUser'],
  ['GET', '/users/:id/posts/:pid', 'getPost'],
]

// controller
export function getUser({ params, send }) {
  console.log(params.id)    // "123"
}

export function getPost({ params, send }) {
  console.log(params.id)    // "123"
  console.log(params.pid)   // "456"
}

Query Parameters

// GET /products?q=laptop&minPrice=500

export function list({ query, send }) {
  console.log(query.q)          // "laptop"
  console.log(query.minPrice)   // "500"
}

Wildcard Routes

routes: [
  ['GET', '/*', 'catchAll'],
]

export function catchAll({ params, send }) {
  console.log(params['*'])  // "everything/after/prefix"
}

HTTP Methods

All standard methods are supported: GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD.

If a route path exists but the method doesn't match, SpaceNode returns 405 Method Not Allowed with an Allow header listing valid methods.

Automatic HEAD Support

SpaceNode handles HEAD requests automatically — you don't need to define separate HEAD routes. When a HEAD request is received, SpaceNode routes it to the matching GET handler, runs the full pipeline (pipes + handler), but suppresses the response body. Status code and headers are preserved.

// Define only GET — HEAD is handled automatically:
routes: [
  ['GET', '/users', 'list'],
]

// HEAD /users → runs list handler, returns headers + status, no body
// GET  /users → runs list handler, returns headers + status + body
Why? — HEAD is used by clients and proxies to check resource availability, content length, and caching without downloading the full response body. SpaceNode follows the HTTP spec: HEAD must return the same headers as GET.

Route Priority

The trie router matches in priority order:

  1. Exact match/users/search wins over /users/:id
  2. Parameter match/users/:id
  3. Wildcard match/users/*

Trie Router Performance

The trie router finds routes in O(path_length) time, not O(n_routes). This means routing performance doesn't degrade as you add more routes — unlike Express's linear regex matching.