
Fullstack Guardian
Apply consistent REST URL structure, HTTP status codes, and standardized API error shapes while designing or reviewing backend endpoints.
Install
npx skills add https://github.com/jeffallan/claude-skills --skill fullstack-guardianWhat is this skill?
- REST collection and resource URL patterns including nested routes (users, posts, comments)
- HTTP status matrix covering 200/201/204/202 success and 400–429 client errors plus 5xx server cases
- TypeScript ApiError interface with machine-readable code and human message fields
- Maps verbs to semantics: GET list/detail, POST create, PUT/PATCH update, DELETE with 204
- Guardrail-oriented reference for fullstack API consistency across services
Adoption & trust: 3.1k installs on skills.sh; 9.7k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Entra App Registrationmicrosoft/azure-skills
Azure Aigatewaymicrosoft/azure-skills
Lark Openapi Explorerlarksuite/cli
Supabasesupabase/agent-skills
Firebase Auth Basicsfirebase/agent-skills
Firebase Data Connectfirebase/agent-skills
Journey fit
Primary fit
Primary shelf is Build because the skill encodes how to shape REST collections, nested resources, and typed error payloads during API implementation. backend is the canonical home for REST conventions, status-code semantics, and ApiError response contracts.
Common Questions / FAQ
Is Fullstack Guardian safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Fullstack Guardian
# API Design Standards ## RESTful API Conventions ### URL Structure ``` # Collection vs Resource GET /api/users # List all users POST /api/users # Create user GET /api/users/:id # Get single user PUT /api/users/:id # Full update PATCH /api/users/:id # Partial update DELETE /api/users/:id # Delete user # Nested resources GET /api/users/:id/posts # User's posts POST /api/users/:id/posts # Create post for user GET /api/posts/:id/comments # Comments on post ``` ### HTTP Status Codes ```typescript // Success codes 200 OK // GET, PUT, PATCH successful 201 Created // POST successful, resource created 204 No Content // DELETE successful, no body 202 Accepted // Async operation queued // Client error codes 400 Bad Request // Malformed request 401 Unauthorized // Authentication required 403 Forbidden // Authenticated but not authorized 404 Not Found // Resource doesn't exist 409 Conflict // Resource conflict (e.g., duplicate) 422 Unprocessable // Validation failed 429 Too Many Requests // Rate limit exceeded // Server error codes 500 Internal Server Error // Unhandled exception 502 Bad Gateway // Upstream service failed 503 Service Unavailable // Temporary downtime ``` ### Standardized Error Responses ```typescript interface ApiError { error: { code: string; // Machine-readable error code message: string; // Human-readable message details?: { // Field-level validation errors [field: string]: string[]; }; requestId: string; // For support/debugging timestamp: string; // ISO 8601 timestamp }; } // Examples { "error": { "code": "VALIDATION_ERROR", "message": "Invalid input data", "details": { "email": ["Must be a valid email address"], "password": ["Must be at least 12 characters"] }, "requestId": "req_abc123", "timestamp": "2025-01-15T10:30:00Z" } } { "error": { "code": "RESOURCE_NOT_FOUND", "message": "User not found", "requestId": "req_def456", "timestamp": "2025-01-15T10:31:00Z" } } ``` ### Pagination ```typescript // Query parameters GET /api/users?page=1&limit=20&sort=-createdAt&filter[role]=admin // Response format interface PaginatedResponse<T> { data: T[]; meta: { page: number; limit: number; total: number; totalPages: number; }; links?: { first: string; prev?: string; next?: string; last: string; }; } // Implementation @Get() async findAll( @Query('page', new DefaultValuePipe(1), ParseIntPipe) page: number, @Query('limit', new DefaultValuePipe(20), ParseIntPipe) limit: number, ) { const [data, total] = await this.service.findAndCount({ page, limit }); return { data, meta: { page, limit, total, totalPages: Math.ceil(total / limit), }, links: { first: `/api/users?page=1&limit=${limit}`, next: page < totalPages ? `/api/users?page=${page + 1}&limit=${limit}` : undefined, last: `/api/users?page=${totalPages}&limit=${limit}`, }, }; } ``` ## API Versioning ### URL Path Versioning (Recommended) ```typescript // Version in URL path GET /api/v1/users GET /api/v2/users // Express routing app.use('/api/v1', v1Router); app.use('/api/v2', v2Router); // NestJS versioning @Controller({ version: '1', path: 'users' }) export class UsersV1Controller {} @Controller({ version: '2', path: 'users' }) export class UsersV2Controller {} ``` ### Header Versioning (Alternative) ```typescript // Request header GET /api/users Accept-Version: v2 // Middleware app.use((req, res, next) => { const version = req.headers['accept-version'] || 'v1'; req.apiVersion = version; next(); }); ``` ## Rate Limiting ### Per-Endpoint Configuration ```typescript // Express with express-rate-limit import rateLimit from 'express-rate-limit'; const generalLimiter