home / skills / amnadtaowsoam / cerebraskills / fastify-rest-api
This skill helps you design high-performance Fastify REST APIs with schema validation, TS support, and robust error handling to improve DX and scalability.
npx playbooks add skill amnadtaowsoam/cerebraskills --skill fastify-rest-apiReview the files below or copy the command above to add this skill to your agents.
---
name: Fastify REST API Patterns
description: High-performance Node.js web framework with built-in schema validation, JSON serialization, and TypeScript support.
---
# Fastify REST API Patterns
## Overview
Fastify is a high-performance Node.js web framework focused on speed and low overhead, featuring built-in schema validation and serialization, enabling developers to create production-ready APIs quickly.
Fastify consists of:
- **High Performance**: 2x faster than Express
- **JSON Schema Validation**: Built-in validation with JSON Schema
- **Fast Serialization**: Optimized JSON serialization
- **TypeScript Support**: First-class TypeScript support
- **Plugin System**: Extensible plugin architecture
- **Low Overhead**: Minimal request overhead
## Why This Matters
- **Enhance Performance**: Fastify can enhance API performance by 2-3x
- **Reduce Infrastructure Cost**: Higher throughput reduces infrastructure cost
- **Increase Developer Experience**: Built-in validation and serialization improve DX
- **Reduce Bugs**: Type-safe validation reduces bugs
- **Improve Scalability**: High-performance framework improves scalability
---
## Core Concepts
### 1. Application Setup
```typescript
import Fastify from 'fastify'
export async function buildApp(): Promise<FastifyInstance> {
const app = Fastify({
logger: {
level: 'info',
},
})
return app
}
```
### 2. Routing
```typescript
import { FastifyPluginAsync } from 'fastify'
const userRoutes: FastifyPluginAsync = async (fastify) => {
fastify.get('/users', async (request, reply) => {
return { users: [] }
})
fastify.post('/users', async (request, reply) => {
return reply.status(201).send({ success: true })
})
}
export default userRoutes
```
### 3. JSON Schema Validation
```typescript
const userProperties = {
id: { type: 'string', format: 'uuid' },
email: { type: 'string', format: 'email' },
name: { type: 'string', minLength: 2, maxLength: 100 },
}
export const createUserSchema: FastifySchema = {
body: {
type: 'object',
required: ['email', 'password', 'name'],
properties: {
email: { type: 'string', format: 'email' },
password: { type: 'string', minLength: 8 },
name: { type: 'string', minLength: 2, maxLength: 100 },
},
},
response: {
201: {
type: 'object',
properties: {
success: { type: 'boolean' },
data: {
type: 'object',
properties: userProperties,
},
},
},
},
}
```
### 4. Plugins
```typescript
import fp from 'fastify-plugin'
async function databasePlugin(fastify: FastifyInstance) {
const prisma = new PrismaClient()
await prisma.$connect()
fastify.decorate('prisma', prisma)
fastify.addHook('onClose', async (instance) => {
await instance.prisma.$disconnect()
})
}
export default fp(databasePlugin, { name: 'database' })
```
### 5. Hooks
**Hook Types (in order):**
- onRequest
- preParsing
- preValidation
- preHandler
- preSerialization
- onSend
- onResponse
```typescript
export async function authHook(
request: FastifyRequest,
reply: FastifyReply
) {
const authHeader = request.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw new UnauthorizedError('No token provided')
}
const token = authHeader.substring(7)
const payload = await verifyToken(token)
request.user = payload
}
```
### 6. Error Handling
```typescript
export class AppError extends Error {
constructor(
public message: string,
public statusCode: number = 500,
public code?: string
) {
super(message)
this.name = this.constructor.name
}
}
app.setErrorHandler((error: FastifyError, request, reply) => {
request.log.error(error)
const statusCode = error.statusCode || 500
const message = error.message || 'Internal Server Error'
reply.status(statusCode).send({
success: false,
error: {
message,
statusCode,
code: error.code,
},
})
})
```
### 7. Authentication
```typescript
import fp from 'fastify-plugin'
import jwt from '@fastify/jwt'
export default fp(async (fastify) => {
await fastify.register(jwt, {
secret: env.JWT_SECRET,
})
})
// Usage in routes
fastify.get('/protected', {
onRequest: async (request, reply) => {
try {
await request.jwtVerify()
} catch (err) {
reply.send(err)
}
}
}, async (request) => {
return { message: 'Protected data' }
})
```
## Quick Start
1. **Install Fastify:**
```bash
npm install fastify
npm install -D typescript @types/node tsx
```
2. **Create basic server:**
```typescript
import Fastify from 'fastify'
const app = Fastify()
app.get('/', async (request, reply) => {
return { hello: 'world' }
})
app.listen({ port: 3000 })
```
3. **Add plugins:**
```bash
npm install @fastify/cors @fastify/helmet @fastify/jwt
```
4. **Start server:**
```bash
npx tsx src/server.ts
```
## Production Checklist
- [ ] Use TypeScript for type safety
- [ ] Implement JSON Schema validation
- [ ] Use Fastify hooks for cross-cutting concerns
- [ ] Implement proper error handling
- [ ] Add authentication and authorization
- [ ] Use plugins for reusable functionality
- [ ] Implement request ID tracking
- [ ] Use async/await for async operations
- [ ] Test endpoints with Jest
- [ ] Use Swagger documentation
- [ ] Add CORS configuration
- [ ] Implement rate limiting
- [ ] Use caching for performance
- [ ] Monitor performance and errors
- [ ] Optimize serialization
- [ ] Use connection pooling
## Anti-patterns
1. **Poor JSON Schema Design**: Don't design JSON schemas incorrectly
2. **Missing Error Handling**: Don't fail to handle errors appropriately
3. **No Request ID**: Don't fail to track request IDs
4. **Poor Performance**: Don't fail to optimize performance
5. **No Monitoring**: Don't fail to monitor performance
6. **Poor TypeScript**: Don't use TypeScript incorrectly
## Integration Points
- **Error Handling**: `03-backend-api/error-handling`
- **Validation**: `03-backend-api/validation`
- **Middleware**: `03-backend-api/middleware`
- **API Design**: `01-foundations/api-design`
- **Monitoring**: `14-monitoring-observability`
## Further Reading
- [Fastify Documentation](https://www.fastify.io/docs/latest/)
- [Fastify Ecosystem](https://www.fastify.io/ecosystem/)
- [Fastify Best Practices](https://github.com/fastify/fastify/blob/main/docs/Guides/Best-Practices.md)
This skill captures practical patterns for building high-performance REST APIs with Fastify. It focuses on schema-driven validation, fast JSON serialization, TypeScript support, and an extensible plugin/hook model to create production-ready services quickly. The content highlights performance wins, developer ergonomics, and concrete patterns for routing, error handling, and authentication.
The skill outlines standard building blocks: app bootstrap, route registration, JSON Schema for request/response validation, plugins for shared resources, hooks for lifecycle concerns, and a centralized error handler. Examples show how to register plugins (database, jwt), attach hooks (auth, request lifecycle), and return precise responses using typed schemas. It also provides a production checklist and common anti-patterns to avoid.
Do I have to write JSON Schema for every route?
You should define schemas for inputs and important responses; at minimum validate incoming bodies and critical responses to prevent invalid data and optimize serialization.
How do plugins share resources like a DB client?
Create a fastify plugin that decorates the instance with the client, connect on register, and disconnect in an onClose hook to ensure clean lifecycle management.