Documentation status — public API reference
This page consolidates the detailed Subatom reference material supplied with the framework implementation examples. Treat the exported/public API surface as authoritative; internal implementation details are intentionally not presented as application APIs.
Response Helper (res.helper)
The res.helper interface (IResponseHelper) is a built-in convenience facade exposed on both ctx.res.helper and the Response object. It provides semantic, type-safe convenience methods corresponding to standard HTTP status codes, streamlining how you return consistent success data payloads, handle redirection responses, and dispatch structured client or server errors.
router.get('/users/:id', {
controller: (ctx) => {
const user = findUser(ctx.params.id);
if (!user) {
return ctx.res.helper.not_found('User not found', { id: ctx.params.id });
}
return ctx.res.helper.success(user);
}
});
Table of Contents
- Overview & Method Signatures
- Success & Informational Helpers (1xx, 2xx, 3xx)
- Error Helpers (4xx, 5xx)
- HTTP Status Registry
- Type Definitions
Overview & Method Signatures
The helpers are partitioned into two core function signatures based on whether the HTTP status code represents an error (isError: true) or a non-error operation (isError: false):
1. Success & Informational Helpers (isError: false)
res.helper[methodName](data?: unknown): IResponse
Used for 1xx, 2xx, and 3xx statuses. Accepts an optional data payload or object that gets serialized into the outgoing response.
2. Error Helpers (isError: true)
res.helper[methodName](messageOrError?: string | Error, details?: unknown): IResponse
Used for 4xx and 5xx statuses. Accepts a custom string message or native Error instance as the primary argument, accompanied by an optional details metadata object (e.g., error codes, field validation arrays, trace IDs).
Success & Informational Helpers (1xx, 2xx, 3xx)
1xx Informational
res.helper.continue([data])
Sends an HTTP 100 Continue status.
router.get('/helper/continue', {
controller: (ctx) => {
return ctx.res.helper.continue();
}
});
res.helper.switching_protocols([data])
Sends an HTTP 101 Switching Protocols status.
ctx.res.helper.switching_protocols();
res.helper.processing([data])
Sends an HTTP 102 Processing status (WebDAV).
ctx.res.helper.processing();
res.helper.early_hints([data])
Sends an HTTP 103 Early Hints status with pre-connect or preload headers.
ctx.res.helper.early_hints();
2xx Success
res.helper.success([data])
Sends an HTTP 200 OK status with the supplied payload.
| Parameter | Type | Description |
|---|---|---|
data |
unknown |
(Optional) The JSON payload, entity object, or array to send to the client. |
router.get('/helper/success', {
controller: (ctx) => {
return ctx.res.helper.success({
id: 'usr_101',
name: 'Kunal Chandra Das',
role: 'Maintainer'
});
}
});
res.helper.created([data])
Sends an HTTP 201 Created status indicating that a new resource has been provisioned.
| Parameter | Type | Description |
|---|---|---|
data |
unknown |
(Optional) The newly created record or resource descriptor. |
router.post('/helper/created', {
controller: (ctx) => {
const newRecord = { id: 42, item: 'Subatom Configuration' };
return ctx.res.helper.created(newRecord);
}
});
res.helper.accepted([data])
Sends an HTTP 202 Accepted status indicating that a request has been accepted for processing, but the processing has not completed.
router.post('/helper/accepted', {
controller: (ctx) => {
return ctx.res.helper.accepted({
jobId: 'job_9981',
status: 'queued'
});
}
});
res.helper.non_authoritative_information([data])
Sends an HTTP 203 Non-Authoritative Information status.
ctx.res.helper.non_authoritative_information({
mirrored: true,
data: [1, 2, 3]
});
res.helper.no_content()
Sends an HTTP 204 No Content status. Indicates success with no response entity body returned.
router.delete('/helper/no-content', {
controller: (ctx) => {
return ctx.res.helper.no_content();
}
});
res.helper.reset_content()
Sends an HTTP 205 Reset Content status indicating that the agent should reset the document view which caused the request to be sent.
ctx.res.helper.reset_content();
res.helper.partial_content([data])
Sends an HTTP 206 Partial Content status, commonly used for chunked byte-range requests.
ctx.res.helper.partial_content({
range: 'bytes 0-1023/2048',
chunk: 'SGVsbG8gU3ViYXRvbQ=='
});
res.helper.multi_status([data])
Sends an HTTP 207 Multi-Status status (WebDAV).
ctx.res.helper.multi_status([
{ href: '/files/1', status: 200 },
{ href: '/files/2', status: 404 }
]);
res.helper.already_reported([data])
Sends an HTTP 208 Already Reported status (WebDAV).
ctx.res.helper.already_reported({ synced: true });
res.helper.im_used([data])
Sends an HTTP 226 IM Used status.
ctx.res.helper.im_used({ delta: 'applied' });
3xx Redirection
res.helper.multiple_choices([data])
Sends an HTTP 300 Multiple Choices status.
ctx.res.helper.multiple_choices(['/version/v1', '/version/v2']);
res.helper.moved_permanently([data])
Sends an HTTP 301 Moved Permanently status.
ctx.res.helper.moved_permanently({ location: 'https://subatomjs.dev/docs/v2' });
res.helper.found([data])
Sends an HTTP 302 Found status.
ctx.res.helper.found({ location: '/login' });
res.helper.see_other([data])
Sends an HTTP 303 See Other status.
ctx.res.helper.see_other({ location: '/receipt/1029' });
res.helper.not_modified()
Sends an HTTP 304 Not Modified status.
ctx.res.helper.not_modified();
res.helper.use_proxy([data])
Sends an HTTP 305 Use Proxy status.
ctx.res.helper.use_proxy();
res.helper.temporary_redirect([data])
Sends an HTTP 307 Temporary Redirect status.
ctx.res.helper.temporary_redirect({ location: '/temp-endpoint' });
res.helper.permanent_redirect([data])
Sends an HTTP 308 Permanent Redirect status.
ctx.res.helper.permanent_redirect({ location: 'https://subatomjs.dev/canonical-path' });
Error Helpers (4xx, 5xx)
All error helpers accept two optional parameters:
messageOrError: Custom error message string or nativeErrorinstance.details: Supplemental context or structured diagnostics payload.
4xx Client Errors
res.helper.bad_request([messageOrError], [details])
Sends an HTTP 400 Bad Request status.
| Parameter | Type | Description |
|---|---|---|
messageOrError |
string | Error |
(Optional) Human-readable error description. Defaults to "Bad Request". |
details |
unknown |
(Optional) Additional metadata or validation error maps. |
router.post('/helper/bad-request', {
controller: (ctx) => {
return ctx.res.helper.bad_request('Invalid email address format', {
field: 'email',
code: 'INVALID_EMAIL'
});
}
});
res.helper.unauthorized([messageOrError], [details])
Sends an HTTP 401 Unauthorized status when authentication credentials are missing or invalid.
router.get('/helper/unauthorized', {
controller: (ctx) => {
return ctx.res.helper.unauthorized('Authentication token expired or missing');
}
});
res.helper.payment_required([messageOrError], [details])
Sends an HTTP 402 Payment Required status.
router.post('/helper/payment-required', {
controller: (ctx) => {
return ctx.res.helper.payment_required('Subscription inactive', {
upgradeUrl: '/billing/plans'
});
}
});
res.helper.forbidden([messageOrError], [details])
Sends an HTTP 403 Forbidden status when client identity is recognized but access rights are denied.
router.get('/helper/forbidden', {
controller: (ctx) => {
return ctx.res.helper.forbidden('Insufficient permissions for administrative area');
}
});
res.helper.not_found([messageOrError], [details])
Sends an HTTP 404 Not Found status.
router.get('/helper/not-found', {
controller: (ctx) => {
return ctx.res.helper.not_found('Requested user resource was not found', {
resourceId: 'usr_missing'
});
}
});
res.helper.method_not_allowed([messageOrError], [details])
Sends an HTTP 405 Method Not Allowed status.
ctx.res.helper.method_not_allowed('Method not permitted on this resource');
res.helper.not_acceptable([messageOrError], [details])
Sends an HTTP 406 Not Acceptable status.
ctx.res.helper.not_acceptable('Accept header does not match acceptable formats');
res.helper.proxy_authentication_required([messageOrError], [details])
Sends an HTTP 407 Proxy Authentication Required status.
ctx.res.helper.proxy_authentication_required('Proxy auth required');
res.helper.request_timeout([messageOrError], [details])
Sends an HTTP 408 Request Timeout status.
ctx.res.helper.request_timeout('Connection negotiation took too long');
res.helper.conflict([messageOrError], [details])
Sends an HTTP 409 Conflict status, typically for unique key violations.
router.post('/helper/conflict', {
controller: (ctx) => {
return ctx.res.helper.conflict('A user with this email address already exists', {
duplicateKey: 'email'
});
}
});
res.helper.gone([messageOrError], [details])
Sends an HTTP 410 Gone status indicating the resource has been permanently removed.
ctx.res.helper.gone('This resource has been permanently purged');
res.helper.length_required([messageOrError], [details])
Sends an HTTP 411 Length Required status.
ctx.res.helper.length_required('Content-Length header required');
res.helper.precondition_failed([messageOrError], [details])
Sends an HTTP 412 Precondition Failed status.
ctx.res.helper.precondition_failed('ETag precondition failed');
res.helper.content_too_large([messageOrError], [details])
Sends an HTTP 413 Content Too Large status.
ctx.res.helper.content_too_large('File payload exceeds allowable 10MB limit');
res.helper.uri_too_long([messageOrError], [details])
Sends an HTTP 414 URI Too Long status.
ctx.res.helper.uri_too_long('URL exceeds 2048 character limit');
res.helper.unsupported_media_type([messageOrError], [details])
Sends an HTTP 415 Unsupported Media Type status.
ctx.res.helper.unsupported_media_type('Only application/json payloads are accepted');
res.helper.range_not_satisfiable([messageOrError], [details])
Sends an HTTP 416 Range Not Satisfiable status.
ctx.res.helper.range_not_satisfiable('Invalid byte range requested');
res.helper.expectation_failed([messageOrError], [details])
Sends an HTTP 417 Expectation Failed status.
ctx.res.helper.expectation_failed('Expect header unsatisfied');
res.helper.im_a_teapot([messageOrError], [details])
Sends an HTTP 418 I'm A Teapot status (RFC 2324).
ctx.res.helper.im_a_teapot('Short and stout: cannot brew coffee');
res.helper.misdirected_request([messageOrError], [details])
Sends an HTTP 421 Misdirected Request status.
ctx.res.helper.misdirected_request('Host mismatch');
res.helper.unprocessable_content([messageOrError], [details])
Sends an HTTP 422 Unprocessable Content status, commonly used for validation error arrays.
router.post('/helper/unprocessable-content', {
controller: (ctx) => {
return ctx.res.helper.unprocessable_content('Semantic validation failed', {
errors: [
{ field: 'age', reason: 'Value must be positive integer' }
]
});
}
});
res.helper.locked([messageOrError], [details])
Sends an HTTP 423 Locked status (WebDAV).
ctx.res.helper.locked('Resource locked');
res.helper.failed_dependency([messageOrError], [details])
Sends an HTTP 424 Failed Dependency status (WebDAV).
ctx.res.helper.failed_dependency('Prior action failed');
res.helper.too_early([messageOrError], [details])
Sends an HTTP 425 Too Early status.
ctx.res.helper.too_early('Replay risk detected');
res.helper.upgrade_required([messageOrError], [details])
Sends an HTTP 426 Upgrade Required status.
ctx.res.helper.upgrade_required('TLS upgrade required');
res.helper.precondition_required([messageOrError], [details])
Sends an HTTP 428 Precondition Required status.
ctx.res.helper.precondition_required('Conditional headers missing');
res.helper.too_many_requests([messageOrError], [details])
Sends an HTTP 429 Too Many Requests status when rate limits are exceeded.
router.get('/helper/too-many-requests', {
controller: (ctx) => {
return ctx.res.helper.too_many_requests('Rate limit exceeded', {
retryAfterSeconds: 60
});
}
});
res.helper.request_header_fields_too_large([messageOrError], [details])
Sends an HTTP 431 Request Header Fields Too Large status.
ctx.res.helper.request_header_fields_too_large('Headers exceed max size');
res.helper.unavailable_for_legal_reasons([messageOrError], [details])
Sends an HTTP 451 Unavailable For Legal Reasons status.
ctx.res.helper.unavailable_for_legal_reasons('Blocked per court order');
5xx Server Errors
res.helper.internal_server_error([messageOrError], [details])
Sends an HTTP 500 Internal Server Error status. Accepts either a string description or a native Error object.
router.get('/helper/internal-server-error', {
controller: (ctx) => {
try {
throw new Error('Database connection pool exhausted');
} catch (err) {
return ctx.res.helper.internal_server_error(err as Error, {
traceId: 'trc_982347a'
});
}
}
});
res.helper.not_implemented([messageOrError], [details])
Sends an HTTP 501 Not Implemented status.
ctx.res.helper.not_implemented('GraphQL queries are not yet supported');
res.helper.bad_gateway([messageOrError], [details])
Sends an HTTP 502 Bad Gateway status.
ctx.res.helper.bad_gateway('Upstream microservice returned an invalid response');
res.helper.service_unavailable([messageOrError], [details])
Sends an HTTP 503 Service Unavailable status.
router.get('/helper/service-unavailable', {
controller: (ctx) => {
return ctx.res.helper.service_unavailable('System undergoing maintenance', {
estimatedDurationSec: 300
});
}
});
res.helper.gateway_timeout([messageOrError], [details])
Sends an HTTP 504 Gateway Timeout status.
ctx.res.helper.gateway_timeout('Upstream database took too long to reply');
res.helper.http_version_not_supported([messageOrError], [details])
Sends an HTTP 505 HTTP Version Not Supported status.
ctx.res.helper.http_version_not_supported('HTTP/3 required');
res.helper.variant_also_negotiates([messageOrError], [details])
Sends an HTTP 506 Variant Also Negotiates status.
ctx.res.helper.variant_also_negotiates('Content negotiation loop');
res.helper.insufficient_storage([messageOrError], [details])
Sends an HTTP 507 Insufficient Storage status (WebDAV).
ctx.res.helper.insufficient_storage('Disk quota exceeded');
res.helper.loop_detected([messageOrError], [details])
Sends an HTTP 508 Loop Detected status (WebDAV).
ctx.res.helper.loop_detected('Infinite redirection loop');
res.helper.not_extended([messageOrError], [details])
Sends an HTTP 510 Not Extended status.
ctx.res.helper.not_extended('Mandatory extension missing');
res.helper.network_authentication_required([messageOrError], [details])
Sends an HTTP 511 Network Authentication Required status.
ctx.res.helper.network_authentication_required('Captive portal intercept');
HTTP Status Registry
Subatom provides the immutable registry map HTTP_STATUS_REGISTRY containing status metadata, error classification, and title-cased fallback strings.
import { HTTP_STATUS_REGISTRY } from 'subatom';
const status = HTTP_STATUS_REGISTRY.get('bad_request');
console.log(status);
// {
// code: 400,
// message: 'bad_request',
// isError: true,
// defaultMessage: 'Bad Request'
// }
Type Definitions
export interface IHttpStatusEntry {
code: number;
message: TSuccessHelperName | TErrorHelperName;
isError: boolean;
defaultMessage: string;
}
export type IResponseHelper = {
[K in TSuccessHelperName]: (data?: unknown) => IResponse;
} & {
[K in TErrorHelperName]: (
messageOrError?: string | Error,
details?: unknown,
) => IResponse;
};
License
MIT © Kunal Chandra Das — Subatom