Skip to main content

backend

Backend development with Node.js, Express, NestJS, and server patterns

来源信息

仓库
miles990/claude-software-skills
最近来源活动
2026年1月8日 05:30
检测到的 SKILL.md 语言
中文
星标
25
分支
6

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

文件资源管理器
6 个文件

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
backend
description
Backend development with Node.js, Express, NestJS, and server patterns
domain
development-stacks
version
1.0.0
tags
["nodejs","express","nestjs","fastify","api","middleware","authentication"]
triggers
{"keywords":{"primary":["backend","server","nodejs","express","nestjs","api","microservice"],"secondary":["fastify","middleware","authentication","rest","graphql","queue"]},"context_boost":["service","endpoint","database","http"],"context_penalty":["frontend","css","ui","mobile"],"priority":"high"}
collaboration
{"prerequisites":[{"skill":"typescript","reason":"Type-safe backend development"}],"delegation_triggers":[{"trigger":"API endpoint design decisions","delegate_to":"api-design","context":"RESTful conventions, versioning, error formats"},{"trigger":"Database schema design or query optimization","delegate_to":"database","context":"Data modeling, indexing strategy"},{"trigger":"Writing tests for services or controllers","delegate_to":"testing-strategies","context":"Integration test patterns, mocking strategies"}],"receives_context_from":[{"skill":"api-design","receives":"[Truncated]"},{"skill":"database","receives":"[Truncated]"}],"provides_context_to":[{"skill":"frontend","provides":"[Truncated]"},{"skill":"testing-strategies","provides":"[Truncated]"}]}
# Backend Development ## Overview Server-side development patterns, frameworks, and best practices for building scalable APIs and services. --- ## Express.js ### Application Structure ```typescript // app.ts import express from 'express'; import helmet from 'helmet'; import cors from 'cors'; import compression from 'compression'; import { errorHandler } from './middleware/errorHandler'; import { requestLogger } from './middleware/requestLogger'; import routes from './routes'; const app = express(); // Security middleware app.use(helmet()); app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') || '*', credentials: true, })); // Request processing app.use(compression()); app.use(express.json({ limit: '10kb' })); app.use(express.urlencoded({ extended: true })); // Logging app.use(requestLogger); // Routes app.use('/api/v1', routes); // Health check app.get('/health', (req, res) => { res.json({ status: 'healthy', timestamp: new Date().toISOString() }); }); // Error handling (must be last) app.use(errorHandler); export default app; ``` ### Middleware Patterns ```typescript // Authentication middleware import { Request, Response, NextFunction } from 'express'; import jwt from 'jsonwebtoken'; interface AuthRequest extends Request { user?: { id: string; role: string }; } export function authenticate(req: AuthRequest, res: Response, next: NextFunction) { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'Authentication required' }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET!) as { id: string; role: string }; req.user = decoded; next(); } catch { return res.status(401).json({ error: 'Invalid token' }); } } // Authorization middleware export function authorize(...roles: string[]) { return (req: AuthRequest, res: Response, next: NextFunction) => { if (!req.user || !roles.includes(req.user.role)) { return res.status(403).json({ error: 'Forbidden' }); } next(); }; } // Rate limiting import rateLimit from 'express-rate-limit'; export const apiLimiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, message: { error: 'Too many requests' }, standardHeaders: true, }); // Validation middleware import { z } from 'zod'; export function validate(schema: z.ZodSchema) { return (req: Request, res: Response, next: NextFunction) => { const result = schema.safeParse({ body: req.body, query: req.query, params: req.params, }); if (!result.success) { return res.status(400).json({ error: 'Validation failed', details: result.error.flatten(), }); } req.body = result.data.body; req.query = result.data.query; req.params = result.data.params; next(); }; } ``` ### Error Handling ```typescript // Custom error classes export class AppError extends Error { constructor( public statusCode: number, public message: string, public isOperational = true ) { super(message); Error.captureStackTrace(this, this.constructor); } } export class NotFoundError extends AppError { constructor(resource: string) { super(404, `${resource} not found`); } } export class ValidationError extends AppError { constructor(message: string) { super(400, message); } } // Global error handler export function errorHandler( err: Error, req: Request, res: Response, next: NextFunction ) { console.error('Error:', err); if (err instanceof AppError) { return res.status(err.statusCode).json({ error: err.message, ...(process.env.NODE_ENV === 'development' && { stack: err.stack }), }); } // Mongoose/Prisma errors if (err.name === 'CastError') { return res.status(400).json({ error: 'Invalid ID format' }); } if (err.name === 'ValidationError') { return res.status(400).json({ error: err.message }); } // Default error res.status(500).json({ error: process.env.NODE_ENV === 'production' ? 'Internal server error' : err.message, }); } ``` --- ## NestJS ### Module Structure ```typescript // users/users.module.ts import { Module } from '@nestjs/common'; import { UsersController } from './users.controller'; import { UsersService } from './users.service'; import { PrismaModule } from '../prisma/prisma.module'; @Module({ imports: [PrismaModule], controllers: [UsersController], providers: [UsersService], exports: [UsersService], }) export class UsersModule {} // users/users.controller.ts import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards, HttpCode, HttpStatus, } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger'; import { UsersService } from './users.service'; import { CreateUserDto, UpdateUserDto, QueryUsersDto } from './dto'; import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard'; import { RolesGuard } from '../auth/guards/roles.guard'; import { Roles } from '../auth/decorators/roles.decorator'; @ApiTags('users') @Controller('users') @UseGuards(JwtAuthGuard, RolesGuard) @ApiBearerAuth() export class UsersController { constructor(private readonly usersService: UsersService) {} @Get() @ApiOperation({ summary: 'List users' }) async findAll(@Query() query: QueryUsersDto) { return this.usersService.findAll(query); } @Get(':id') @ApiOperation({ summary: 'Get user by ID' }) async findOne(@Param('id') id: string) { return this.usersService.findOne(id); } @Post() @Roles('admin') @ApiOperation({ summary: 'Create user' }) async create(@Body() createUserDto: CreateUserDto) { return this.usersService.create(createUserDto); } @Put(':id') @ApiOperation({ summary: 'Update user' }) async update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) { return this.usersService.update(id, updateUserDto); } @Delete(':id') @Roles('admin') @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: 'Delete user' }) async remove(@Param('id') id: string) { await this.usersService.remove(id); } } ``` ### DTOs with Validation ```typescript // users/dto/create-user.dto.ts import { IsEmail, IsString, MinLength, IsOptional, IsEnum } from 'class-validator'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; export enum UserRole { USER = 'user', ADMIN = 'admin', } export class CreateUserDto { @ApiProperty({ example: 'user@example.com' }) @IsEmail() email: string; @ApiProperty({ minLength: 8 }) @IsString() @MinLength(8) password: string; @ApiPropertyOptional() @IsOptional() @IsString() name?: string; @ApiPropertyOptional({ enum: UserRole, default: UserRole.USER }) @IsOptional() @IsEnum(UserRole) role?: UserRole = UserRole.USER; } // Partial DTO for updates import { PartialType, OmitType } from '@nestjs/swagger'; export class UpdateUserDto extends PartialType( OmitType(CreateUserDto, ['password'] as const) ) {} ``` ### Services with Dependency Injection ```typescript // users/users.service.ts import { Injectable, NotFoundException } from '@nestjs/common'; import { PrismaService } from '../prisma/prisma.service'; import { CreateUserDto, UpdateUserDto, QueryUsersDto } from './dto'; import * as argon2 from 'argon2'; @Injectable() export class UsersService { constructor(private prisma: PrismaService) {} async findAll(query: QueryUsersDto) { const { page = 1, limit = 10, search } = query; const where = search ? { OR: [ { name: { contains: search, mode: 'insensitive' } }, { email: { contains: search, mode: 'insensitive' } }, ], } : {}; const [users, total] = await Promise.all([ this.prisma.user.findMany({ where, skip: (page - 1) * limit, take: limit, select: { id: true, email: true, name: true, role: true, createdAt: true, }, }), this.prisma.user.count({ where }), ]); return { data: users, meta: { page, limit, total, totalPages: Math.ceil(total / limit), }, }; } async findOne(id: string) { const user = await this.prisma.user.findUnique({ where: { id }, select: { id: true, email: true, name: true, role: true, createdAt: true, }, }); if (!user) { throw new NotFoundException(`User with ID ${id} not found`); } return user; } async create(dto: CreateUserDto) { const hashedPassword = await argon2.hash(dto.password); return this.prisma.user.create({ data: { ...dto, password: hashedPassword, }, select: { id: true, email: true, name: true, role: true, }, }); } async update(id: string, dto: UpdateUserDto) { await this.findOne(id); // Throws if not found return this.prisma.user.update({ where: { id }, data: dto, select: { id: true, email: true, name: true, role: true, }, }); } async remove(id: string) { await this.findOne(id); // Throws if not found await this.prisma.user.delete({ where: { id } }); } } ``` --- ## Database Integration ### Prisma ORM ```typescript // prisma/schema.prisma generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique password String name String? role Role @default(USER) posts Post[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Post { id String @id @default(cuid()) title String content String? published Boolean @default(false) author User @relation(fields: [authorId], references: [id]) authorId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } enum Role { USER ADMIN } // Prisma service import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable()
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看