← All context files

lite/routes-and-mounting.md

lite – Routes, mount() and Registration Order

Applies to lite v6 (@kyd/lite). v6's mount(routes) replaced v4's get()/post() decorators, and the matching semantics changed with it.

preprocess fires on path match alone

v4 registered routes into method-keyed registries and checked the method before the path. v6 does not: if a route has a preprocess, it runs as soon as the path matches, whatever the HTTP method, and regardless of the methods array.

POST /demand/archive was being matched by GET /demand/:id with id = 'archive'. The preprocess ran a SELECT with a non-GUID id and SQL Server threw a UUID conversion error — before any method check happened.

Register fixed paths before parameterised siblings

Any route whose path is /thing/LITERAL (two segments, literal second segment) must be registered before /thing/:id:

// BEFORE demand (/demand/:id):
demandArchive,       // /demand/archive          ← 2-seg literal, MUST be first
demandWatch,         // /demand/watch            ← 2-seg literal, MUST be first
demandStatus,        // /demand/:id/status       ← 3-seg, safe either way
demandView,          // /demand/:id/view         ← 3-seg, safe either way
demandMessageDelete, // /demand/messages/:id/delete ← 4-seg, safe
demand,              // /demand/:id              ← catch-all last

Routes with three or more segments are safe regardless of order, because path-to-regexp's :id only matches a single non-slash segment — /demand/:id does not match /demand/abc/parents.

Never split GET and POST for the same path into two files

This is the one that produces a baffling runtime crash rather than a wrong result.

Even with a req.method guard inside preprocess, the pipeline continues to handleResponsevalidatedMethod, which throws new ClientError(msg, 405) for the method that route doesn't declare. ClientError extends Error, so Babel compiles it with _wrapNativeSuper(Error), which calls Reflect.construct. JScript has no Reflect → the ASP build dies with:

'Reflect' is undefined

The method guard does not prevent this. The only fix is one file per path:

export default {
  path: '/activity-designators',
  table: 'LPA_Activity_Designators',
  methods: ['GET', 'POST'],

  preprocess(req) {
    if (req.method === 'POST') {
      // handle create
      return;
    }
    // handle GET
  },
};

The table property

Checklist