Overview
Controller types define the function signatures for handling HTTP requests in Asimilation. There are two main controller types: Controller (with extended request/response objects) and BasicController (with standard Node.js HTTP objects).
import type { Types } from '@asimilation/core' ;
// Access types
type Controller = Types . Controller ;
type BasicController = Types . BasicController ;
Type Definitions
Controller
The primary controller type with extended request and response objects that provide additional helper methods.
type Controller = (
req : ArgumentedIncomingMessageAbc ,
res : ArgumentedServerResponseAbc
) => void
req
ArgumentedIncomingMessageAbc
Extended incoming HTTP request object with additional properties:
params: Record<string, string> - URL path parameters from dynamic routes
All standard Node.js IncomingMessage properties (headers, method, url, etc.)
res
ArgumentedServerResponseAbc
Extended HTTP response object with helper methods:
sendJson(json: Object, code: number): void - Send JSON response
sendText(text: string, code: number): void - Send text response
redirect(url: string, code?: number): void - Redirect to another URL
All standard Node.js ServerResponse properties and methods
Controller functions do not return a value. They send responses using the res object.
BasicController
A basic controller type using standard Node.js HTTP objects without extended functionality.
type BasicController = (
req : IncomingMessage ,
res : ServerResponse
) => void
Standard Node.js incoming HTTP request object.
Standard Node.js HTTP response object.
Controller functions do not return a value.
BasicController is primarily for internal use. Use Controller for your route handlers to benefit from the extended functionality.
Examples
Basic Controller
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const getUsers : Types . Controller = ( req , res ) => {
const users = [
{ id: 1 , name: 'Alice' },
{ id: 2 , name: 'Bob' }
];
res . sendJson ({ users }, 200 );
};
url . addPath ( '/users' , getUsers );
Controller with Path Parameters
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const getUserById : Types . Controller = ( req , res ) => {
const { id } = req . params ;
// Fetch user from database
const user = { id , name: 'Alice' };
res . sendJson ({ user }, 200 );
};
url . addPath ( '/users/:id' , getUserById );
Controller with Multiple Parameters
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const getComment : Types . Controller = ( req , res ) => {
const { postId , commentId } = req . params ;
res . sendJson ({
postId ,
commentId ,
comment: 'This is a comment'
}, 200 );
};
url . addPath ( '/posts/:postId/comments/:commentId' , getComment );
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const authenticatedRoute : Types . Controller = ( req , res ) => {
const authHeader = req . headers . authorization ;
if ( ! authHeader ) {
res . sendJson ({ error: 'Missing authorization header' }, 401 );
return ;
}
res . sendJson ({ message: 'Authenticated!' }, 200 );
};
url . addPath ( '/protected' , authenticatedRoute );
Controller with Query Parameters
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const searchUsers : Types . Controller = ( req , res ) => {
// Parse query string from URL
const urlParts = req . url ?. split ( '?' ) || [];
const queryString = urlParts [ 1 ] || '' ;
const params = new URLSearchParams ( queryString );
const search = params . get ( 'q' ) || '' ;
const limit = parseInt ( params . get ( 'limit' ) || '10' );
res . sendJson ({
search ,
limit ,
results: []
}, 200 );
};
url . addPath ( '/search' , searchUsers );
// Usage: GET /search?q=alice&limit=5
Text Response Controller
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const getHello : Types . Controller = ( req , res ) => {
res . sendText ( 'Hello, World!' , 200 );
};
url . addPath ( '/hello' , getHello );
Redirect Controller
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const oldRoute : Types . Controller = ( req , res ) => {
res . redirect ( '/new-route' , 301 ); // Permanent redirect
};
const temporaryRedirect : Types . Controller = ( req , res ) => {
res . redirect ( '/temporary' , 302 ); // Temporary redirect (default)
};
url . addPath ( '/old' , oldRoute );
url . addPath ( '/temp' , temporaryRedirect );
Async Controller Pattern
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const getUsers : Types . Controller = async ( req , res ) => {
try {
// Async operation
const users = await fetchUsersFromDatabase ();
res . sendJson ({ users }, 200 );
} catch ( error ) {
res . sendJson ({ error: 'Failed to fetch users' }, 500 );
}
};
async function fetchUsersFromDatabase () {
// Database query
return [
{ id: 1 , name: 'Alice' },
{ id: 2 , name: 'Bob' }
];
}
url . addPath ( '/users' , getUsers );
Error Handling Controller
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const safeController : Types . Controller = async ( req , res ) => {
try {
const data = await riskyOperation ();
res . sendJson ({ data }, 200 );
} catch ( error ) {
console . error ( 'Error:' , error );
res . sendJson ({
error: 'Internal server error' ,
message: error instanceof Error ? error . message : 'Unknown error'
}, 500 );
}
};
async function riskyOperation () {
throw new Error ( 'Something went wrong' );
}
url . addPath ( '/risky' , safeController );
Controller with Request Body
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
const createUser : Types . Controller = ( req , res ) => {
let body = '' ;
req . on ( 'data' , ( chunk ) => {
body += chunk . toString ();
});
req . on ( 'end' , () => {
try {
const userData = JSON . parse ( body );
// Create user in database
const newUser = {
id: Date . now (),
... userData
};
res . sendJson ({ user: newUser }, 201 );
} catch ( error ) {
res . sendJson ({ error: 'Invalid JSON' }, 400 );
}
});
};
url . addPath ( '/users' , createUser , { methods: [ 'POST' ] });
Request Object Properties
The ArgumentedIncomingMessageAbc object includes:
Property Type Description paramsRecord<string, string>URL path parameters from dynamic routes methodstring | undefinedHTTP method (GET, POST, etc.) urlstring | undefinedRequest URL path and query string headersIncomingHttpHeadersHTTP request headers statusCodenumberHTTP status code
Response Object Methods
The ArgumentedServerResponseAbc object provides:
sendJson()
Sends a JSON response with the specified status code.
res . sendJson ({ message: 'Success' }, 200 );
res . sendJson ({ error: 'Not found' }, 404 );
sendText()
Sends a plain text response with the specified status code.
res . sendText ( 'Hello, World!' , 200 );
res . sendText ( 'Not Found' , 404 );
redirect()
Redirects to another URL with an optional status code (defaults to 302).
res . redirect ( '/new-url' ); // 302 temporary redirect
res . redirect ( '/new-url' , 301 ); // 301 permanent redirect
res . redirect ( '/new-url' , 307 ); // 307 temporary redirect (preserve method)
Type Safety
import { url } from '@asimilation/core' ;
import type { Types } from '@asimilation/core' ;
// Explicitly typed controller
const typedController : Types . Controller = ( req , res ) => {
// TypeScript knows about req.params
const { id } = req . params ; // ✓ Type-safe
// TypeScript knows about res.sendJson
res . sendJson ({ id }, 200 ); // ✓ Type-safe
};
// Inline controller (type inferred)
url . addPath ( '/users/:id' , ( req , res ) => {
// TypeScript infers the types
const { id } = req . params ;
res . sendJson ({ id }, 200 );
});
url.addPath() Register controllers for routes
Middleware Types Middleware function signatures
PathKwargs Route configuration options