From harness-claude
Structures Express applications with middleware chains, routers, async error handling, request validation, and proper middleware ordering for REST APIs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-claude:node-express-patternsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Structure Express applications with middleware chains, routers, and proper error handling
Structure Express applications with middleware chains, routers, and proper error handling
import express from 'express';
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// routes/users.ts
import { Router } from 'express';
const router = Router();
router.get('/', async (req, res) => {
const users = await userService.findAll();
res.json(users);
});
router.get('/:id', async (req, res) => {
const user = await userService.findById(req.params.id);
if (!user) return res.status(404).json({ error: 'User not found' });
res.json(user);
});
router.post('/', async (req, res) => {
const user = await userService.create(req.body);
res.status(201).json(user);
});
export { router as userRouter };
// app.ts
app.use('/api/users', userRouter);
type AsyncHandler = (req: Request, res: Response, next: NextFunction) => Promise<void>;
function asyncHandler(fn: AsyncHandler) {
return (req: Request, res: Response, next: NextFunction) => {
fn(req, res, next).catch(next);
};
}
router.get(
'/:id',
asyncHandler(async (req, res) => {
const user = await userService.findById(req.params.id);
if (!user) throw new NotFoundError('User', req.params.id);
res.json(user);
})
);
// 1. Parsing (runs first)
app.use(express.json());
// 2. Logging
app.use(requestLogger);
// 3. Authentication
app.use('/api', authenticate);
// 4. Routes
app.use('/api/users', userRouter);
app.use('/api/posts', postRouter);
// 5. 404 handler (after all routes)
app.use((req, res) => res.status(404).json({ error: 'Not found' }));
// 6. Error handler (must have 4 parameters)
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err);
res.status(500).json({ error: 'Internal server error' });
});
import { z, ZodSchema } from 'zod';
function validate(schema: ZodSchema) {
return (req: Request, res: Response, next: NextFunction) => {
const result = schema.safeParse(req.body);
if (!result.success) {
return res.status(400).json({ errors: result.error.flatten().fieldErrors });
}
req.body = result.data;
next();
};
}
const CreateUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
});
router.post(
'/',
validate(CreateUserSchema),
asyncHandler(async (req, res) => {
const user = await userService.create(req.body); // req.body is validated
res.status(201).json(user);
})
);
async function authenticate(req: Request, res: Response, next: NextFunction) {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) return res.status(401).json({ error: 'No token provided' });
try {
const payload = await verifyToken(token);
req.userId = payload.userId;
next();
} catch {
res.status(401).json({ error: 'Invalid token' });
}
}
const server = app.listen(3000);
process.on('SIGTERM', () => {
server.close(() => process.exit(0));
});
Express uses a middleware chain pattern where each middleware receives (req, res, next) and either responds or calls next() to pass control to the next middleware.
Error handling middleware must have exactly 4 parameters (err, req, res, next). Express identifies error handlers by their arity. Place them after all routes.
Express 5 (beta): Automatically catches async errors without the asyncHandler wrapper. Until Express 5 is stable, the wrapper is required.
Trade-offs:
https://expressjs.com/en/guide/routing.html
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeProvides expert Node.js backend patterns for Express, NestJS, Fastify APIs including project structures, async error handlers, custom error classes, and global error handling.
Implements Node.js backend patterns with Express/Fastify for middleware, error handling, auth, DB integration, REST/GraphQL APIs, microservices, and WebSockets.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.