API Standards Validator
Validate REST API design standards compliance including versioning, naming conventions, HTTP methods, status codes, pagination, and Swagger documentation.
What This Skill Does
Performs comprehensive API standards validation:
- Versioning: Checks
/v1/prefix on all routes - Resource Naming: Validates plural nouns, lowercase-with-hyphens
- HTTP Methods: Validates proper method usage and status codes
- Pagination: Ensures list endpoints support pagination
- Swagger Docs: Verifies complete OpenAPI documentation
- Error Mapping: Checks proper status code usage
When to Use This Skill
Use when you need to:
- Validate API endpoints before deployment
- Check new endpoints for standards compliance
- Review API design during code review
- Ensure Swagger documentation completeness
Examples:
- "Validate the User API endpoints"
- "Check if Product API follows design standards"
- "Review Order API for compliance"
API Design Standards
Versioning Rules
All controllers MUST be prefixed with /v1/:
// ✅ CORRECT
@JsonController('/v1/users')
export class UserController {}
@JsonController('/v1/sms-messages')
export class SmsMessageController {}
// ❌ WRONG
@JsonController('/users') // Missing version
@JsonController('/api/users') // Wrong format
Resource Naming Rules
Must be:
- Plural nouns:
/v1/usersnot/v1/user - Lowercase with hyphens:
/v1/sms-messages - No verbs:
/v1/usersnot/v1/getUsers
// ✅ CORRECT
'/v1/users'
'/v1/products'
'/v1/sms-messages'
'/v1/order-items'
// ❌ WRONG
'/v1/user' // Singular
'/v1/getUsers' // Verb
'/v1/Users' // Wrong casing
'/v1/sms_messages' // Underscores
HTTP Methods and Status Codes
Expected patterns:
- POST (Create) → 201 Created
- GET (Read) → 200 OK
- PATCH (Partial Update) → 200 OK
- PUT (Full Update) → 200 OK
- DELETE → 204 No Content
Error status codes:
- 400 Bad Request → Validation errors
- 401 Unauthorized → Authentication required
- 403 Forbidden → Permission denied
- 404 Not Found → Resource not found
- 409 Conflict → Duplicate resource
- 422 Unprocessable Entity → Business rule violation
- 500 Internal Server Error → Unexpected errors
Pagination Requirements
List endpoints MUST support pagination with DTOs:
// ✅ CORRECT
export class QueryEntityDto {
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(1)
limit?: number = 20;
@IsOptional()
@Type(() => Number)
@IsNumber()
@Min(0)
offset?: number = 0;
sortBy: z.enum(['createdAt', 'name']).optional(),
order: z.enum(['asc', 'desc']).default('desc'),
});
// Response format
{
items: Entity[],
total: number,
limit: number,
offset: number
}
Swagger Documentation Requirements
All endpoints MUST have:
.post('/', controller.create.bind(controller), {
body: CreateSchema,
detail: {
summary: 'Create entity', // Required
description: 'Detailed description', // Recommended
tags: ['Entities'], // Required
responses: { // Required
201: { description: 'Created' },
400: { description: 'Invalid input' },
409: { description: 'Duplicate' },
},
},
})
Validation Checks
Versioning Validation
Checks:
- All route prefixes include
/v1/ - No routes without versioning
- Consistent version across all endpoints
Reports:
CRITICAL: Missing API version
File: src/contexts/user/presentation/user.routes.ts:5
Issue: Route prefix '/users' lacks /v1/
Fix: Change to '/v1/users'
Resource Naming Validation
Checks:
- Resources are plural nouns
- Lowercase with hyphens (not underscores or camelCase)
- No verbs in resource names
- Proper REST conventions
Reports:
CRITICAL: Singular resource name
File: src/contexts/user/presentation/user.routes.ts:5
Issue: Resource '/v1/user' is singular
Fix: Change to '/v1/users'
CRITICAL: Verb in resource name
File: src/contexts/user/presentation/user.routes.ts:10
Issue: Resource '/v1/getUsers' contains verb
Fix: Use '/v1/users' with GET method
HTTP Method Validation
Checks:
- GET for reads (200 OK)
- POST for creates (201 Created)
- PATCH/PUT for updates (200 OK)
- DELETE for deletions (204 No Content)
- Swagger responses match expected codes
Reports:
CRITICAL: Wrong status code for POST
File: src/contexts/user/presentation/user.routes.ts:15
Issue: POST endpoint documents 200, should be 201
Fix: Change response code to 201 in Swagger detail
Error Mapping Validation
Checks:
- Controllers map domain errors to HTTP exceptions
- Correct status codes used:
- EntityNotFoundError → 404
- DuplicateError → 409
- ValidationError → 400
- UnauthorizedError → 401
- ForbiddenError → 403
- BusinessRuleViolation → 422
Reports:
WARNING: Missing error mapping
File: src/contexts/user/presentation/user.controller.ts:20
Issue: EntityNotFoundError not mapped to HttpException
Fix: Add error mapping:
if (error instanceof EntityNotFoundError) {
throw new HttpException(404, error.message, error.code);
}
Pagination Validation
Checks:
- List endpoints have
limitparameter - List endpoints have
offsetparameter - Defaults defined for pagination
- Response includes total count
Reports:
CRITICAL: Missing pagination
File: src/contexts/user/presentation/schemas/query-user.schema.ts
Issue: Query schema lacks limit and offset
Fix: Add pagination fields:
limit: z.coerce.number().min(1).max(100).default(10),
offset: z.coerce.number().min(0).default(0),
Swagger Documentation Validation
Checks:
- All endpoints have
detailobject summaryfield presenttagsarray presentresponsesobject with status codes- Response descriptions provided
Reports:
WARNING: Incomplete Swagger documentation
File: src/contexts/user/presentation/user.routes.ts:15
Issue: POST endpoint missing 'responses' in detail
Fix: Add responses object:
responses: {
201: { description: 'User created' },
400: { description: 'Invalid input' },
409: { description: 'Email exists' },
}
Controller Binding Validation
Checks:
- Controller methods use
.bind(controller) - Controller resolved from DI container
Reports:
CRITICAL: Controller method not bound
File: src/contexts/user/presentation/user.routes.ts:12
Issue: .post('/', controller.create) missing .bind()
Fix: Add .bind(controller): .post('/', controller.create.bind(controller))
Common Violations
Missing Versioning
// ❌ WRONG
new Elysia({ prefix: '/users' })
// ✅ CORRECT
new Elysia({ prefix: '/v1/users' })
Wrong Resource Naming
// ❌ WRONG - Singular
new Elysia({ prefix: '/v1/user' })
// ❌ WRONG - Verb
.get('/getUser', ...)
// ✅ CORRECT
new Elysia({ prefix: '/v1/users' })
.get('/:id', ...)
Wrong Status Code
// ❌ WRONG
.post('/', ..., {
detail: {
responses: {
200: {} // Should be 201 for POST
}
}
})
// ✅ CORRECT
.post('/', ..., {
detail: {
responses: {
201: { description: 'Created' }
}
}
})
Missing Pagination
// ❌ WRONG
export const QuerySchema = z.object({
search: z.string().optional(),
});
// ✅ CORRECT
export const QuerySchema = z.object({
limit: z.coerce.number().min(1).max(100).default(10),
offset: z.coerce.number().min(0).default(0),
search: z.string().optional(),
});
Incomplete Swagger
// ❌ WRONG
.post('/', controller.create.bind(controller), {
body: CreateSchema,
})
// ✅ CORRECT
.post('/', controller.create.bind(controller), {
body: CreateSchema,
detail: {
summary: 'Create user',
tags: ['Users'],
responses: {
201: { description: 'User created' },
400: { description: 'Invalid input' },
},
},
})
Report Format
- Summary: Endpoints validated
- Endpoint Inventory: List all found endpoints
- Critical Issues: Must fix immediately
- Warnings: Should fix before deployment
- Suggestions: Nice-to-have improvements
- Compliance Score: Percentage of standards met
Integration
The validator is read-only - it never modifies code. After review:
- Fix critical issues (versioning, naming)
- Address warnings (Swagger docs, pagination)
- Consider suggestions (additional docs)
- Re-run validator to verify compliance
Related Skills
- ddd-validator: Validate DDD architecture
- ddd-api-generator: Generate compliant APIs
- di-helper: Check DI setup
微信扫一扫