name: api-architecture version: "2.0.0" description: REST, GraphQL, and hybrid API architecture patterns for building scalable and maintainable APIs sasmp_version: "1.3.0" bonded_agent: 01-api-architect bond_type: PRIMARY_BOND
Skill Configuration
atomic_design: single_responsibility: "API paradigm selection and architecture decisions" boundaries: includes: [rest_design, graphql_design, hybrid_patterns, api_versioning] excludes: [implementation_details, security_policies, database_design]
parameter_validation: schema: type: object properties: api_style: type: string enum: [rest, graphql, grpc, hybrid] description: "Target API paradigm" scale_requirements: type: object properties: requests_per_second: { type: number, minimum: 0 } latency_target_ms: { type: number, minimum: 0 } use_case: type: string enum: [public_api, internal_api, partner_api, mobile_backend]
retry_config: enabled: true max_attempts: 3 backoff: type: exponential initial_delay_ms: 1000 max_delay_ms: 30000 multiplier: 2
logging: level: INFO fields: [skill_name, api_style, decision, duration_ms]
dependencies: skills: [rest, graphql, versioning] agents: [01-api-architect]
API Architecture Skill
Purpose
Select and design the optimal API architecture for your use case.
Decision Matrix
┌──────────────────────────────────────────────────────────────────┐
│ API Style Selection │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Use Case → Recommended Style │
│ ───────────────────────────────────────────────────────────── │
│ Public API + Wide adoption → REST (OpenAPI 3.1) │
│ Complex queries + Frontend-heavy → GraphQL │
│ High performance + Internal → gRPC │
│ Mobile + Offline support → REST + GraphQL hybrid │
│ Microservices communication → gRPC / Event-driven │
│ Real-time updates → GraphQL Subscriptions │
│ │
└──────────────────────────────────────────────────────────────────┘
API Comparison
| Aspect | REST | GraphQL | gRPC |
|---|---|---|---|
| Learning curve | Low | Medium | High |
| Flexibility | Low | High | Medium |
| Performance | Good | Good | Excellent |
| Caching | Easy (HTTP) | Complex | Custom |
| Tooling | Excellent | Good | Good |
| Documentation | OpenAPI | SDL | Protobuf |
| Browser support | Native | Native | Limited |
REST Architecture (Richardson Maturity Model)
Level 0: Single endpoint, POST everything
Level 1: Multiple endpoints per resource
Level 2: Proper HTTP methods + status codes ← Target
Level 3: HATEOAS (hypermedia links)
Resource Design
# Good resource naming
GET /api/v1/users # List users
GET /api/v1/users/{id} # Get user
POST /api/v1/users # Create user
PUT /api/v1/users/{id} # Replace user
PATCH /api/v1/users/{id} # Update user
DELETE /api/v1/users/{id} # Delete user
# Nested resources (max 2 levels)
GET /api/v1/users/{id}/orders # User's orders
# Actions (when CRUD doesn't fit)
POST /api/v1/orders/{id}/cancel
POST /api/v1/users/{id}/verify
GraphQL Architecture
# Schema-first design
type Query {
user(id: ID!): User
users(first: Int, after: String): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}
type Subscription {
userCreated: User!
orderStatusChanged(orderId: ID!): Order!
}
Hybrid Strategy
┌─────────────────────────────────────────────────────────┐
│ API Gateway │
├─────────────────────────────────────────────────────────┤
│ │
│ Public Clients ────► REST API (OpenAPI) │
│ │
│ Web/Mobile App ────► GraphQL API │
│ │
│ Internal Services ─► gRPC │
│ │
└─────────────────────────────────────────────────────────┘
Versioning Strategies
| Strategy | Example | Pros | Cons |
|---|---|---|---|
| URL path | /api/v1/users | Clear, cacheable | URL pollution |
| Header | Accept: application/vnd.api.v1+json | Clean URLs | Hidden |
| Query param | /api/users?version=1 | Flexible | Unconventional |
Recommendation: URL versioning for public APIs, header for internal.
Unit Test Template
import { describe, it, expect } from 'vitest';
import { selectApiStyle, validateResourceNaming } from './api-architecture';
describe('API Architecture Skill', () => {
describe('selectApiStyle', () => {
it('should recommend REST for public APIs', () => {
const result = selectApiStyle({
use_case: 'public_api',
audience: 'external',
});
expect(result.style).toBe('rest');
expect(result.reasons).toContain('wide tooling support');
});
it('should recommend GraphQL for complex frontend needs', () => {
const result = selectApiStyle({
use_case: 'internal_api',
complex_queries: true,
frontend_heavy: true,
});
expect(result.style).toBe('graphql');
});
});
describe('validateResourceNaming', () => {
it('should accept valid resource names', () => {
expect(validateResourceNaming('/api/v1/users')).toBe(true);
expect(validateResourceNaming('/api/v1/users/{id}/orders')).toBe(true);
});
it('should reject invalid resource names', () => {
expect(validateResourceNaming('/api/v1/getUsers')).toBe(false); // verb in name
expect(validateResourceNaming('/api/v1/user')).toBe(false); // singular
});
});
});
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Over-fetching (REST) | Too much data returned | Add field selection or use GraphQL |
| Under-fetching (REST) | Multiple round trips | Embed related resources or use GraphQL |
| N+1 queries (GraphQL) | Resolver per field | Use DataLoader for batching |
| Version conflicts | Breaking changes | Semantic versioning + deprecation policy |
Quality Checklist
- API style matches use case requirements
- Resource naming follows conventions
- Versioning strategy defined
- Error response format standardized
- Pagination strategy chosen
- Rate limiting planned