Core Concepts
Detailed explanation of the fundamental concepts and architecture of the C15T Backend package, including instance management, context system, and request handling.
This document covers the fundamental concepts and architecture of the C15T Backend package.
Instance Management
Creating an Instance
The C15T instance is the core of the system, managing all components and their interactions:
import { c15tInstance } from '@c15t/backend';
import { memoryAdapter } from '@c15t/backend/db/adapters/memory';
const instance = c15tInstance({
baseURL: 'http://localhost:3000',
database: memoryAdapter({}),
plugins: [],
context: {},
});
For a quick start guide, see Getting Started.
Instance Configuration
The instance configuration includes:
interface C15TOptions {
// Base URL for the API
baseURL: string;
// Database adapter
database: DatabaseAdapter;
// Optional base path for API routes
basePath?: string;
// Trusted origins for CORS
trustedOrigins?: string[] | ((request: Request) => string[]);
// Plugin configurations
plugins?: C15TPlugin[];
// Additional context data
context?: Record<string, unknown>;
// Authentication configuration
auth?: AuthConfig;
// Rate limiting configuration
rateLimit?: RateLimitConfig;
}
Learn more about database adapters in Database Adapters.
Context System
Context Structure
The context is a shared state that persists throughout the request lifecycle:
interface C15TContext {
// Request-specific data
request: Request;
response?: Response;
// Database access
database: DatabaseAdapter;
// Authentication data
auth?: {
userId: string;
roles: string[];
metadata?: Record<string, unknown>;
};
// Plugin data
plugins: Record<string, PluginData>;
// Custom context data
[key: string]: unknown;
}
Context Extensions
Plugins can extend the context with additional data:
const contextPlugin: C15TPlugin = {
id: 'context-plugin',
name: 'Context Plugin',
type: 'core',
init: () => ({
context: {
customData: {
timestamp: Date.now(),
requestId: generateId(),
},
},
}),
};
Learn more about plugins in Plugin System.
Request Handling
Request Flow
-
Request Reception
const request = new Request('http://localhost:3000/api/c15t/status', { method: 'GET', headers: { 'Accept': 'application/json', 'Origin': 'http://localhost:3000', }, });
-
Request Processing
const response = await instance.handler(request);
-
Response Generation
if (response.isOk()) { const data = await response.value.json(); console.log(data); } else { console.error(response.error); }
For API endpoint details, see API Endpoints.
Request Lifecycle
-
Pre-processing
const preProcessed = await instance.preProcess(request);
-
Authentication
const authenticated = await instance.authenticate(preProcessed);
-
Authorization
const authorized = await instance.authorize(authenticated);
-
Handler Execution
const result = await instance.executeHandler(authorized);
-
Post-processing
const response = await instance.postProcess(result);
Response Processing
Response Types
interface C15TResponse<T = unknown> {
// Response data
data?: T;
// Response metadata
metadata?: {
timestamp: string;
requestId: string;
processingTime: number;
};
// Response status
status: number;
// Response headers
headers: Headers;
}
For API response formats, see API Endpoints.
Response Formatting
const formatResponse = (data: unknown): C15TResponse => ({
data,
metadata: {
timestamp: new Date().toISOString(),
requestId: generateId(),
processingTime: Date.now() - startTime,
},
status: 200,
headers: new Headers({
'Content-Type': 'application/json',
}),
});
Error Handling
Error Types
// Authentication errors
class AuthenticationError extends C15TError {
constructor(message: string) {
super(message, 401);
}
}
// Authorization errors
class AuthorizationError extends C15TError {
constructor(message: string) {
super(message, 403);
}
}
// Validation errors
class ValidationError extends C15TError {
constructor(message: string, details?: Record<string, unknown>) {
super(message, 400, details);
}
}
// Database errors
class DatabaseError extends C15TError {
constructor(message: string) {
super(message, 500);
}
}
For error handling in plugins, see Plugin System.
Error Handling
try {
const response = await instance.handler(request);
} catch (error) {
if (error instanceof AuthenticationError) {
// Handle authentication errors
} else if (error instanceof AuthorizationError) {
// Handle authorization errors
} else if (error instanceof ValidationError) {
// Handle validation errors
} else if (error instanceof DatabaseError) {
// Handle database errors
} else {
// Handle unexpected errors
}
}
Middleware System
Middleware Types
-
Request Middleware
const requestMiddleware = async (request: Request, ctx: C15TContext) => { // Modify request return { request }; };
-
Response Middleware
const responseMiddleware = async (response: Response, ctx: C15TContext) => { // Modify response return { response }; };
-
Error Middleware
const errorMiddleware = async (error: Error, ctx: C15TContext) => { // Handle error return { error }; };
Learn more about middleware in Plugin System.
Middleware Chain
const middlewareChain = [
requestMiddleware,
authMiddleware,
validationMiddleware,
responseMiddleware,
];
const result = await middlewareChain.reduce(
async (acc, middleware) => middleware(acc, ctx),
request
);
Event System
Event Types
interface C15TEvent {
type: string;
data: unknown;
timestamp: string;
metadata?: Record<string, unknown>;
}
Event Handling
const eventHandler = async (event: C15TEvent) => {
switch (event.type) {
case 'request.received':
// Handle request received
break;
case 'response.sent':
// Handle response sent
break;
case 'error.occurred':
// Handle error occurred
break;
}
};
Event Emission
const emitEvent = async (type: string, data: unknown) => {
const event: C15TEvent = {
type,
data,
timestamp: new Date().toISOString(),
};
await eventHandler(event);
};
Testing
Test Utilities
import { createTestInstance, createTestRequest } from '@c15t/backend/testing';
describe('Core Functionality', () => {
it('should handle requests', async () => {
const instance = createTestInstance();
const request = createTestRequest({
url: 'http://localhost:3000/api/c15t/status',
method: 'GET',
});
const response = await instance.handler(request);
expect(response.status).toBe(200);
});
});
Mock Context
import { createMockContext } from '@c15t/backend/testing';
const ctx = createMockContext({
database: mockDatabase,
auth: {
userId: 'test-user',
roles: ['admin'],
},
});
Performance Optimization
Caching
const cache = new Map<string, unknown>();
const getCachedData = async (key: string) => {
if (cache.has(key)) {
return cache.get(key);
}
const data = await fetchData();
cache.set(key, data);
return data;
};
For database performance, see Database Adapters.
Connection Pooling
const pool = new Pool({
max: 20,
idleTimeoutMillis: 30000,
});
const getConnection = async () => {
return await pool.connect();
};
Request Batching
const batchRequests = async (requests: Request[]) => {
return await Promise.all(
requests.map(request => instance.handler(request))
);
};