| name | expressjs |
| description | Express.js web framework best practices and patterns |
| license | MIT |
| compatibility | opencode |
| metadata | {"audience":"developers","category":"frameworks"} |
What I do
- Build REST APIs with Express.js
- Implement middleware for cross-cutting concerns
- Handle async errors properly
- Structure applications with routers
- Implement authentication and authorization
- Use proper error handling
- Configure CORS and security headers
- Write tests with Jest and Supertest
When to use me
When building Express.js applications or APIs.
Application Structure
src/
├── app.ts # App configuration
├── server.ts # Entry point
├── config/
│ ├── environment.ts
│ └── database.ts
├── routes/
│ ├── index.ts
│ ├── users/
│ │ ├── routes.ts
│ │ ├── controller.ts
│ │ ├── service.ts
│ │ ├── model.ts
│ │ └── validation.ts
│ └── posts/
├── middleware/
│ ├── auth.ts
│ ├── error.ts
│ ├── validation.ts
│ └── logging.ts
├── utils/
│ ├── logger.ts
│ └── helpers.ts
├── types/
│ └── express.d.ts
└── tests/
└── *.test.ts
Express Application
import express, { Application, Request, Response, NextFunction } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import { config } from './config/environment';
import { errorHandler } from './middleware/error';
import { requestLogger } from './middleware/logging';
import routes from './routes';
const app: Application = express();
app.use(helmet());
app.use(cors({
origin: config.CORS_ORIGIN,
credentials: true,
}));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
app.(());
app.(requestLogger);
app.(, {
res.({
: ,
: ().(),
: process.(),
});
});
app.(, routes);
app.( {
res.().({
: {
: ,
: ,
},
});
});
app.(errorHandler);
app;
Router Structure
import { Router, Request, Response } from 'express';
import { userController } from './controller';
import { authenticate } from '../../middleware/auth';
import { validateRequest } from '../../middleware/validation';
import { createUserSchema, updateUserSchema } from './validation';
const router: Router = Router();
router.post(
'/',
authenticate,
createUserSchema,
validateRequest,
userController.create
);
router.get(
'/',
authenticate,
userController.list
);
router.get(
'/:id',
authenticate,
userController.getById
);
router.patch(
'/:id',
authenticate,
updateUserSchema,
validateRequest,
userController.update
);
router.delete(
'/:id',
authenticate,
userController.delete
);
export default router;
Controller with Error Handling
import { Request, Response, NextFunction } from 'express';
import { userService } from './service';
import { CreateUserInput, UpdateUserInput } from './model';
export const userController = {
async create(req: Request, res: Response, next: NextFunction) {
try {
const input: CreateUserInput = req.body;
const user = await userService.create(input);
res.status(201).json({
success: true,
data: user,
});
} catch (error) {
next(error);
}
},
async list(req: Request, res: Response, next: NextFunction) {
try {
{ page = , limit = , sort = } = req.;
{ users, total } = userService.({
: (page),
: (limit),
: (sort),
});
res.({
: ,
: users,
: {
total,
: (page),
: (limit),
: .(total / (limit)),
},
});
} (error) {
(error);
}
},
() {
{
{ id } = req.;
user = userService.(id);
(!user) {
res.().({
: ,
: {
: ,
: ,
},
});
}
res.({
: ,
: user,
});
} (error) {
(error);
}
},
};
Middleware
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { config } from '../config/environment';
export interface AuthenticatedRequest extends Request {
user?: {
id: string;
email: string;
role: string;
};
}
export function authenticate(
req: AuthenticatedRequest,
res: Response,
next: NextFunction
): void {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
res.status(401).json({
error: {
code: 'UNAUTHORIZED',
message: 'No token provided',
},
});
return;
}
const token = authHeader.()[];
{
decoded = jwt.(token, config.) {
: ;
: ;
: ;
};
req. = decoded;
();
} (error) {
res.().({
: {
: ,
: ,
},
});
}
}
() {
(: , : , : ): {
(!req.) {
res.().({
: { : , : },
});
;
}
(!roles.(req..)) {
res.().({
: { : , : },
});
;
}
();
};
}
Error Handling
import { Request, Response, NextFunction } from 'express';
import { ZodError } from 'zod';
import { config } from '../config/environment';
export class AppError extends Error {
constructor(
public statusCode: number,
public code: string,
message: string
) {
super(message);
this.name = 'AppError';
}
}
export function errorHandler(
err: Error,
req: Request,
res: Response,
next: NextFunction
): void {
console.error('Error:', {
name: err.name,
message: err.message,
: err.,
});
(err ) {
res.().({
: ,
: {
: ,
: ,
: err..( ({
: e..(),
: e.,
})),
},
});
;
}
(err ) {
res.(err.).({
: ,
: {
: err.,
: err.,
},
});
;
}
(err. === ) {
res.().({
: ,
: {
: ,
: ,
},
});
;
}
res.().({
: ,
: {
: ,
: config. ===
?
: err.,
},
});
}
Testing
import request from 'supertest';
import app from '../app';
import { createTestUser, generateToken } from './fixtures';
describe('Users API', () => {
let testUser: any;
let authToken: string;
beforeAll(async () => {
testUser = await createTestUser();
authToken = generateToken(testUser);
});
describe('GET /api/v1/users', () => {
it('should return 401 without authentication', async () => {
const res = await request(app)
.get('/api/v1/users');
expect(res.status).toBe(401);
});
it('should return list of users with authentication', async () => {
const res = await request(app)
.get('/api/v1/users')
.set('Authorization', );
(res.).();
(res..).();
(.(res..)).();
});
});
(, {
(, () => {
newUser = {
: ,
: ,
: ,
};
res = (app)
.()
.(, )
.(newUser);
(res.).();
(res..).();
(res...).(newUser.);
});
(, () => {
res = (app)
.()
.(, )
.({});
(res.).();
(res...).();
});
});
});