api-design-principles

Master REST API design principles to build intuitive, scalable, and maintainable APIs. Use when designing new APIs, reviewing API specifications, or establishing API design standards.

$ Installieren

git clone https://github.com/majiayu000/claude-skill-registry /tmp/claude-skill-registry && cp -r /tmp/claude-skill-registry/skills/design/api-design-principles ~/.claude/skills/claude-skill-registry

// tip: Run this command in your terminal to install the skill


name: api-design-principles description: "Master REST API design principles to build intuitive, scalable, and maintainable APIs. Use when designing new APIs, reviewing API specifications, or establishing API design standards." layer: 2 tech_stack: [agnostic] topics: [rest-api, versioning, pagination, http-methods, status-codes, api-design] depends_on: [] complements: [technical-design-patterns, abp-api-implementation] keywords: [REST, API, Endpoint, GET, POST, PUT, DELETE, OpenAPI, Swagger, HTTP]

API Design Principles

Master REST API design principles to build intuitive, scalable, and maintainable APIs. This skill focuses on design theory - for implementation patterns, see abp-api-implementation or abp-service-patterns.

When to Use This Skill

  • Designing new REST API contracts
  • Reviewing API specifications before implementation
  • Establishing API design standards for your team
  • Planning API versioning and evolution strategy
  • Creating developer-friendly API documentation

Audience

  • Backend Architects - API contract design
  • Tech Leads - Standards and review
  • Business Analysts - Understanding API capabilities

For Implementation: Use abp-service-patterns for AppService code, api-response-patterns for response wrappers, fluentvalidation-patterns for validation.


Core Principles

1. Resource-Oriented Design

APIs expose resources (nouns), not actions (verbs).

ConceptGoodBad
Resource naming/patients, /appointments/getPatients, /createAppointment
Actions via HTTP methodsPOST /patientsPOST /createPatient
Plural for collections/patients/patient
Consistent casingkebab-case or camelCaseMixed styles

Resource Hierarchy:

/api/v1/patients                    # Collection
/api/v1/patients/{id}               # Single resource
/api/v1/patients/{id}/appointments  # Nested collection
/api/v1/appointments/{id}           # Direct access to nested resource

Avoid Deep Nesting (max 2 levels):

# Good - Shallow
GET /api/v1/patients/{id}/appointments
GET /api/v1/appointments/{id}

# Bad - Too deep
GET /api/v1/clinics/{id}/doctors/{id}/patients/{id}/appointments/{id}

2. HTTP Methods Semantics

MethodPurposeIdempotentSafeRequest Body
GETRetrieve resource(s)YesYesNo
POSTCreate resourceNoNoYes
PUTReplace entire resourceYesNoYes
PATCHPartial updateYes*NoYes
DELETERemove resourceYesNoNo

Idempotent: Multiple identical requests produce same result. Safe: Does not modify server state.

3. HTTP Status Codes

Success (2xx):

CodeMeaningUse When
200 OKSuccessGET, PUT, PATCH succeeded
201 CreatedResource createdPOST succeeded
204 No ContentSuccess, no bodyDELETE succeeded

Client Errors (4xx):

CodeMeaningUse When
400 Bad RequestMalformed requestInvalid JSON, missing required headers
401 UnauthorizedNot authenticatedMissing or invalid token
403 ForbiddenNot authorizedValid token, insufficient permissions
404 Not FoundResource doesn't existID not found
409 ConflictState conflictDuplicate email, version mismatch
422 Unprocessable EntityValidation failedBusiness rule violations
429 Too Many RequestsRate limitedExceeded request quota

Server Errors (5xx):

CodeMeaningUse When
500 Internal Server ErrorUnexpected errorUnhandled exception
503 Service UnavailableTemporarily downMaintenance, overload

Design Patterns

Pattern 1: Pagination

Always paginate collections - Never return unbounded lists.

Offset-Based (simple, good for small datasets):

GET /api/v1/patients?page=2&pageSize=20

Response:
{
  "items": [...],
  "totalCount": 150,
  "pageNumber": 2,
  "pageSize": 20,
  "totalPages": 8
}

Cursor-Based (efficient for large datasets, real-time data):

GET /api/v1/patients?cursor=eyJpZCI6MTIzfQ&limit=20

