Augmented Request & Response
When you use route handlers registered via a TypedRouter object
(using methods like .get, .post, .getUnchecked, etc.), the standard Express
request and response objects are augmented with additional properties and methods
related to the API specification.
Augmented Request (req)
The Express request object (req) passed to typed route handlers includes an
additional property:
req.decoded
- Type (Checked Routes):
DecodedRequest- In handlers attached using the "checked" methods (such as
typedRouter.get(...)),req.decodedholds the successfully decoded and validated request data. Its TypeScript type is inferred directly from therequestcodec defined in the correspondinghttpRouteof theApiSpec. This object contains the flattened combination of path parameters, query parameters, headers, and body properties as defined by thehttpRequestcodec used in the spec.
- In handlers attached using the "checked" methods (such as
- Type (Unchecked Routes & Middleware):
Either<t.Errors, DecodedRequest>- In handlers attached using the "unchecked" methods (such as
typedRouter.getUnchecked(...)) or in middleware added viatypedRouter.use(...),req.decodedholds the raw result of the decoding attempt fromio-ts. This is anEithertype from thefp-tslibrary. - Use
E.isRight(req.decoded)to check if decoding was successful. If true,req.decoded.rightcontains theDecodedRequest. - Use
E.isLeft(req.decoded)to check if decoding failed. If true,req.decoded.leftcontains thet.Errorsobject detailing the validation failures.
- In handlers attached using the "unchecked" methods (such as
Augmented Response (res)
The Express response object (res) passed to typed route handlers includes an
additional method:
res.sendEncoded(status, payload)
Use this method instead of res.json() or res.send() when sending responses that
should conform to the API specification.
Parameters:
status(number): The HTTP status code for the response. This status code must be a key defined in theresponseobject of thehttpRouteassociated with the current route in theApiSpec.payload(any): The data to be sent as the response body.
Behavior:
- Type Checking: Validates that the provided
payloadconforms to theio-tscodec associated with the givenstatusin thehttpRoute'sresponsedefinition. - Encoding: Encodes the
payloadusing the sameio-tscodec. This handles necessary transformations (such as converting aDateobject to an ISO string if usingDateFromISOString, or abigintto a string if usingBigIntFromString). - Sending Response: Sets the response status code to
status, sets theContent-Typeheader toapplication/json, and sends the JSON-stringified encoded payload as the response body. - Error Handling: If the
payloadfails validation against the codec for the specifiedstatus, calls theonEncodeErrorhook (route-specific or global). - Post-Response Hook: After the response has been successfully sent, calls the
afterEncodedResponseSenthook (route-specific or global).
Example:
import { TypedRequestHandler } from '@api-ts/typed-express-router';
import { MyApi } from 'my-api-package';
// Assuming 'api.v1.getUser' route expects a { user: UserType } payload for status 200
const getUserHandler: TypedRequestHandler<MyApi['api.v1.getUser']['get']> = (
req,
res,
) => {
const userId = req.decoded.userId; // Access decoded request data
const user = findUserById(userId);
if (!user) {
// Assuming 404 is defined in the spec with an error object payload
res.sendEncoded(404, { error: 'User not found' });
return;
}
// Send status 200 with the UserType payload
// 'sendEncoded' ensures 'user' matches the spec for status 200
res.sendEncoded(200, { user: user });
};