Workers
The @zintrust/workers package provides Cloudflare Workers integration for ZinTrust, enabling serverless deployment and edge computing capabilities.
Installation
bash
npm install @zintrust/workersConfiguration
Add the Workers configuration to your environment:
typescript
// config/workers.ts
import { WorkersConfig } from '@zintrust/core';
export const workers: WorkersConfig = {
enabled: true,
runtime: 'cloudflare',
deployment: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
apiToken: process.env.CLOUDFLARE_API_TOKEN,
zoneId: process.env.CLOUDFLARE_ZONE_ID,
},
routes: {
enabled: true,
patterns: [
'api.example.com/*',
'app.example.com/api/*',
],
},
environment: {
variables: {
NODE_ENV: 'production',
LOG_LEVEL: 'info',
},
secrets: {
DATABASE_URL: 'database-url-secret',
API_KEY: 'api-key-secret',
},
},
limits: {
cpuMs: 50000,
memory: 128,
maxRequests: 1000,
},
};Environment Variables
bash
CLOUDFLARE_ACCOUNT_ID=your-account-id
CLOUDFLARE_API_TOKEN=your-api-token
CLOUDFLARE_ZONE_ID=your-zone-id
WORKERS_ENABLED=trueUsage
typescript
import { Workers } from '@zintrust/core';
// Define worker
const apiWorker = Workers.define({
name: 'api-worker',
routes: ['api.example.com/*'],
handler: async (request, env, ctx) => {
const url = new URL(request.url);
if (url.pathname === '/api/users') {
const users = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(users);
}
return new Response('Not Found', { status: 404 });
},
});
// Deploy worker
await Workers.deploy(apiWorker, {
accountId: 'your-account-id',
zoneId: 'your-zone-id',
});
// Get worker metrics
const metrics = await Workers.getMetrics('api-worker');Features
- Serverless Runtime: Cloudflare Workers runtime support
- Edge Deployment: Global edge network deployment
- Route Management: Automatic route configuration
- Environment Variables: Secure environment and secret management
- Performance Monitoring: Built-in performance metrics
- Hot Reloading: Development hot reloading
- Multi-Environment: Support for multiple deployment environments
- Durable Objects: Durable Objects integration
Worker Definition
Basic Worker
typescript
import { Workers } from '@zintrust/workers';
const basicWorker = Workers.define({
name: 'basic-worker',
handler: async (request, env, ctx) => {
// Handle different HTTP methods
if (request.method === 'GET') {
return Response.json({ message: 'Hello from ZinTrust Worker!' });
}
if (request.method === 'POST') {
const body = await request.json();
return Response.json({ received: body });
}
return new Response('Method Not Allowed', { status: 405 });
},
});Advanced Worker
typescript
const advancedWorker = Workers.define({
name: 'advanced-worker',
routes: ['api.example.com/*'],
middleware: [
corsMiddleware,
authMiddleware,
rateLimitMiddleware,
],
handler: async (request, env, ctx) => {
const url = new URL(request.url);
const path = url.pathname;
// Route handling
if (path.startsWith('/api/users')) {
return handleUserRequest(request, env, ctx);
}
if (path.startsWith('/api/posts')) {
return handlePostRequest(request, env, ctx);
}
return new Response('Not Found', { status: 404 });
},
environment: {
variables: {
API_VERSION: 'v1',
MAX_REQUESTS: 1000,
},
secrets: {
DATABASE_URL: 'database-secret',
JWT_SECRET: 'jwt-secret',
},
},
limits: {
cpuMs: 50000,
memory: 128,
},
});Durable Objects Worker
typescript
const durableObjectWorker = Workers.define({
name: 'durable-worker',
durableObjects: {
ChatRoom: {
class: ChatRoomDO,
scriptName: 'chat-room-do',
},
},
handler: async (request, env, ctx) => {
const url = new URL(request.url);
const id = env.ChatRoom.idFromName(url.pathname.split('/')[2]);
const stub = env.ChatRoom.get(id);
return stub.fetch(request);
},
});
class ChatRoomDO {
constructor(state, env) {
this.state = state;
this.env = env;
this.messages = [];
}
async fetch(request) {
const url = new URL(request.url);
if (request.method === 'POST' && url.pathname === '/message') {
const message = await request.json();
this.messages.push({
...message,
timestamp: Date.now(),
});
// Persist to Durable Object storage
await this.state.storage.put('messages', this.messages);
return Response.json({ success: true });
}
if (request.method === 'GET' && url.pathname === '/messages') {
const messages = await this.state.storage.get('messages') || [];
return Response.json(messages);
}
return new Response('Not Found', { status: 404 });
}
}Middleware
CORS Middleware
typescript
import { cors } from '@zintrust/workers';
const corsMiddleware = cors({
origins: ['https://example.com', 'https://app.example.com'],
methods: ['GET', 'POST', 'PUT', 'DELETE'],
headers: ['Content-Type', 'Authorization'],
credentials: true,
});Authentication Middleware
typescript
import { auth } from '@zintrust/workers';
const authMiddleware = auth({
type: 'jwt',
secret: env.JWT_SECRET,
algorithms: ['HS256'],
optional: false,
onError: (error) => {
return Response.json({ error: 'Unauthorized' }, { status: 401 });
},
});Rate Limiting Middleware
typescript
import { rateLimit } from '@zintrust/workers';
const rateLimitMiddleware = rateLimit({
windowMs: 60000, // 1 minute
max: 100, // 100 requests per minute
keyGenerator: (request) => {
return request.headers.get('CF-Connecting-IP') || 'unknown';
},
onLimit: () => {
return Response.json({ error: 'Too Many Requests' }, { status: 429 });
},
});Database Integration
D1 Database
typescript
const d1Worker = Workers.define({
name: 'd1-worker',
bindings: {
DB: {
type: 'd1',
databaseName: 'my-database',
},
},
handler: async (request, env, ctx) => {
if (request.method === 'GET' && request.url.includes('/users')) {
const users = await env.DB.prepare('SELECT * FROM users').all();
return Response.json(users);
}
if (request.method === 'POST' && request.url.includes('/users')) {
const { name, email } = await request.json();
const result = await env.DB.prepare(
'INSERT INTO users (name, email) VALUES (?, ?)'
).bind(name, email).run();
return Response.json({ id: result.meta.last_row_id });
}
return new Response('Not Found', { status: 404 });
},
});KV Storage
typescript
const kvWorker = Workers.define({
name: 'kv-worker',
bindings: {
CACHE: {
type: 'kv',
namespaceId: 'cache-namespace',
},
},
handler: async (request, env, ctx) => {
const url = new URL(request.url);
const key = url.searchParams.get('key');
if (request.method === 'GET' && key) {
const value = await env.CACHE.get(key);
return value ? Response.json({ value }) : new Response('Not Found', { status: 404 });
}
if (request.method === 'PUT' && key) {
const { value, ttl } = await request.json();
await env.CACHE.put(key, JSON.stringify(value), { expirationTtl: ttl });
return Response.json({ success: true });
}
return new Response('Bad Request', { status: 400 });
},
});Deployment
Local Development
typescript
import { WorkersDev } from '@zintrust/workers';
const devServer = new WorkersDev({
port: 8787,
hotReload: true,
env: {
NODE_ENV: 'development',
LOG_LEVEL: 'debug',
},
});
devServer.addWorker(basicWorker);
devServer.addWorker(advancedWorker);
await devServer.start();
console.log('Workers development server running on http://localhost:8787');Production Deployment
typescript
import { WorkersDeploy } from '@zintrust/workers';
const deployer = new WorkersDeploy({
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
apiToken: process.env.CLOUDFLARE_API_TOKEN,
});
// Deploy single worker
await deployer.deploy(basicWorker, {
zoneId: 'your-zone-id',
routes: ['api.example.com/*'],
});
// Deploy multiple workers
await deployer.deployBatch([
{ worker: basicWorker, zoneId: 'zone-1' },
{ worker: advancedWorker, zoneId: 'zone-2' },
]);Environment Management
typescript
// Development environment
const devConfig = {
environment: 'development',
variables: {
NODE_ENV: 'development',
LOG_LEVEL: 'debug',
API_URL: 'http://localhost:3000',
},
secrets: {
DATABASE_URL: 'dev-db-url',
},
};
// Production environment
const prodConfig = {
environment: 'production',
variables: {
NODE_ENV: 'production',
LOG_LEVEL: 'info',
API_URL: 'https://api.example.com',
},
secrets: {
DATABASE_URL: 'prod-db-url',
},
};
// Deploy with environment
await deployer.deploy(basicWorker, {
zoneId: 'your-zone-id',
environment: 'production',
config: prodConfig,
});Performance Monitoring
Metrics Collection
typescript
import { WorkersMetrics } from '@zintrust/workers';
const metrics = new WorkersMetrics({
enabled: true,
interval: 60000, // Collect metrics every minute
destinations: ['prometheus', 'cloudwatch'],
});
// Get worker metrics
const workerMetrics = await metrics.getWorkerMetrics('api-worker');
// Returns: {
// requests: 1000,
// errors: 5,
// averageLatency: 150,
// p95Latency: 300,
// cpuUsage: 45,
// memoryUsage: 67,
// }
// Get route-specific metrics
const routeMetrics = await metrics.getRouteMetrics('api-worker', '/api/users');Performance Optimization
typescript
const optimizedWorker = Workers.define({
name: 'optimized-worker',
optimization: {
caching: {
enabled: true,
ttl: 300, // 5 minutes
strategies: ['memory', 'edge'],
},
compression: {
enabled: true,
algorithms: ['gzip', 'br'],
},
minification: {
enabled: true,
level: 'advanced',
},
},
handler: async (request, env, ctx) => {
// Optimized handler logic
const cacheKey = `response:${request.url}`;
const cached = await env.CACHE.get(cacheKey);
if (cached) {
return new Response(cached, {
headers: { 'X-Cache': 'HIT' },
});
}
const response = await handleRequest(request, env, ctx);
// Cache response
ctx.waitUntil(env.CACHE.put(cacheKey, response.clone().body, {
expirationTtl: 300,
}));
return response;
},
});Security
Security Headers
typescript
import { securityHeaders } from '@zintrust/workers';
const securityMiddleware = securityHeaders({
contentSecurityPolicy: {
directives: {
'default-src': ["'self'"],
'script-src': ["'self'", 'https://cdn.example.com'],
'style-src': ["'self'", 'https://fonts.googleapis.com'],
},
},
hsts: {
maxAge: 31536000,
includeSubdomains: true,
preload: true,
},
frameOptions: 'DENY',
contentTypeOptions: 'nosniff',
});Input Validation
typescript
import { validate } from '@zintrust/workers';
const validationMiddleware = validate({
body: {
type: 'object',
properties: {
name: { type: 'string', minLength: 1, maxLength: 100 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 0, maximum: 150 },
},
required: ['name', 'email'],
},
onError: (errors) => {
return Response.json({ errors }, { status: 400 });
},
});Testing
Unit Testing
typescript
import { WorkersTest } from '@zintrust/workers';
const testEnv = new WorkersTest({
bindings: {
DB: {
type: 'd1',
databaseName: 'test-db',
localMode: true,
},
CACHE: {
type: 'kv',
localMode: true,
},
},
});
// Test worker
test('GET /api/users returns users', async () => {
const request = new Request('https://api.example.com/api/users');
const response = await basicWorker.handler(request, testEnv.env, testEnv.ctx);
expect(response.status).toBe(200);
const users = await response.json();
expect(Array.isArray(users)).toBe(true);
});Integration Testing
typescript
import { WorkersIntegrationTest } from '@zintrust/workers';
const integrationTest = new WorkersIntegrationTest({
accountId: 'test-account',
zoneId: 'test-zone',
workers: [basicWorker, advancedWorker],
});
// Test API endpoints
test('API endpoints work correctly', async () => {
const response = await integrationTest.request('GET', '/api/users');
expect(response.status).toBe(200);
const createResponse = await integrationTest.request('POST', '/api/users', {
name: 'Test User',
email: 'test@example.com',
});
expect(createResponse.status).toBe(201);
});Best Practices
- Keep Workers Small: Minimize worker size for faster cold starts
- Use Caching: Implement caching for frequently accessed data
- Handle Errors: Implement comprehensive error handling
- Monitor Performance: Track worker performance metrics
- Security: Implement proper security headers and validation
- Environment Management: Use different configs for different environments
- Testing: Write comprehensive tests for workers
- Documentation: Document worker APIs and usage
Limitations
- CPU Time: Limited CPU time per request (50ms for free tier)
- Memory: Limited memory (128MB for free tier)
- Request Size: Maximum request size limitations
- Execution Time: Maximum execution time limits
- Storage: Limited storage capabilities
- External APIs: Rate limits on external API calls
Troubleshooting
Common Issues
- Cold Starts: Optimize worker code for faster cold starts
- Memory Issues: Reduce memory usage and optimize data structures
- Timeout Errors: Increase timeout limits or optimize code
- Deployment Issues: Check configuration and credentials
- Route Issues: Verify route patterns and zone configuration
Debug Mode
typescript
export const workers: WorkersConfig = {
enabled: true,
debug: process.env.NODE_ENV === 'development',
logging: {
level: 'debug',
logRequests: true,
logResponses: false,
logErrors: true,
logPerformance: true,
},
};