Response:
{
  "items": [...],
  "nextCursor": "eyJpZCI6MTQzfQ",
  "hasMore": true
}
ApproachProsConsBest For
OffsetSimple, supports jumping to pageSlow on large datasets, inconsistent with real-time dataAdmin panels, reports
CursorFast, consistentCan't jump to arbitrary pageInfinite scroll, feeds

Pattern 2: Filtering and Sorting

Query Parameters for Filtering:

GET /api/v1/patients?status=active
GET /api/v1/patients?status=active&createdAfter=2025-01-01
GET /api/v1/patients?doctorId=abc-123

Sorting:

GET /api/v1/patients?sorting=name
GET /api/v1/patients?sorting=createdAt desc
GET /api/v1/patients?sorting=lastName,firstName

Searching:

GET /api/v1/patients?filter=john
GET /api/v1/patients?search=john doe

Design Decisions:

  • Use WhereIf pattern - only apply filter if parameter provided
  • Define allowed sort fields (security - don't expose internal fields)
  • Set maximum page size (prevent abuse)

Pattern 3: Error Response Design

Consistent Structure:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "One or more validation errors occurred.",
    "details": [
      {
        "field": "email",
        "message": "Invalid email format."
      },
      {
        "field": "dateOfBirth",
        "message": "Date of birth cannot be in the future."
      }
    ],
    "traceId": "00-abc123-def456-00"
  }
}

Error Codes (for client handling):

CodeHTTP StatusMeaning
VALIDATION_ERROR422Input validation failed
NOT_FOUND404Resource doesn't exist
UNAUTHORIZED401Authentication required
FORBIDDEN403Permission denied
CONFLICT409State conflict
RATE_LIMITED429Too many requests

Pattern 4: Versioning Strategy

URL Versioning (Recommended for ABP):

/api/v1/patients
/api/v2/patients
StrategyExampleProsCons
URL Path/api/v1/Clear, easy routingMultiple URLs
HeaderApi-Version: 1Clean URLsHidden, harder to test
Query Param?version=1Easy testingCan be forgotten

Versioning Policy:

  • Major version for breaking changes
  • Support N-1 version minimum
  • Deprecation notice 6+ months before removal
  • Document migration path

Pattern 5: Resource Relationships

Embedding vs Linking:

// Embedded (fewer requests, larger payload)
{
  "id": "patient-123",
  "name": "John Doe",
  "doctor": {
    "id": "doctor-456",
    "name": "Dr. Smith"
  }
}

// Linked (smaller payload, more requests)
{
  "id": "patient-123",
  "name": "John Doe",
  "doctorId": "doctor-456"
}

// Hybrid (with expand parameter)
GET /api/v1/patients/123?expand=doctor,appointments

Decision Criteria:

Use EmbeddingUse Linking
Related data always neededRelated data rarely needed
Few relationshipsMany relationships
Related data is smallRelated data is large

API Contract Checklist

Resource Design

  • Resources are nouns, not verbs
  • Plural names for collections
  • Consistent naming convention
  • Max 2 levels of nesting
  • All CRUD mapped to correct HTTP methods

Request/Response

  • All collections paginated
  • Default and max page size defined
  • Filter parameters documented
  • Sorting parameters documented
  • Consistent error response format

Security

  • Authentication method defined
  • Authorization on all mutating endpoints
  • Rate limiting configured
  • Sensitive data not in URLs
  • CORS configured

Documentation

  • OpenAPI/Swagger spec
  • All endpoints documented
  • Request/response examples
  • Error responses documented

Anti-Patterns to Avoid

Anti-PatternProblemSolution
Verb endpointsPOST /createPatientPOST /patients
Ignoring HTTP methodsUsing POST for everythingUse appropriate method
No paginationReturning 10,000 itemsAlways paginate
Inconsistent errorsDifferent formats per endpointStandardize error structure
Exposing internalsDatabase columns in APIDesign API contract separately
No versioningBreaking changes break clientsVersion from day one
Deep nesting/a/{id}/b/{id}/c/{id}/dFlatten, max 2 levels

Integration with Other Skills

NeedSkill
AppService implementationabp-service-patterns
Response wrappersapi-response-patterns
Input validationfluentvalidation-patterns
Query optimizationlinq-optimization-patterns
Technical design docstechnical-design-patterns

References

  • references/rest-best-practices.md - Detailed REST patterns
  • assets/api-design-checklist.md - Pre-implementation checklist