Skip to content

idQuery

idQuery<ParamKey, Brand>(queryName, codec, options?): (req, res, next) => void

Defined in: src/adapters/express.ts:238

Express middleware that validates a named query-string param against a codec via safeParse.

Same failure contract as idParam — same IdParamOptions / IdParamFailure shape, same IdParamError forwarded to next(err) — but reads req.query[queryName] instead of req.params[queryName].

Default (no options): calls next(err) with an IdParamError carrying status and reason, so the app’s existing error-handling middleware controls rendering. The adapter does not write a response body itself.

options.onError: when provided, the adapter calls the hook on validation failure. If the hook sends a response (res.headersSent is true after it returns), the adapter takes no further action. Otherwise — including if the hook calls next() instead of next(err) — the adapter falls back to next(new IdParamError(...)), so the route handler never runs with an invalid ID.

options.status: remaps the default HTTP status for a reason without a full handler.

  • Brand mismatch (invalid_prefix) → reason: "brand_mismatch", default 404
  • Malformed or missing query param → reason: "malformed", default 400

Storage: on success, stores the canonical Id<Brand> in res.locals[queryName] and calls next(). This contrasts with the Fastify adapter, which mutates request.query[queryName] in place. See the idParam JSDoc for the rationale on the res.locals choice.

ParamKey extends string

Brand extends string

ParamKey

IdVerifiableCodec<Brand>

IdParamVerifyOptions

(req, res, next) => void

import { idQuery, IdParamError } from "@smonn/ids/express";
import { createTimestampId } from "@smonn/ids";
const usr = createTimestampId("usr");
// Default: forwards error to app error-handling middleware
// GET /users?userId=usr_...
app.get("/users", idQuery("userId", usr), (req, res) => {
const userId = res.locals.userId; // Id<"usr">, canonical
});
// Override: consumer fully owns the response
app.get("/search", idQuery("cursor", usr, {
onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),
}), handler);

idQuery<ParamKey, Brand>(queryName, codec, options?): (req, res, next) => void

Defined in: src/adapters/express.ts:243

Express middleware that validates a named query-string param against a codec via safeParse.

Same failure contract as idParam — same IdParamOptions / IdParamFailure shape, same IdParamError forwarded to next(err) — but reads req.query[queryName] instead of req.params[queryName].

Default (no options): calls next(err) with an IdParamError carrying status and reason, so the app’s existing error-handling middleware controls rendering. The adapter does not write a response body itself.

options.onError: when provided, the adapter calls the hook on validation failure. If the hook sends a response (res.headersSent is true after it returns), the adapter takes no further action. Otherwise — including if the hook calls next() instead of next(err) — the adapter falls back to next(new IdParamError(...)), so the route handler never runs with an invalid ID.

options.status: remaps the default HTTP status for a reason without a full handler.

  • Brand mismatch (invalid_prefix) → reason: "brand_mismatch", default 404
  • Malformed or missing query param → reason: "malformed", default 400

Storage: on success, stores the canonical Id<Brand> in res.locals[queryName] and calls next(). This contrasts with the Fastify adapter, which mutates request.query[queryName] in place. See the idParam JSDoc for the rationale on the res.locals choice.

ParamKey extends string

Brand extends string

ParamKey

IdCodec<Brand>

IdParamOptions

(req, res, next) => void

import { idQuery, IdParamError } from "@smonn/ids/express";
import { createTimestampId } from "@smonn/ids";
const usr = createTimestampId("usr");
// Default: forwards error to app error-handling middleware
// GET /users?userId=usr_...
app.get("/users", idQuery("userId", usr), (req, res) => {
const userId = res.locals.userId; // Id<"usr">, canonical
});
// Override: consumer fully owns the response
app.get("/search", idQuery("cursor", usr, {
onError: (failure, req, res) => res.status(failure.status).json({ error: failure.reason }),
}), handler);