RESTful and GraphQL API design with documentation. Generates complete API specifications and code.
2.0
2025-01
intermediate
Development & Coding
You are a senior API architect with extensive experience in: - RESTful API design principles and best practices - GraphQL schema design and optimization - OpenAPI/Swagger specification - API versioning strategies - Authentication methods (OAuth2, JWT, API keys) - Rate limiting and throttling - Caching strategies - Error handling and status codes - HATEOAS and Richardson Maturity Model - Microservices and API gateways - WebSocket and real-time APIs - API documentation and developer experience You design APIs that are intuitive, scalable, secure, and maintainable. You consider both the API provider and consumer perspectives.
Design a comprehensive, production-ready API based on the requirements below. Create a complete specification with implementation details. ## 📋 API Requirements ### Business Context: [DESCRIBE_BUSINESS_NEED] ### Core Functionality: [LIST_MAIN_FEATURES] ### Technical Constraints: - Expected Traffic: [REQUESTS_PER_SECOND] - Data Volume: [APPROXIMATE_SIZE] - Response Time SLA: [MILLISECONDS] - Platform: [CLOUD_PROVIDER_OR_INFRASTRUCTURE] ## 🏗️ API Design Specification ### API Overview **Name**: [Generated API Name] **Version**: v1 **Base URL**: `https://api.example.com/v1` **Protocol**: REST / GraphQL / gRPC **Documentation URL**: `https://docs.api.example.com` ### Authentication & Security ```yaml security: - type: OAuth2 flows: authorizationCode: authorizationUrl: https://auth.example.com/oauth/authorize tokenUrl: https://auth.example.com/oauth/token scopes: read: Read access write: Write access admin: Admin access - type: ApiKey in: header name: X-API-Key ``` **Security Best Practices**: - Rate limiting: [Limits per tier] - CORS configuration: [Allowed origins] - Input validation: [Validation rules] - Encryption: [TLS requirements] ### Resource Design #### Resource 1: [RESOURCE_NAME] ```yaml /[resources]: get: summary: List all [resources] parameters: - name: page in: query type: integer default: 1 - name: limit in: query type: integer default: 20 maximum: 100 - name: sort in: query type: string enum: [created_at, updated_at, name] - name: filter in: query type: string responses: 200: description: Success schema: type: object properties: data: type: array items: $ref: '#/definitions/Resource' pagination: $ref: '#/definitions/Pagination' _links: $ref: '#/definitions/Links' 401: $ref: '#/responses/Unauthorized' 429: $ref: '#/responses/RateLimited' post: summary: Create a new [resource] parameters: - name: body in: body required: true schema: $ref: '#/definitions/ResourceInput' responses: 201: description: Created headers: Location: type: string description: URL of created resource schema: $ref: '#/definitions/Resource' 400: $ref: '#/responses/BadRequest' 422: $ref: '#/responses/ValidationError' /[resources]/{id}: get: summary: Get a specific [resource] parameters: - name: id in: path required: true type: string format: uuid responses: 200: description: Success schema: $ref: '#/definitions/Resource' 404: $ref: '#/responses/NotFound' put: summary: Update a [resource] parameters: - name: id in: path required: true type: string - name: body in: body required: true schema: $ref: '#/definitions/ResourceInput' responses: 200: description: Updated schema: $ref: '#/definitions/Resource' 404: $ref: '#/responses/NotFound' 409: $ref: '#/responses/Conflict' delete: summary: Delete a [resource] parameters: - name: id in: path required: true type: string responses: 204: description: Deleted 404: $ref: '#/responses/NotFound' ``` ### Data Models ```typescript // TypeScript interfaces for clarity interface Resource { id: string; created_at: string; // ISO 8601 updated_at: string; // ISO 8601 [FIELD_1]: Type; [FIELD_2]: Type; [FIELD_3]: Type; _links: { self: string; related: string[]; }; } interface ResourceInput { [FIELD_1]: Type; [FIELD_2]: Type; [FIELD_3]: Type; } interface PaginationMeta { current_page: number; per_page: number; total_pages: number; total_items: number; has_next: boolean; has_previous: boolean; } interface ErrorResponse { error: { code: string; message: string; details?: any; timestamp: string; request_id: string; }; } ``` ### Error Handling | Status Code | Error Code | Description | Example Response | |------------|------------|-------------|------------------| | 400 | BAD_REQUEST | Invalid request format | `{"error": {"code": "BAD_REQUEST", "message": "Invalid JSON"}}` | | 401 | UNAUTHORIZED | Missing or invalid auth | `{"error": {"code": "UNAUTHORIZED", "message": "Invalid token"}}` | | 403 | FORBIDDEN | Insufficient permissions | `{"error": {"code": "FORBIDDEN", "message": "Requires admin role"}}` | | 404 | NOT_FOUND | Resource doesn't exist | `{"error": {"code": "NOT_FOUND", "message": "Resource not found"}}` | | 409 | CONFLICT | State conflict | `{"error": {"code": "CONFLICT", "message": "Resource already exists"}}` | | 422 | VALIDATION_ERROR | Validation failed | `{"error": {"code": "VALIDATION_ERROR", "details": {...}}}` | | 429 | RATE_LIMITED | Too many requests | `{"error": {"code": "RATE_LIMITED", "retry_after": 60}}` | | 500 | INTERNAL_ERROR | Server error | `{"error": {"code": "INTERNAL_ERROR", "request_id": "..."}}` | ### Implementation Code #### Express.js Implementation ```javascript const express = require('express'); const router = express.Router(); const { validate } = require('./middleware/validation'); const { authenticate } = require('./middleware/auth'); const { rateLimit } = require('./middleware/rateLimit'); // List resources with pagination, filtering, and sorting router.get('/resources', authenticate, rateLimit({ max: 100, window: '1m' }), async (req, res) => { try { const { page = 1, limit = 20, sort = 'created_at', filter } = req.query; // Build query const query = {}; if (filter) { // Parse and apply filters Object.assign(query, parseFilters(filter)); } // Execute query with pagination const totalItems = await Resource.count(query); const totalPages = Math.ceil(totalItems / limit); const offset = (page - 1) * limit; const resources = await Resource.find(query) .sort(sort) .limit(limit) .skip(offset); // Build response with HATEOAS links const response = { data: resources.map(r => ({ ...r.toJSON(), _links: { self: `/resources/${r.id}`, update: { href: `/resources/${r.id}`, method: 'PUT' }, delete: { href: `/resources/${r.id}`, method: 'DELETE' } } })), pagination: { current_page: page, per_page: limit, total_pages: totalPages, total_items: totalItems, has_next: page < totalPages, has_previous: page > 1 }, _links: { self: `/resources?page=${page}&limit=${limit}`, next: page < totalPages ? `/resources?page=${page + 1}&limit=${limit}` : null, previous: page > 1 ? `/resources?page=${page - 1}&limit=${limit}` : null, first: `/resources?page=1&limit=${limit}`, last: `/resources?page=${totalPages}&limit=${limit}` } }; res.json(response); } catch (error) { next(error); } } ); // Create resource router.post('/resources', authenticate, rateLimit({ max: 20, window: '1m' }), validate(ResourceSchema), async (req, res) => { try { const resource = await Resource.create({ ...req.body, user_id: req.user.id }); res.status(201) .location(`/resources/${resource.id}`) .json({ ...resource.toJSON(), _links: { self: `/resources/${resource.id}`, collection: '/resources' } }); } catch (error) { if (error.code === 11000) { return res.status(409).json({ error: { code: 'CONFLICT', message: 'Resource already exists', details: error.keyValue } }); } next(error); } } ); module.exports = router; ``` ### API Testing ```javascript // Jest test suite describe('Resources API', () => { describe('GET /resources', () => { it('should return paginated resources', async () => { const response = await request(app) .get('/resources?page=1&limit=10') .set('Authorization', 'Bearer ' + token) .expect(200); expect(response.body).toHaveProperty('data'); expect(response.body.data).toBeInstanceOf(Array); expect(response.body.pagination.per_page).toBe(10); }); it('should handle rate limiting', async () => { // Make requests up to limit for (let i = 0; i < 100; i++) { await request(app) .get('/resources') .set('Authorization', 'Bearer ' + token); } // Next request should be rate limited const response = await request(app) .get('/resources') .set('Authorization', 'Bearer ' + token) .expect(429); expect(response.body.error.code).toBe('RATE_LIMITED'); }); }); }); ``` ### Documentation #### OpenAPI Specification [Complete OpenAPI 3.0 specification in YAML] #### Client SDKs Generate SDKs for: - JavaScript/TypeScript - Python - Go - Java #### Postman Collection [Export Postman collection JSON] ### Performance Optimization - Implement caching with Redis (TTL: 5 minutes for lists, 1 hour for individual resources) - Use database indexing on frequently queried fields - Implement pagination cursors for large datasets - Use ETags for conditional requests - Enable compression (gzip/brotli) ### Monitoring & Analytics - Track API usage per endpoint - Monitor response times (p50, p95, p99) - Log error rates and types - Set up alerts for anomalies - Dashboard metrics to track ### Deployment Checklist - [ ] API versioning strategy defined - [ ] Rate limiting configured - [ ] Authentication/authorization tested - [ ] Error handling comprehensive - [ ] Documentation complete - [ ] Client SDKs generated - [ ] Performance tested - [ ] Security scan passed - [ ] Monitoring configured - [ ] Rollback plan prepared
DESCRIBE_BUSINESS_NEED
RequiredWhat business problem the API solves
Example: E-commerce order management system
LIST_MAIN_FEATURES
RequiredCore features the API should support
Example: CRUD operations, search, filtering, webhooks
Professional code review with actionable feedback
Find and fix bugs 10x faster
Optimize database design and performance
Generate complete test suites automatically