AgentSkillsCN

backend-fastify

采用 Fastify + TypeScript 进行后端开发。当您需要创建新的后端 API、新增路由、实现服务、集成插件,或配置环境变量时,可选用此技术栈。

SKILL.md
--- frontmatter
name: backend-fastify
description: Backend development using Fastify + TypeScript. Use when creating new backend APIs, adding routes, implementing services, working with plugins, or configuring environment variables.

Backend Fastify Stack

High-performance Node.js backend stack:

  • Fastify 5.x - Web framework
  • TypeScript - Type safety
  • tsx - Development with watch mode
  • pino-pretty - Pretty logging for development
  • @fastify/env - Environment variable validation with JSON Schema
  • @fastify/cors - CORS support
  • fastify-plugin - Plugin system

Environment Setup

Use asdf to manage Node.js versions:

bash
# Install Node.js plugin (one-time)
asdf plugin add nodejs

# Set project Node.js version
asdf set nodejs latest:22

This creates a .tool-versions file in the project root that ensures consistent Node.js versions across the team.

Reference Files

FileWhen to Use
setup-guide.mdStarting a new backend project from scratch
patterns.mdImplementing routes, services, schema validation
authentication.mdAdding JWT auth, authorization, protected routes
api-design.mdSwagger/OpenAPI integration, response format, errors
mcp-integration.mdIntegrating MCP server for AI agent access
gotchas.mdDebugging issues, common mistakes and fixes

Quick Reference

Commands

bash
# Dev server with watch mode
npm run dev

# Build for production
npm run build

# Run production build
npm start

# Type check
npm run type-check

Key Imports

typescript
// Fastify types
import Fastify, { FastifyInstance, FastifyPluginAsync } from 'fastify'
import fp from 'fastify-plugin'

// Common plugins
import fastifyEnv from '@fastify/env'
import cors from '@fastify/cors'

Configuration Access

Always access configuration through fastify.config, never process.env directly:

typescript
// CORRECT - type-safe, validated at startup
const port = fastify.config.PORT
const apiKey = fastify.config.API_KEY

// WRONG - no validation, no type safety
const port = process.env.PORT  // Don't do this

Response Format

typescript
// Standard response structure
{
  success: boolean
  data?: T
  error?: string
  metadata?: { timestamp: Date }
}

Plugin Pattern

typescript
import fp from 'fastify-plugin'

export default fp(async (fastify, opts) => {
  // Plugin logic here
  fastify.decorate('something', value)
}, '5.x')

Route Pattern

typescript
import { FastifyPluginAsync } from 'fastify'

const routes: FastifyPluginAsync = async (fastify, opts) => {
  fastify.get('/', async (request, reply) => {
    return { success: true, data: 'example' }
  })
}

export default routes

Service Pattern

typescript
// 1. Create service class
export class MyService {
  constructor(private fastify: FastifyInstance) {}

  async doWork() {
    // Access config through fastify instance
    const apiKey = this.fastify.config.API_KEY
    this.fastify.log.info('Service method called')
  }
}

// 2. Declare module augmentation
declare module 'fastify' {
  interface FastifyInstance {
    myService: MyService
  }
}

// 3. Initialize and decorate in app.ts
fastify.decorate('myService', new MyService(fastify))

Project Structure

code
backend/
├── src/
│   ├── plugins/          # Fastify plugins (env, auth, etc.)
│   ├── routes/           # HTTP route handlers
│   ├── services/         # Business logic classes
│   ├── utils/            # Shared utilities
│   ├── app.ts            # Plugin registration & setup
│   └── index.ts          # Server entry point
├── package.json
├── tsconfig.json
├── .env.example
└── .gitignore

Common Gotchas

  • Plugin order matters: Register env plugin first, then services, then routes
  • Config access: Use fastify.config.VAR not process.env.VAR
  • Server ready: Call await server.ready() before accessing config in index.ts
  • Path normalization: Centralize path utilities, handle root '/' as special case
  • Package management: Use npm install <pkg> not manual package.json edits