Enhanced request context with built-in utilities, HTTP client, logging, background task execution, and seamless integration with Egg.js services and middleware.
Extended context class that provides request-scoped access to application services, utilities, and enhanced functionality.
/**
* Enhanced request context extending EggCore Context
*/
class Context extends EggCoreContext {
/** Application instance reference */
app: Application;
/** Enhanced request object */
request: Request;
/** Enhanced response object */
response: Response;
/** Service container with all loaded services */
service: BaseContextClass;
/** Request start timestamp */
starttime: number;
/** Performance timer start time */
performanceStarttime: number;
/** Request cookies with signing support */
get cookies(): Cookies;
/** Context-aware HTTP client */
get httpclient(): HttpClient;
get httpClient(): HttpClient; // Alias
/** Router instance */
get router(): Router;
set router(val: Router);
/** Helper utilities instance */
get helper(): Helper;
/** Application logger */
get logger(): EggLogger;
/** Core framework logger */
get coreLogger(): EggLogger;
/** View locals (merged with app.locals) */
get locals(): Record<string, any>;
set locals(val: Record<string, any>);
/** Alias for locals (Koa compatibility) */
get state(): Record<string, any>;
set state(val: Record<string, any>);
/** Make HTTP request with context */
curl<T = any>(url: HttpClientRequestURL, options?: HttpClientRequestOptions): Promise<HttpClientResponse<T>>;
/** Run async function in background */
runInBackground(scope: (ctx: Context) => Promise<void>, taskName?: string): void;
/** Get logger by name */
getLogger(name: string): EggLogger;
}Usage Examples:
// In controller or middleware
export default class HomeController extends Controller {
async index() {
const { ctx } = this;
// Access request information
console.log('Request start time:', ctx.starttime);
console.log('User IP:', ctx.ip);
console.log('Query params:', ctx.query);
// Use HTTP client
const response = await ctx.curl('https://api.example.com/data', {
method: 'GET',
dataType: 'json'
});
// Set response
ctx.body = {
message: 'Hello World',
data: response.data
};
// Run background task
ctx.runInBackground(async (ctx) => {
await ctx.service.analytics.track('page_view', {
path: ctx.path,
userAgent: ctx.get('user-agent')
});
});
}
}Enhanced request properties with additional utilities.
/** Whether request accepts JSON response */
get acceptJSON(): boolean;
/** Query parameters as key-value pairs */
get query(): Record<string, string>;
/** Query parameters with array support */
get queries(): Record<string, string[]>;
/** Client IP address (respects proxy headers) */
get ip(): string;
set ip(val: string);Usage Examples:
// In controller
async handleRequest() {
const { ctx } = this;
// Check if client accepts JSON
if (ctx.acceptJSON) {
ctx.body = { status: 'ok', data: someData };
} else {
await ctx.render('template.html', { data: someData });
}
// Handle query parameters
const userId = ctx.query.userId;
const tags = ctx.queries.tags; // ['tag1', 'tag2'] for ?tags=tag1&tags=tag2
// Log client information
ctx.logger.info('Request from IP: %s', ctx.ip);
}Enhanced response properties for status and header management.
/** Real response status (may differ from ctx.status for logging) */
get realStatus(): number;
set realStatus(val: number);Usage Examples:
// In error handling middleware
async errorHandler(ctx, next) {
try {
await next();
} catch (err) {
// Set real status for logging
ctx.realStatus = err.status || 500;
// Set user-facing status
ctx.status = err.expose ? err.status : 500;
ctx.body = { error: err.expose ? err.message : 'Internal Error' };
}
}Execute async tasks without blocking the request response.
/**
* Run async function in the background without blocking response
* @param scope - Function to execute, receives context as parameter
* @param taskName - Optional task name for logging
*/
runInBackground(scope: (ctx: Context) => Promise<void>, taskName?: string): void;
/**
* Internal method for background task execution (can be overridden by plugins)
* @param scope - Function to execute
* @param taskName - Task name for logging
*/
_runInBackground(scope: (ctx: Context) => Promise<void>, taskName: string): Promise<void>;Usage Examples:
// In controller
async createUser() {
const { ctx } = this;
const userData = ctx.request.body;
// Create user synchronously
const user = await ctx.service.user.create(userData);
// Send welcome email in background
ctx.runInBackground(async (ctx) => {
await ctx.service.email.sendWelcome(user.email, {
name: user.name,
activationLink: ctx.helper.urlFor('activation', { token: user.token })
});
}, 'send-welcome-email');
// Respond immediately
ctx.body = { success: true, user };
}
// Custom background task name
ctx.runInBackground(async (ctx) => {
await processLargeDataset();
}, 'process-dataset');Additional context-aware utilities and helpers.
/** Request/Response extensions */
class Request extends EggCoreRequest {
declare app: EggCore;
declare response: Response;
declare ctx: Context;
}
class Response extends EggCoreResponse {
declare app: EggCore;
declare request: Request;
declare ctx: Context;
}Usage Examples:
// Access enhanced request/response
async uploadFile() {
const { ctx } = this;
// Request enhancements
const files = ctx.request.files;
const body = ctx.request.body;
// Response enhancements
ctx.response.attachment('download.pdf');
ctx.response.type = 'application/pdf';
// Context integration
ctx.logger.info('File upload from %s', ctx.request.ip);
}interface Cookies extends ContextCookies {
request: any;
response: any;
}
interface HttpClientRequestOptions extends RequestOptions {
ctx?: any;
tracer?: any;
}
type HttpClientRequestURL = string | URL | RequestURLObject;
interface HttpClientResponse<T = any> {
status: number;
headers: Record<string, string>;
data: T;
res: IncomingMessage;
}