Api contract validation
Skill TheophilusChinomona/idev/skills/api-contract-validation
Claude Code plugin: token-optimized dev workflow — cached project context, pattern scanners, build & wiring verification, session persistence, self-review. 23 skills, 3 agents, 4 commands.
npx -y skills add TheophilusChinomona/idev --skill api-contract-validationAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Verifies frontend API calls match backend endpoints (URL paths, HTTP methods, request/response types). Use after creating or modifying API endpoints, service functions, or DTOs, or when asked to validate API alignment, check FE-BE contracts, or generate API contract docs.
SKILL.md
8.1 KB, as published. Nobody here has run it
API Contract Validation Skill
Purpose
Verify that frontend API calls and backend API endpoints agree on URL paths, HTTP methods, request/response shapes, and field types. Catches type mismatches, missing fields, and wrong URLs before runtime.
Activation
- After creating a new API endpoint (backend) or service function (frontend)
- After modifying a DTO, type, or API response shape
- When user reports a data mismatch between FE and BE
How It Works
This skill compares frontend service calls against backend controller signatures to find mismatches. It does NOT assume any specific stack — it detects how each side defines its contracts.
Phase 1: Extract Frontend Contract
Detect how the frontend defines API calls:
TypeScript/JavaScript (Axios/Fetch):
Grep service files for HTTP calls:
axios.get<ResponseType>("api/endpoint")
axios.post<ResponseType>("api/endpoint", requestBody)
fetch("api/endpoint", { method: "POST", body: ... })
Extract: URL, HTTP method, request body type, response type
React Query hooks:
Find useQuery/useMutation calls that wrap service functions
Extract: query key, service function reference
Vue/Angular:
Similar pattern — grep for HttpClient or $http calls
Extract per endpoint:
- URL path (e.g., "api/orders/get-all")
- HTTP method (GET, POST, PUT, DELETE)
- Request body type (TypeScript interface/type)
- Response type (TypeScript interface/type)
- Field names and types from the request/response interfaces
Phase 2: Extract Backend Contract
Detect how the backend defines API routes:
.NET:
[Route("api/orders")]
[HttpGet("get-all")] → full path: api/orders/get-all
Method signature: Task<IActionResult> GetAll()
[FromBody] OrderCreateDto dto → request body type
Return type: wrapped in GetResultDtoAsync → extract inner DTO
Express/NestJS:
router.get("/api/endpoint", handler)
@Get("/endpoint") → extract path
Request body: req.body typed or validated by schema
FastAPI:
@app.get("/api/endpoint", response_model=ResponseType)
Request body: Pydantic model
Django:
urlpatterns path("api/endpoint", view)
Serializer class defines request/response shape
Spring:
@GetMapping("/api/endpoint")
@RequestBody CreateDto dto → request body
Return type: ResponseEntity<Dto>
Extract per endpoint:
- URL path
- HTTP method
- Request body DTO (field names and types)
- Response DTO (field names and types)
Phase 3: Compare Contracts
For each endpoint, compare FE and BE:
URL Match
FE: "api/orders/get-all" (GET)
BE: [Route("api/orders")] + [HttpGet("get-all")] → "api/orders/get-all" (GET)
Result: ✓ Match
Field Name Match
FE type: { templateId: number, templateKey: string, templateName: string }
BE DTO: { TemplateId: int, TemplateKey: Guid, TemplateName: string }
Check: Do FE field names match BE field names (accounting for casing)?
templateId ↔ TemplateId → ✓ (camelCase ↔ PascalCase, auto-converted by JSON serializer)
templateKey ↔ TemplateKey → ✓
Field Type Match
FE: templateKey: string
BE: TemplateKey: Guid
Question: Does Guid serialize to string in JSON? → Yes ✓
FE: createdDate: string
BE: CreatedDate: DateTime
Question: Does DateTime serialize to string (ISO format)? → Yes ✓
FE: templateId: number
BE: TemplateId: int
Question: Does int serialize to number? → Yes ✓
FE: isDefault: boolean
BE: IsDefault: bool
Question: Does bool serialize to boolean? → Yes ✓
Common Type Mappings (auto-detected per stack)
.NET → TypeScript:
int, long → number
decimal, double, float → number
string → string
bool → boolean
DateTime → string (ISO 8601)
Guid → string
List<T> → T[]
IList<T> → T[]
T? (nullable) → T | null | undefined
Python → TypeScript:
int, float → number
str → string
bool → boolean
datetime → string
uuid → string
List[T] → T[]
Optional[T] → T | null
Java → TypeScript:
int, long, Integer, Long → number
String → string
boolean, Boolean → boolean
LocalDateTime → string
UUID → string
List<T> → T[]
Phase 4: Report Results
API Contract Validation: api/orders
✓ GET /get-all → URL match, response types match
✓ GET /get-by-id/{id} → URL match, response types match
✓ POST /create → URL match, request body match, response match
✗ PUT /update/{key} → FE sends templateKey as string, BE expects Guid
Fix: Guid auto-parses from string — OK at runtime, but FE type should be string
✓ DELETE /delete/{key} → URL match
Missing in FE: GET /get-by-key/{key} (BE endpoint exists, no FE service call)
Missing in BE: (none)
Phase 5: Auto-Fix Common Issues
Missing FE service function for existing BE endpoint:
→ Generate the service function following the project's detected conventions
(see the frontend-patterns skill cache at .claude/idev/frontend-patterns/cache.md)
Missing BE endpoint for existing FE service call:
→ Flag as error — this causes 404 at runtime
(see the lessons-learned skill log if present for past instances)
Type mismatch:
→ If auto-serializable (Guid→string, DateTime→string): warn but pass
→ If incompatible (number↔string, boolean↔string): fail and suggest fix
Field name mismatch:
→ Check if JSON serializer handles casing (camelCase ↔ PascalCase)
→ If custom serialization: flag for manual review
Phase 6: Cache Format
Write to .claude/idev/api-contract-validation/cache.json:
{
"generated": "YYYY-MM-DD",
"contracts": [
{
"endpoint": "api/orders/get-all",
"httpMethod": "GET",
"feService": "relative/path/to/service.ts",
"feFunction": "getOrders",
"feResponseType": "Order[]",
"beController": "relative/path/to/Controller.cs",
"beMethod": "GetAll",
"beResponseType": "IList<OrderDto>",
"status": "valid|mismatch|missing-fe|missing-be",
"issues": []
}
],
"typeMapping": {
"serializationFormat": "System.Text.Json|Newtonsoft|json",
"casingConversion": "camelCase (auto)"
}
}
Phase 7: Documentation Output (Optional)
When asked to generate API contract docs (or after validating a full feature), write one compact doc per feature to .claude/idev/api-contracts/<feature>.md:
# Orders API Contract
> Updated: YYYY-MM-DD | Source: api-contract-validation
| Method | Endpoint | FE function | Request | Response | Status |
|--------|-----------------------|---------------|----------------|----------------|--------|
| GET | api/orders/get-all | getOrders | — | OrderDto[] | valid |
| POST | api/orders/create | createOrder | OrderCreateDto | OrderDto | valid |
| PUT | api/orders/update/{k} | updateOrder | OrderUpdateDto | OrderDto | type mismatch: key string↔Guid |
Notes:
- Auth: all endpoints require [Authorize]
- Casing: camelCase ↔ PascalCase (auto via System.Text.Json)
Rules:
- Keep each doc under ~40 lines — a table plus brief notes, not prose
- Update the existing doc in place; do not duplicate
- Derive entries from the validation cache (Phase 6) rather than re-scanning source
- Paths: cache lives at
.claude/idev/api-contract-validation/cache.json; generated docs live in.claude/idev/api-contracts/
Anti-Patterns
- Do NOT assume casing matches — check JSON serializer config
- Do NOT flag Guid→string as a type error — it serializes fine
- Do NOT skip validation for "simple" endpoints — validate all
- Do NOT run full validation after every single file change — run after feature completion
- Do NOT hardcode type mappings — detect serializer and derive them