HTTP Request and Response Handling
The HTTPResult class
The HTTPResult class represents an HTTP response. It encapsulates the status code, body, content type, custom headers, and optional streaming.
Basic usage
Route handlers can return plain objects, strings, or HTTPResult instances.
import { Controller, Get, Post, HTTPResult } from "@antelopejs/interface-api";
class ExampleController extends Controller("/examples") {
@Get()
getExample() {
// Returns JSON (content-type: application/json)
return { status: "success", data: [1, 2, 3] };
}
@Get("text")
getTextExample() {
// Returns plain text (content-type: text/plain)
return "This is a text response";
}
@Get("custom")
getCustom() {
// Returns a fully customized response
const result = new HTTPResult(200, "<h1>Hello World</h1>", "text/html");
result.addHeader("X-Custom-Header", "Custom Value");
return result;
}
}
Status codes
Set HTTP status codes through the constructor or the setStatus method.
// Through the constructor
const notFound = new HTTPResult(404, "Not Found");
// Through setStatus
const forbidden = new HTTPResult();
forbidden.setStatus(403);
Response body
The body accepts strings, objects, or a custom content type.
// String body (text/plain)
const textResult = new HTTPResult(200, "Hello World");
// Object body (application/json)
const jsonResult = new HTTPResult(200, { message: "Success" });
// Custom content type
const htmlResult = new HTTPResult(200, "<p>HTML content</p>", "text/html");
When the body is an object, HTTPResult automatically serializes it to JSON and sets the content type to application/json.
Custom headers
Add, remove, and retrieve custom response headers.
const result = new HTTPResult(200, "Success");
// Add headers
result.addHeader("X-Rate-Limit", "100");
result.addHeader("X-Rate-Limit-Remaining", "99");
// Remove a header
result.removeHeader("X-Rate-Limit");
// Get all headers
const headers = result.getHeaders();
// Read headers without creating the mutable store
const existingHeaders = result.peekHeaders();
The withHeaders static method
The HTTPResult.withHeaders method creates an HTTPResult with additional headers from an existing body or HTTPResult.
import { HTTPResult } from "@antelopejs/interface-api";
// From a plain body
const result = HTTPResult.withHeaders(
{ message: "Success" },
{ "X-Request-Id": "abc-123" }
);
// From an existing HTTPResult
const original = new HTTPResult(200, { data: "test" });
const withExtra = HTTPResult.withHeaders(original, {
"Cache-Control": "no-cache",
});
Streaming responses
For long-running processes or server-sent events, use the getWriteStream method.
import { Controller, Get, Context, WriteStream, RequestContext } from "@antelopejs/interface-api";
import { PassThrough } from "node:stream";
class StreamController extends Controller("/stream") {
@Get()
async streamData(
@Context() context: RequestContext,
@WriteStream() stream: PassThrough,
) {
stream.write("Starting stream\n");
for (let i = 0; i < 10; i++) {
await new Promise((resolve) => setTimeout(resolve, 1000));
stream.write(`Data chunk ${i}\n`);
}
stream.end("Stream complete\n");
return context.response;
}
}
The getWriteStream method accepts an optional content type (defaults to text/plain) and an optional status code (defaults to 200).
The RequestContext interface
The RequestContext interface provides access to all request-related information.
| Property | Type | Description |
|---|---|---|
rawRequest | IncomingMessage | The raw Node.js HTTP request object |
rawResponse | ServerResponse | The raw Node.js HTTP response object |
url | URL | The parsed request URL |
routeParameters | Record<string, string> | Parameters extracted from URL path segments |
body | unknown | The request body data |
response | HTTPResult | The response object sent to the client |
error | unknown | Error thrown during processing, if any |
connection | unknown | WebSocket connection, if applicable |
Read request bodies
The ReadBody function reads the raw request body as a Buffer. Buffered request bodies are limited to 1 MiB by default. Requests with a larger Content-Length, or whose received data exceeds the limit, receive HTTP 413 Payload Too Large.
import { Controller, Post, RawBody } from "@antelopejs/interface-api";
class UserController extends Controller("/users") {
@Post()
async createUser(@RawBody() body: Buffer) {
const data = JSON.parse(body.toString());
return { id: "new-user", ...data };
}
}
For JSON bodies, use the @JSONBody decorator, which automatically parses the request body.
import { Controller, Post, JSONBody } from "@antelopejs/interface-api";
class UserController extends Controller("/users") {
@Post()
async createUser(@JSONBody() userData: { name: string; email: string }) {
return { id: "new-user-id", ...userData };
}
}
Pass a byte limit to @RawBody, @JSONBody, or ReadBody when an endpoint intentionally accepts a larger buffered body:
const TEN_MIBIBYTES = 10 * 1024 * 1024;
class UploadController extends Controller("/uploads") {
@Post()
async upload(@RawBody(TEN_MIBIBYTES) body: Buffer) {
return { bytes: body.length };
}
}
For bodies that should not be buffered in memory, use @Context() and consume context.rawRequest as a stream instead.
API Controllers
Controllers are the core building blocks of the Interface API. They group route handlers under a shared base path and provide a structured way to organize HTTP endpoints.
Parameter Handling
The Interface API provides a parameter injection system for controller methods. Parameters are automatically extracted from various request sources and processed before being passed to handler methods.