# Create API Endpoint Command You are helping the user create a new API endpoint following Sngular's backend development best practices. ## Instructions 1. **Detect the backend framework**: - Node.js with Express - Node.js with Fastify - NestJS - Python with FastAPI - Python with Flask/Django - Go with Gin/Echo - Other framework 2. **Ask for endpoint details**: - HTTP method (GET, POST, PUT, PATCH, DELETE) - Route path (e.g., `/api/users`, `/api/posts/:id`) - Purpose and description - Request body schema (if applicable) - Response schema - Authentication required (yes/no) - Rate limiting needed (yes/no) 3. **Determine API style**: - REST API - GraphQL (query/mutation/subscription) - gRPC - WebSocket ## Implementation Tasks ### For REST Endpoints: 1. **Create route handler** with: - HTTP method and path - Request validation middleware - Business logic / controller method - Response formatting - Error handling 2. **Add request validation**: - Query parameters validation - Path parameters validation - Request body validation (using Zod, Joi, class-validator) - File upload validation (if needed) 3. **Implement authentication/authorization**: - JWT token verification - Role-based access control (RBAC) - Permission checks - API key validation 4. **Add error handling**: - Try-catch blocks - Custom error classes - HTTP status codes - Error response formatting 5. **Create tests**: - Unit tests for controller logic - Integration tests for full endpoint - Mock database/external services - Test authentication flows 6. **Add documentation**: - OpenAPI/Swagger annotations - JSDoc/docstrings - Request/response examples - Error codes documentation ### For GraphQL: 1. **Define schema**: - Type definitions - Input types - Custom scalars 2. **Create resolver**: - Query/Mutation/Subscription resolver - Field resolvers - DataLoader for N+1 prevention 3. **Add validation & auth**: - Schema directives - Resolver-level authorization - Input validation ## Files to Create/Update 1. **Route/Controller file**: Define the endpoint handler 2. **Validation schema**: Request/response validation 3. **Service layer**: Business logic (separate from controller) 4. **Tests**: Comprehensive endpoint testing 5. **Types/Interfaces**: TypeScript types or Pydantic models 6. **Documentation**: API docs/Swagger definitions ## Best Practices to Follow ### Code Structure ``` src/ ├── routes/ │ └── users.routes.ts # Route definitions ├── controllers/ │ └── users.controller.ts # Request handlers ├── services/ │ └── users.service.ts # Business logic ├── validators/ │ └── users.validator.ts # Input validation ├── types/ │ └── users.types.ts # TypeScript types └── tests/ └── users.test.ts # Endpoint tests ``` ### Request Validation ```typescript import { z } from 'zod' const CreateUserSchema = z.object({ email: z.string().email(), name: z.string().min(2).max(100), age: z.number().int().positive().optional(), }) ``` ### Error Handling ```typescript // Custom error classes class BadRequestError extends Error { statusCode = 400 } class UnauthorizedError extends Error { statusCode = 401 } // Error handling middleware app.use((err, req, res, next) => { res.status(err.statusCode || 500).json({ error: { message: err.message, code: err.code, }, }) }) ``` ### Authentication ```typescript // JWT middleware const authMiddleware = async (req, res, next) => { const token = req.headers.authorization?.split(' ')[1] if (!token) { throw new UnauthorizedError('No token provided') } const decoded = jwt.verify(token, process.env.JWT_SECRET) req.user = decoded next() } ``` ### Rate Limiting ```typescript import rateLimit from 'express-rate-limit' const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100, // limit each IP to 100 requests per windowMs }) app.use('/api/', limiter) ``` ### Response Formatting ```typescript // Success response res.status(200).json({ success: true, data: result, meta: { page: 1, limit: 20, total: 100, }, }) // Error response res.status(400).json({ success: false, error: { code: 'VALIDATION_ERROR', message: 'Invalid email format', details: validationErrors, }, }) ``` ### Database Operations ```typescript // Use transactions for multiple operations await db.transaction(async (trx) => { const user = await trx('users').insert(userData) await trx('profiles').insert({ user_id: user.id, ...profileData }) }) ``` ### Logging ```typescript import logger from './utils/logger' app.post('/api/users', async (req, res) => { logger.info('Creating new user', { email: req.body.email }) try { const user = await createUser(req.body) logger.info('User created successfully', { userId: user.id }) res.status(201).json({ data: user }) } catch (error) { logger.error('Failed to create user', { error, body: req.body }) throw error } }) ``` ## Testing Example ```typescript import request from 'supertest' import app from '../app' describe('POST /api/users', () => { it('creates a new user with valid data', async () => { const response = await request(app) .post('/api/users') .send({ email: 'test@example.com', name: 'Test User', }) .expect(201) expect(response.body.data).toHaveProperty('id') expect(response.body.data.email).toBe('test@example.com') }) it('returns 400 for invalid email', async () => { await request(app) .post('/api/users') .send({ email: 'invalid-email', name: 'Test User', }) .expect(400) }) it('requires authentication', async () => { await request(app) .post('/api/users') .send({ email: 'test@example.com' }) .expect(401) }) }) ``` ## OpenAPI/Swagger Documentation ```typescript /** * @swagger * /api/users: * post: * summary: Create a new user * tags: [Users] * security: * - bearerAuth: [] * requestBody: * required: true * content: * application/json: * schema: * type: object * required: * - email * - name * properties: * email: * type: string * format: email * name: * type: string * responses: * 201: * description: User created successfully * 400: * description: Invalid input * 401: * description: Unauthorized */ ``` ## Security Considerations - Always validate and sanitize input - Use parameterized queries to prevent SQL injection - Implement rate limiting - Use HTTPS in production - Never expose sensitive data in responses - Hash passwords with bcrypt - Implement CORS properly - Use security headers (helmet.js) - Validate JWT tokens properly - Implement proper session management Ask the user: "What API endpoint would you like to create?"