🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Exemplos de Koa
Exemplos do framework de middleware Node.js Koa incluindo encadeamento de middleware, tratamento de contexto, padrões async/await e integração com ecossistema
💻 Olá Mundo com Koa javascript
🟢 simple
Configuração básica do servidor Koa com middleware, roteamento, handlers async e padrões modernos de JavaScript
// Koa Hello World Examples
// 1. Basic Koa Server
const Koa = require('koa');
const app = new Koa();
// Middleware function
app.use(async ctx => {
ctx.body = 'Hello Koa!';
});
app.listen(3000);
console.log('Server running on http://localhost:3000');
// 2. Koa with Multiple Middleware
const Koa = require('koa');
const app = new Koa();
// Logger middleware
app.use(async (ctx, next) => {
console.log(`${new Date().toISOString()} ${ctx.method} ${ctx.url}`);
await next();
console.log(`Response status: ${ctx.status}`);
});
// Error handling middleware
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.status || 500;
ctx.body = { error: err.message };
ctx.app.emit('error', err, ctx);
}
});
// Response time middleware
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
});
// Route handler
app.use(async ctx => {
ctx.body = {
message: 'Hello from Koa with middleware!',
method: ctx.method,
url: ctx.url,
headers: ctx.headers
};
});
app.listen(3000);
console.log('Server with middleware running on http://localhost:3000');
// 3. Koa Router with REST API
const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new Router();
// Middleware
app.use(bodyParser());
// Mock data store
let users = [
{ id: 1, name: 'John Doe', email: '[email protected]', age: 30 },
{ id: 2, name: 'Jane Smith', email: '[email protected]', age: 25 }
];
// Routes
router.get('/api/users', async (ctx) => {
ctx.body = { users, total: users.length };
});
router.get('/api/users/:id', async (ctx) => {
const id = parseInt(ctx.params.id);
const user = users.find(u => u.id === id);
if (!user) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
ctx.body = user;
});
router.post('/api/users', async (ctx) => {
const { name, email, age } = ctx.request.body;
if (!name || !email) {
ctx.status = 400;
ctx.body = { error: 'Name and email are required' };
return;
}
const newUser = {
id: users.length + 1,
name,
email,
age: age || null
};
users.push(newUser);
ctx.status = 201;
ctx.body = newUser;
});
router.put('/api/users/:id', async (ctx) => {
const id = parseInt(ctx.params.id);
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
users[userIndex] = { ...users[userIndex], ...ctx.request.body };
ctx.body = users[userIndex];
});
router.delete('/api/users/:id', async (ctx) => {
const id = parseInt(ctx.params.id);
const userIndex = users.findIndex(u => u.id === id);
if (userIndex === -1) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
users.splice(userIndex, 1);
ctx.status = 204;
});
// Health check
router.get('/health', async (ctx) => {
ctx.body = {
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime()
};
});
// Mount routes
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
console.log('REST API server running on http://localhost:3000');
// 4. Koa with Custom Middleware
const Koa = require('koa');
const app = new Koa();
// Custom authentication middleware
const authMiddleware = (options = {}) => {
return async (ctx, next) => {
// Skip authentication for certain paths
if (ctx.path.startsWith('/public') || ctx.path === '/') {
await next();
return;
}
const token = ctx.headers.authorization?.replace('Bearer ', '');
if (!token) {
ctx.status = 401;
ctx.body = { error: 'No token provided' };
return;
}
// Mock authentication (use proper JWT validation in production)
if (token !== 'valid-token') {
ctx.status = 401;
ctx.body = { error: 'Invalid token' };
return;
}
// Set user in context
ctx.state.user = { id: 1, name: 'John Doe', role: 'user' };
await next();
};
};
// Custom CORS middleware
const corsMiddleware = (options = {}) => {
const defaults = {
origin: '*',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization']
};
const config = { ...defaults, ...options };
return async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', config.origin);
ctx.set('Access-Control-Allow-Methods', config.allowMethods.join(', '));
ctx.set('Access-Control-Allow-Headers', config.allowHeaders.join(', '));
if (ctx.method === 'OPTIONS') {
ctx.status = 204;
return;
}
await next();
};
};
// Custom rate limiting middleware
const rateLimitMiddleware = (options = {}) => {
const defaults = {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests, please try again later'
};
const config = { ...defaults, ...options };
const requests = new Map();
return async (ctx, next) => {
const ip = ctx.ip;
const now = Date.now();
if (!requests.has(ip)) {
requests.set(ip, { count: 0, resetTime: now + config.windowMs });
}
const requestData = requests.get(ip);
if (now > requestData.resetTime) {
requestData.count = 0;
requestData.resetTime = now + config.windowMs;
}
requestData.count++;
if (requestData.count > config.max) {
ctx.status = 429;
ctx.body = { error: config.message };
return;
}
await next();
};
};
// Apply middleware
app.use(corsMiddleware({ origin: 'http://localhost:3000' }));
app.use(rateLimitMiddleware({ max: 10, windowMs: 60000 })); // 10 requests per minute
app.use(authMiddleware());
// Routes
app.use(async (ctx) => {
ctx.body = {
message: 'Protected content',
user: ctx.state.user,
path: ctx.path,
method: ctx.method
};
});
// Public route
app.use(async (ctx, next) => {
if (ctx.path === '/public/info') {
ctx.body = { message: 'This is public information' };
return;
}
await next();
});
app.listen(3000);
console.log('Server with custom middleware running on http://localhost:3000');
// 5. Koa with Error Handling and Validation
const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');
const { Joi } = require('koa-joi-router');
const app = new Koa();
const router = new Router();
// Custom error class
class AppError extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
this.isOperational = true;
}
}
// Validation schema
const userSchema = Joi.object({
name: Joi.string().min(2).max(50).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(0).max(150).optional()
});
// Error handling middleware
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
console.error('Error:', err);
if (err.isJoi) {
// Validation error
ctx.status = 400;
ctx.body = {
error: 'Validation Error',
details: err.details.map(detail => ({
field: detail.path.join('.'),
message: detail.message
}))
};
} else if (err.isOperational) {
// Operational error
ctx.status = err.statusCode || 500;
ctx.body = { error: err.message };
} else {
// Programming error
ctx.status = 500;
ctx.body = { error: 'Internal Server Error' };
}
}
});
// Request validation middleware
const validate = (schema) => {
return async (ctx, next) => {
const { error, value } = schema.validate(ctx.request.body);
if (error) {
error.isJoi = true;
throw error;
}
ctx.request.validatedBody = value;
await next();
};
};
// Middleware
app.use(bodyParser());
// Routes with validation
router.post('/api/users', validate(userSchema), async (ctx) => {
const userData = ctx.request.validatedBody;
// Simulate database operation
const newUser = {
id: Date.now(),
...userData,
createdAt: new Date().toISOString()
};
ctx.status = 201;
ctx.body = {
message: 'User created successfully',
user: newUser
};
});
// Route that throws operational error
router.get('/api/error', async (ctx) => {
throw new AppError('This is an operational error', 400);
});
// Route that throws programming error
router.get('/api/crash', async (ctx) => {
throw new Error('Unexpected error occurred');
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
console.log('Server with error handling running on http://localhost:3000');
// 6. Koa with File Uploads and Static Files
const Koa = require('koa');
const Router = require('@koa/router');
const serve = require('koa-static');
const mount = require('koa-mount');
const formidable = require('koa-formidable');
const path = require('path');
const fs = require('fs').promises;
const app = new Koa();
const router = new Router();
// Serve static files
app.use(mount('/public', serve(path.join(__dirname, 'public'))));
// Ensure upload directory exists
const uploadDir = path.join(__dirname, 'uploads');
fs.mkdir(uploadDir, { recursive: true }).catch(console.error);
// File upload middleware
const uploadMiddleware = formidable({
uploadDir,
keepExtensions: true,
maxFileSize: 10 * 1024 * 1024, // 10MB
multiples: true
});
// Single file upload
router.post('/upload', uploadMiddleware, async (ctx) => {
try {
const files = ctx.request.files;
const file = files.file; // 'file' is the field name
if (!file) {
ctx.status = 400;
ctx.body = { error: 'No file uploaded' };
return;
}
ctx.body = {
message: 'File uploaded successfully',
file: {
name: file.name,
path: file.path,
size: file.size,
type: file.type
}
};
} catch (error) {
console.error('Upload error:', error);
ctx.status = 500;
ctx.body = { error: 'File upload failed' };
}
});
// Multiple files upload
router.post('/upload/multiple', uploadMiddleware, async (ctx) => {
try {
const files = ctx.request.files;
const uploadedFiles = [];
for (const [fieldName, fileArray] of Object.entries(files)) {
if (Array.isArray(fileArray)) {
fileArray.forEach(file => {
uploadedFiles.push({
field: fieldName,
name: file.name,
path: file.path,
size: file.size,
type: file.type
});
});
} else {
uploadedFiles.push({
field: fieldName,
name: fileArray.name,
path: fileArray.path,
size: fileArray.size,
type: fileArray.type
});
}
}
ctx.body = {
message: 'Files uploaded successfully',
files: uploadedFiles,
count: uploadedFiles.length
};
} catch (error) {
console.error('Multiple upload error:', error);
ctx.status = 500;
ctx.body = { error: 'Multiple file upload failed' };
}
});
// File download
router.get('/download/:filename', async (ctx) => {
try {
const filename = ctx.params.filename;
const filePath = path.join(uploadDir, filename);
const stats = await fs.stat(filePath);
ctx.set('Content-Disposition', `attachment; filename="${filename}"`);
ctx.set('Content-Type', 'application/octet-stream');
ctx.body = await fs.readFile(filePath);
} catch (error) {
ctx.status = 404;
ctx.body = { error: 'File not found' };
}
});
// List uploaded files
router.get('/files', async (ctx) => {
try {
const files = await fs.readdir(uploadDir);
const fileInfos = [];
for (const file of files) {
const filePath = path.join(uploadDir, file);
const stats = await fs.stat(filePath);
fileInfos.push({
name: file,
size: stats.size,
createdAt: stats.birthtime.toISOString(),
downloadUrl: `/download/${file}`
});
}
ctx.body = {
files: fileInfos,
count: fileInfos.length
};
} catch (error) {
ctx.status = 500;
ctx.body = { error: 'Failed to list files' };
}
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
console.log('File server running on http://localhost:3000');
// 7. Koa with Session Management
const Koa = require('koa');
const Router = require('@koa/router');
const session = require('koa-session');
const bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new Router();
// Session configuration
const sessionConfig = {
key: 'koa.sess', // cookie key
maxAge: 86400000, // 24 hours
autoCommit: true,
overwrite: true,
httpOnly: true,
signed: true,
rolling: false,
renew: false,
secure: false, // set to true in production with HTTPS
sameSite: null
};
app.keys = ['your-secret-key'];
// Middleware
app.use(session(sessionConfig, app));
app.use(bodyParser());
// Authentication routes
router.post('/login', async (ctx) => {
const { username, password } = ctx.request.body;
// Mock authentication (use proper password hashing in production)
if (username === 'admin' && password === 'password') {
ctx.session.user = {
id: 1,
username: 'admin',
role: 'admin'
};
ctx.body = {
message: 'Login successful',
user: ctx.session.user
};
} else {
ctx.status = 401;
ctx.body = { error: 'Invalid credentials' };
}
});
router.post('/logout', async (ctx) => {
ctx.session = null;
ctx.body = { message: 'Logged out successfully' };
});
router.get('/profile', async (ctx) => {
if (!ctx.session.user) {
ctx.status = 401;
ctx.body = { error: 'Not authenticated' };
return;
}
ctx.body = {
user: ctx.session.user,
sessionId: ctx.sessionId,
visits: (ctx.session.visits || 0) + 1
};
ctx.session.visits = (ctx.session.visits || 0) + 1;
});
// Shopping cart example
router.get('/cart', async (ctx) => {
const cart = ctx.session.cart || [];
ctx.body = { cart };
});
router.post('/cart/add', async (ctx) => {
const { productId, name, price } = ctx.request.body;
if (!ctx.session.cart) {
ctx.session.cart = [];
}
const existingItem = ctx.session.cart.find(item => item.productId === productId);
if (existingItem) {
existingItem.quantity += 1;
} else {
ctx.session.cart.push({
productId,
name,
price: parseFloat(price),
quantity: 1
});
}
ctx.body = {
message: 'Item added to cart',
cart: ctx.session.cart
};
});
router.delete('/cart/:productId', async (ctx) => {
const productId = parseInt(ctx.params.productId);
if (ctx.session.cart) {
ctx.session.cart = ctx.session.cart.filter(item => item.productId !== productId);
}
ctx.body = { message: 'Item removed from cart' };
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
console.log('Session-enabled server running on http://localhost:3000');
// 8. Koa with Database Integration (MongoDB)
const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-bodyparser');
const mongoose = require('mongoose');
const app = new Koa();
const router = new Router();
// MongoDB connection
mongoose.connect('mongodb://localhost:27017/koa-app', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// User model
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
age: { type: Number, min: 0, max: 150 },
createdAt: { type: Date, default: Date.now }
});
const User = mongoose.model('User', UserSchema);
// Middleware
app.use(bodyParser());
app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
ctx.status = err.status || 500;
ctx.body = { error: err.message };
}
});
// CRUD routes
router.post('/api/users', async (ctx) => {
try {
const user = new User(ctx.request.body);
await user.save();
ctx.status = 201;
ctx.body = user;
} catch (err) {
ctx.status = 400;
ctx.body = { error: err.message };
}
});
router.get('/api/users', async (ctx) => {
const users = await User.find();
ctx.body = { users, total: users.length };
});
router.get('/api/users/:id', async (ctx) => {
try {
const user = await User.findById(ctx.params.id);
if (!user) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
ctx.body = user;
} catch (err) {
ctx.status = 400;
ctx.body = { error: 'Invalid user ID' };
}
});
router.put('/api/users/:id', async (ctx) => {
try {
const user = await User.findByIdAndUpdate(
ctx.params.id,
ctx.request.body,
{ new: true, runValidators: true }
);
if (!user) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
ctx.body = user;
} catch (err) {
ctx.status = 400;
ctx.body = { error: err.message };
}
});
router.delete('/api/users/:id', async (ctx) => {
try {
const user = await User.findByIdAndDelete(ctx.params.id);
if (!user) {
ctx.status = 404;
ctx.body = { error: 'User not found' };
return;
}
ctx.status = 204;
} catch (err) {
ctx.status = 400;
ctx.body = { error: 'Invalid user ID' };
}
});
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
console.log('Database-enabled server running on http://localhost:3000');
// 9. Koa with WebSocket Support
const Koa = require('koa');
const Router = require('@koa/router');
const WebSocket = require('ws');
const http = require('http');
const app = new Koa();
const router = new Router();
const server = http.createServer(app.callback());
// WebSocket server
const wss = new WebSocket.Server({ server });
// Store connected clients
const clients = new Set();
wss.on('connection', (ws) => {
clients.add(ws);
console.log('Client connected, total clients:', clients.size);
// Send welcome message
ws.send(JSON.stringify({
type: 'welcome',
message: 'Connected to chat server',
timestamp: new Date().toISOString()
}));
// Handle incoming messages
ws.on('message', (data) => {
try {
const message = JSON.parse(data);
// Broadcast message to all clients
const broadcast = {
type: 'message',
data: message,
timestamp: new Date().toISOString()
};
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(broadcast));
}
});
} catch (error) {
console.error('Invalid message format:', error);
}
});
// Handle client disconnection
ws.on('close', () => {
clients.delete(ws);
console.log('Client disconnected, total clients:', clients.size);
// Notify other clients
const notification = {
type: 'notification',
message: 'A user left the chat',
userCount: clients.size,
timestamp: new Date().toISOString()
};
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(notification));
}
});
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
clients.delete(ws);
});
});
// HTTP routes
router.get('/', async (ctx) => {
ctx.body = {
message: 'Koa WebSocket Server',
connectedClients: clients.size,
endpoints: [
'GET / - Server info',
'GET /clients - Connected clients count',
'WebSocket ws://localhost:3000 - WebSocket endpoint'
]
};
});
router.get('/clients', async (ctx) => {
ctx.body = {
connectedClients: clients.size,
timestamp: new Date().toISOString()
};
});
// Broadcast API
router.post('/broadcast', async (ctx) => {
const { message, type = 'notification' } = ctx.request.body;
const broadcast = {
type,
message,
timestamp: new Date().toISOString()
};
clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(broadcast));
}
});
ctx.body = {
message: 'Broadcast sent to all clients',
clientCount: clients.size
};
});
app.use(router.routes());
app.use(router.allowedMethods());
// Start server
server.listen(3000, () => {
console.log('WebSocket server running on http://localhost:3000');
console.log('Connect with WebSocket client to ws://localhost:3000');
});
// 10. Koa Production Best Practices
const Koa = require('koa');
const Router = require('@koa/router');
const helmet = require('koa-helmet');
const compress = require('koa-compress');
const cors = require('@koa/cors');
const bodyParser = require('koa-bodyparser');
const rateLimit = require('koa-ratelimit');
const app = new Koa();
const router = new Router();
// Security middleware
app.use(helmet());
// Compression middleware
app.use(compress({
filter: (contentType) => {
return /text|javascript|json/i.test(contentType);
},
threshold: 1024,
gzip: {
flush: require('zlib').constants.Z_SYNC_FLUSH
},
deflate: {
flush: require('zlib').constants.Z_SYNC_FLUSH
},
br: false // disable brotli
}));
// CORS middleware
app.use(cors({
origin: process.env.CORS_ORIGIN || '*',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
credentials: true
}));
// Rate limiting
app.use(rateLimit({
driver: 'memory',
db: new Map(),
duration: 60000, // 1 minute
max: 100, // 100 requests per minute
id: (ctx) => ctx.ip,
disableHeader: false,
whitelist: (ctx) => {
// Whitelist local development
return ctx.ip === '127.0.0.1' || ctx.ip === '::1';
},
blacklist: (ctx) => {
// Example: block specific IPs
return false;
}
}));
// Body parser with security options
app.use(bodyParser({
enableTypes: ['json', 'form'],
jsonLimit: '10mb',
formLimit: '10mb',
textLimit: '10mb',
strict: true, // only accept objects and arrays
detectJSON: (ctx) => {
return ctx.request.is('json');
}
}));
// Request logging
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${new Date().toISOString()} ${ctx.method} ${ctx.url} - ${ctx.status} - ${ms}ms`);
});
// Health check endpoint
router.get('/health', async (ctx) => {
ctx.body = {
status: 'ok',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage(),
environment: process.env.NODE_ENV || 'development'
};
});
// API versioning
router.get('/api/v1/info', async (ctx) => {
ctx.body = {
name: 'Koa Production API',
version: '1.0.0',
environment: process.env.NODE_ENV || 'development',
nodeVersion: process.version,
uptime: process.uptime()
};
});
// Graceful shutdown
const gracefulShutdown = (signal) => {
console.log(`
Received ${signal}. Starting graceful shutdown...`);
server.close(() => {
console.log('HTTP server closed');
process.exit(0);
});
// Force close after 10 seconds
setTimeout(() => {
console.error('Could not close connections in time, forcefully shutting down');
process.exit(1);
}, 10000);
};
// Handle shutdown signals
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
// Handle uncaught exceptions
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
gracefulShutdown('uncaughtException');
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
app.use(router.routes());
app.use(router.allowedMethods());
const server = app.listen(3000, () => {
console.log('🚀 Production-ready Koa server running on http://localhost:3000');
});