@200systems/mf-express-adapter
Express.js integration adapter para o microframework TypeScript com middleware estruturado, controllers base e tratamento de erros.
Features Implementadas
- 🚀 ExpressApp Class - Classe principal com configuração Express pré-configurada
- 📋 BaseController - Controller base com async handlers e utilitários
- 🛡️ Middleware Stack - Error handling, request logging e response formatting
- 🔐 JWT Authentication - Middleware de autenticação JWT com role-based access
- 📊 Response Helpers - Formatação padronizada de respostas da API
- ✅ Validation Utilities - Helpers de validação e sanitização
- 📄 Pagination Support - Utilitários de paginação e ordenação
Instalação
npm install @200systems/mf-express-adapter
Peer Dependencies
npm install express cors helmet compression express-rate-limit jsonwebtoken
npm install --save-dev @types/express @types/cors @types/compression @types/jsonwebtoken
Quick Start
1. Configuração Básica da Aplicação
import { ExpressApp } from '@200systems/mf-express-adapter';
import { createLogger } from '@200systems/mf-logger';
const app = new ExpressApp({
port: 3000,
host: '0.0.0.0',
cors: {
origin: process.env.CORS_ORIGIN || 'http://localhost:5173',
credentials: true
},
trustProxy: true,
security: {
helmet: true,
rateLimit: {
windowMs: 15 * 60 * 1000,
max: 100
}
}
});
app.start().then(() => {
console.log('Server started successfully');
});
2. JWT Authentication Setup
import { JwtMiddleware } from '@200systems/mf-express-adapter';
import { createLogger } from '@200systems/mf-logger';
const logger = createLogger({ context: 'auth' });
export const jwtAuth = new JwtMiddleware({
secret: process.env.JWT_SECRET || 'your-secret-key',
algorithms: ['HS256'],
skipPaths: ['/auth/login', '/auth/register', '/health'],
headerName: 'authorization',
cookieName: 'token'
}, logger);
import { Router } from 'express';
const router = Router();
router.get('/profile', jwtAuth.authenticate, userController.getProfile);
router.get('/public', jwtAuth.optional, contentController.getPublicContent);
router.delete('/admin/users/:id',
jwtAuth.authenticate,
jwtAuth.requireRole(['admin', 'super-admin']),
adminController.deleteUser
);
3. Controller Implementation
import { Request, Response, NextFunction } from 'express';
import { BaseController, AuthenticatedRequest } from '@200systems/mf-express-adapter';
import { Logger } from '@200systems/mf-logger';
import { ServiceResult } from '@200systems/mf-service-base';
export class UserController extends BaseController {
constructor(logger: Logger, private userService: UserService) {
super(logger);
}
getProfile = this.asyncHandler(async (req: AuthenticatedRequest, res: Response): Promise<ServiceResult<User>> => {
const userId = req.user!.userId;
const user = await this.userService.getUserById(userId);
return ServiceResult.success(user);
});
login = this.asyncHandler(async (req: Request, res: Response): Promise<ServiceResult<LoginResponse>> => {
const { email, password } = req.body;
const user = await this.userService.authenticateUser(email, password);
const token = JwtMiddleware.generateToken(
{ userId: user.id, email: user.email, roles: user.roles },
process.env.JWT_SECRET!,
'24h'
);
return ServiceResult.success({ user, token });
});
}
4. Login/Logout Implementation
export class AuthController extends BaseController {
login = this.asyncHandler(async (req: Request, res: Response): Promise<void> => {
const { email, password } = req.body;
const user = await this.authService.login(email, password);
const token = JwtMiddleware.generateToken(
{
userId: user.id,
email: user.email,
roles: user.roles || []
},
process.env.JWT_SECRET!,
'24h'
);
res.cookie('token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 24 * 60 * 60 * 1000
});
res.json({
success: true,
data: { user, token },
meta: { timestamp: new Date().toISOString() }
});
});
logout = this.asyncHandler(async (req: Request, res: Response): Promise<void> => {
res.clearCookie('token');
res.json({
success: true,
message: 'Logged out successfully',
meta: { timestamp: new Date().toISOString() }
});
});
}
API Reference
JwtMiddleware
interface JwtMiddlewareConfig {
secret?: string;
algorithms?: string[];
skipPaths?: string[];
cookieName?: string;
headerName?: string;
onTokenExpired?: (req: Request, res: Response) => void;
onTokenInvalid?: (req: Request, res: Response) => void;
}
class JwtMiddleware {
constructor(config: JwtMiddlewareConfig, logger: Logger);
authenticate: RequestHandler;
optional: RequestHandler;
requireRole(roles: string | string[]): RequestHandler;
static generateToken(payload: JwtPayload, secret: string, expiresIn?: string): string;
static decodeToken(token: string): JwtPayload | null;
}
JWT Payload Structure
interface JwtPayload {
userId: number;
email: string;
roles?: string[];
[key: string]: unknown;
}
Authentication Patterns
router.get('/protected', jwtAuth.authenticate, controller.method);
router.get('/mixed', jwtAuth.optional, (req: AuthenticatedRequest, res) => {
if (req.user) {
} else {
}
});
router.post('/admin',
jwtAuth.authenticate,
jwtAuth.requireRole('admin'),
adminController.method
);
router.delete('/resource/:id',
jwtAuth.authenticate,
jwtAuth.requireRole(['admin', 'moderator']),
controller.method
);
ExpressApp
interface ExpressConfig {
port?: number;
host?: string;
cors?: {
origin?: string | string[] | boolean;
credentials?: boolean;
methods?: string[];
allowedHeaders?: string[];
};
security?: {
helmet?: boolean;
rateLimit?: {
windowMs?: number;
max?: number;
message?: string;
};
};
compression?: boolean;
bodyParser?: {
json?: { limit?: string };
urlencoded?: { limit?: string; extended?: boolean };
};
logger?: Partial<LoggerConfig>;
trustProxy?: boolean;
}
BaseController
abstract class BaseController {
constructor(logger: Logger);
protected asyncHandler(handler: RouteHandler): RouteHandler;
protected getIdFromParams(req: Request, paramName?: string): string;
protected getQueryParam(req: Request, paramName: string, defaultValue?: string): string | undefined;
protected getQueryParamAsNumber(req: Request, paramName: string, defaultValue?: number): number | undefined;
protected getPaginationParams(req: Request): { page: number; limit: number; offset: number };
}
Response Helpers
ResponseHelper.success(res, data, 'Operation successful');
ResponseHelper.created(res, newUser, 'User created');
ResponseHelper.noContent(res);
ResponseHelper.error(res, 'Something went wrong', 400);
ResponseHelper.notFound(res, 'User not found');
ResponseHelper.unauthorized(res, 'Invalid credentials');
ResponseHelper.forbidden(res, 'Access denied');
ResponseHelper.unauthorized(res);
ResponseHelper.forbidden(res);
Authentication Error Responses
JWT middleware returns standardized error responses:
{
"success": false,
"error": {
"message": "No token provided",
"code": "NO_TOKEN"
},
"meta": {
"timestamp": "2024-01-15T10:30:00.000Z",
"requestId": "abc123"
}
}
{
"success": false,
"error": {
"message": "Token has expired",
"code": "TOKEN_EXPIRED"
}
}
{
"success": false,
"error": {
"message": "Invalid token",
"code": "TOKEN_INVALID"
}
}
{
"success": false,
"error": {
"message": "Insufficient permissions",
"code": "INSUFFICIENT_PERMISSIONS",
"details": {
"requiredRoles": ["admin"],
"userRoles": ["user"]
}
}
}
Middleware Stack Automático
A classe ExpressApp
configura automaticamente:
- Security: Helmet para headers de segurança
- Rate Limiting: Proteção contra ataques de força bruta
- CORS: Configuração de Cross-Origin Resource Sharing
- Compression: Compressão gzip/deflate
- Body Parsing: JSON e URL-encoded parsing
- Request Logging: Log automático de requests com timing
- Response Formatting: Formatação padronizada de respostas
- Error Handling: Tratamento global de erros
Exemplo Completo com Autenticação
import { ExpressApp, JwtMiddleware } from '@200systems/mf-express-adapter';
import { createLogger } from '@200systems/mf-logger';
import { UserController } from './controllers/UserController';
import { AuthController } from './controllers/AuthController';
const logger = createLogger({ context: 'api-server' });
const jwtAuth = new JwtMiddleware({
secret: process.env.JWT_SECRET!,
skipPaths: ['/auth/login', '/auth/register', '/health'],
algorithms: ['HS256']
}, logger);
const app = new ExpressApp({
port: 3000,
cors: { origin: true, credentials: true },
trustProxy: true
});
app.addRoutes([
{ method: 'post', path: '/auth/login', handler: authController.login },
{ method: 'post', path: '/auth/register', handler: authController.register },
{ method: 'post', path: '/auth/logout', handler: authController.logout }
]);
app.addRoutes([
{
method: 'get',
path: '/api/profile',
handler: userController.getProfile,
middleware: [jwtAuth.authenticate]
},
{
method: 'get',
path: '/api/admin/users',
handler: userController.getAllUsers,
middleware: [jwtAuth.authenticate, jwtAuth.requireRole('admin')]
}
]);
app.start();
Integração com Outros Packages
Este adapter funciona perfeitamente com:
@200systems/mf-logger
- Sistema de logging (obrigatório)
@200systems/mf-service-base
- Base classes para services (obrigatório)
@200systems/mf-db-core
- Abstração de banco de dados
Dependencies
Required
@200systems/mf-logger
- Logging functionality
@200systems/mf-service-base
- Service base classes
@200systems/mf-db-core
- Database core abstractions
Peer Dependencies
express
- Express.js framework
cors
- CORS middleware
helmet
- Security middleware
compression
- Response compression
express-rate-limit
- Rate limiting
jsonwebtoken
- JWT token handling
License
MIT