registerCatPipeline
Registers an Express route whose handlers are already in the cat-inspector registry (@Cat or cat()). The SDK stamps each step with route, HTTP method, pipeline id, and index, wraps execution for inspector correlation, and sets ApiContext on the last handler so ApiReturn events attach to the endpoint.
Signature
function registerCatPipeline(
router: Router,
method: HttpMethod,
route: string,
handlers: readonly ((...args: any[]) => any)[],
): void
type HttpMethod = 'get' | 'post' | 'put' | 'delete' | 'patch'Usage
Minimal route (one handler)
import express, { type Request, type Response } from 'express'
import { ApiReturn, cat, registerCatPipeline } from '@gloocan/cat-inspector'
const createOrder = cat('OrderController.create', function create(
req: Request,
res: Response,
): void {
const r = ApiReturn('CREATED', 201, { ok: true, order: req.body })
res.status(r.statusCode).json(r.body)
})
const router = express.Router()
registerCatPipeline(router, 'post', '/orders', [createOrder])
// Mount on your app, e.g. app.use('/api', router)Middleware pipeline (auth → validate → handler)
Order matters: earlier cat() handlers run as middleware (mode: 'api_candidate'); the last registered handler is the API endpoint (mode: 'api').
import 'reflect-metadata'
import express, { type NextFunction, type Request, type Response } from 'express'
import {
ApiReturn,
Cat,
registerCatPipeline,
} from '@gloocan/cat-inspector'
import { createInspectorCorrelationMiddleware } from '@gloocan/cat-inspector/socket-io'
class AuthMiddleware {
@Cat
requireUser(req: Request, res: Response, next: NextFunction): void {
if (!req.header('authorization')) {
const r = ApiReturn('UNAUTHORIZED', 401, { error: 'missing token' })
res.status(r.statusCode).json(r.body)
return
}
next()
}
}
class OrderController {
@Cat
create(req: Request, res: Response): void {
const r = ApiReturn('CREATED', 201, { ok: true, order: req.body })
res.status(r.statusCode).json(r.body)
}
}
const app = express()
app.use(express.json())
app.use(createInspectorCorrelationMiddleware())
const router = express.Router()
const auth = new AuthMiddleware()
const ctrl = new OrderController()
registerCatPipeline(router, 'post', '/orders', [
auth.requireUser.bind(auth),
ctrl.create.bind(ctrl),
])
app.use('/api', router)Use .bind(instance) when passing class methods so registry identity matches the wrapped function Express runs.
Several cat() steps (functional style)
import express, { type NextFunction, type Request, type Response } from 'express'
import { ApiReturn, cat, registerCatPipeline } from '@gloocan/cat-inspector'
const verifySession = cat('Pipeline.verifySession', function verifySession(
req: Request,
res: Response,
next: NextFunction,
): void {
if (!req.header('x-session')) {
const r = ApiReturn('UNAUTHORIZED', 401, { error: 'missing session' })
res.status(r.statusCode).json(r.body)
return
}
next()
})
const validateBody = cat('Pipeline.validateBody', function validateBody(
req: Request,
res: Response,
next: NextFunction,
): void {
if (!req.body?.origin) {
const r = ApiReturn('VALIDATION_FAILED', 422, {
issues: [{ path: 'origin', message: 'required' }],
})
res.status(r.statusCode).json(r.body)
return
}
next()
})
const execute = cat('Pipeline.execute', function execute(req: Request, res: Response): void {
const r = ApiReturn('OK', 200, { ok: true, result: runWorkflow(req.body) })
res.status(r.statusCode).json(r.body)
})
const router = express.Router()
registerCatPipeline(router, 'post', '/sdk-showcase/trigger', [
verifySession,
validateBody,
execute,
])Non-cat middleware (e.g. multer, express.json() on the router) can sit in the same array; only functions found in the registry get pipeline metadata. Put body parsers before instrumented handlers that read req.body.
After bootstrap(), the catalog exposes one entry per pipeline step plus the endpoint’s apiResponses from ApiReturn labels in source.
Behavior
- Computes
pipelineIdviapipelineIdForRoute— e.g.POST /api/orders. - Walks each handler in
handlers: matching registry entries receiveroute,httpMethod,pipelineId, andpipelineIndex. - Last handler →
mode: 'api'; earlier instrumented handlers →mode: 'api_candidate'. - Wraps handlers so
ApiReturnand HTTP inspector broadcasts use the endpointfnKey(see Inspector HTTP correlation andX-Socket-Idfor tab routing).
pipelineIdForRoute
function pipelineIdForRoute(method: string, route: string): stringReturns `${METHOD.toUpperCase()} ${route}` — stable id for grouping (see groupApiPipelines).
Example: pipelineIdForRoute('post', '/orders') → "POST /orders".
Requirements
- Handlers must already be registered (via
@Catorcat()) with Express-shaped signatures(req, res)or(req, res, next). - Unknown functions in the array are passed through to Express unchanged (no pipeline metadata).
- For live HTTP traces in the QA app, mount
createInspectorCorrelationMiddleware()on the API prefix before routes that useregisterCatPipeline.
See also
ApiReturn— label HTTP responses; pipeline UI conventions forerror/issuesbodies- Inspector HTTP correlation
- Synthetic invoke
- Cat modes