SuperAPI AI Directory

ddd-api-designer

Coding & development

View repository

Updated 10-15 21:48

About this skill

DDD API Designer

A complete design guide from domain model to REST API: CQRS read-write separation, four-layer data object transformation chain (PO→DO→DTO→VO), unified response format, BFF multi-client adaptation, version management, and security design.

Workflow

  1. Identify Command vs Query — Divide domain behavior into commands (write) and queries (read), determining Method and endpoints
  2. Design data object transformation chain — Establish PO→DO→DTO→VO four-layer transformation, each layer with independent responsibilities
  3. Design REST endpoints — Command verb suffix, Query resource naming
  4. Define unified response format — Result<T> wrapper + business error code system
  5. Apply BFF — One BFF per frontend, data aggregation + format adaptation + protocol conversion
  6. Choose versioning strategy — Recommended URL Path: /api/v1/orders, CDN friendly
  7. Apply security controls — AuthN + AuthZ + three-layer validation + differentiated rate limiting

When to Use

✅ ALWAYS use when ❌ Skip when
API design, REST API, interface design Internal tools with no external consumers
DTO/VO design, data object transformation GraphQL/gRPC projects
BFF / Backend for Frontend When there is no domain model → domain-designer
OpenAPI / Swagger / API documentation Simple CRUD without DDD
API version management / security design Pure gRPC microservices (use protobuf IDL)
Need to expose DDD aggregates as REST API Rapid prototyping without concern for API specifications

Boundary

✅ Clearly applicable

  • Need to expose DDD domain model as REST API — CQRS read-write separation, full implementation of data object transformation chain
  • CQRS command/query separation design — independent Command DTO and Query DTO, each evolving separately
  • Unified API design for multiple clients (Web/iOS/MiniApp) — BFF pattern adapted per platform
  • Unified response format and error code system design — Result<T> + business error code standardization
  • OpenAPI/Swagger specification output — code generation strategy keeps interface and implementation in sync

⚠ Needs careful evaluation

  • Team unfamiliar with DDD/CQRS → learn basic concepts first
  • Monolithic application with no scaling needs → evaluate ROI, may be over-engineering
  • Existing API has no consumer compatibility requirements → version management can be simplified

❌ Not applicable

  • GraphQL/gRPC projects → use corresponding IDL and toolchain
  • Simple CRUD without DDD → first use a general REST framework or domain-designer
  • Rapid prototyping/demo stage → first use a simplified API, introduce specifications later
  • Pure gRPC microservices → use protobuf IDL + gRPC interceptors
  • Internal tools with no external consumers → simplify API design

CQRS API Design

Commands (write) are verb-driven, Queries (read) are resource-driven:

Dimension Command Query
HTTP Method POST/PUT/DELETE GET
URL verb Required (confirm, cancel) Not required
Request body Command object Query parameters only
DTO separation Independent Command DTO Independent Query DTO
Idempotency Must be implemented Naturally idempotent
Caching Never cached ETag, max-age
Response Created resource summary Data DTO / List

Principle: Command DTO and Query DTO are always defined separately. Sub-resource nesting is at most 2 levels. See references/patterns/cqrs-api-design.md

Data object conversion chain (PO → DO → DTO → VO)

Object Layer Responsibility Visibility
PO Infrastructure ORM mapping, corresponds to database structure Internal
DO Domain Rich domain model, contains business behavior Internal
DTO Interface/App Cross-layer and cross-service data transfer Semi-internal
VO Interface Page-specific display data External

Read direction: PO→DO→DTO→VO; write direction: VO→DTO→Command→DO→PO. One DO can be converted into multiple DTOs by scenario (detail DTO, summary DTO, etc.). Controller does not directly return domain objects. See references/examples-ref/data-object-transformation.md

API Design Specification

Rule Example
Plural nouns /orders ✓
Kebab-case /order-history ✓
Maximum 2 levels of nesting /orders/{id}/items
Write verb suffix /orders/{id}/confirm
Query parameters ?status=PAID&page=1
No URL verbs ❌ GET /getOrders → GET /orders

HTTP Status: 201 Created (create), 200 OK (query/update), 204 No Content (delete), 400 (validation/business), 404 (not found), 409 (concurrency conflict), 429 (rate limiting), 500 (internal error). See references/security/api-naming-conventions.md

Unified response format

Success:{ "code": 0, "message": "success", "data": T } — 201/200/204 Error:{ "code": 40001, "message": "...", "detail": "...", "requestId": "req-xxx" } — 400/404/409/429/500

Response wrapper Result<T> contains code + message + data + requestId. Error responses never return stack traces. See references/examples-ref/unified-response-format.md

BFF(Backend for Frontend)

One BFF per frontend (Web/iOS/MiniApp), responsibilities:

  • Data aggregation: combine data from multiple services into a page VO (1 frontend call replaces N calls)
  • Format adaptation: full fields for Web / streamlined fields for mobile
  • Protocol conversion: internal gRPC → external REST/JSON
  • Response shaping: remove internal fields, add UI metadata

Difference from API Gateway: BFF does view aggregation (page level), Gateway does routing + rate limiting (service level). BFF does not directly access the database and does not contain business logic. See references/patterns/BFF-design-pattern.md

API Version Management

Strategy Example Recommendation level
URL Path ★ /api/v1/orders → /api/v2/orders ★★★★★
Request Header Accept: vnd.company.v2+json ★★★☆☆
Query Param /api/orders?version=2 ★★☆☆☆

Recommended URL Path: intuitive, CDN-friendly, Swagger-compatible. Migration process: v1 → v1+v2 → v2 only → v1 sunset (410 Gone). See references/migration/api-versioning-strategies.md

API Security Design

Four-layer security model:

  1. Authentication: JWT Bearer Token / OAuth2 / API Key (service-to-service)
  2. Authorization: by bounded context + resource ownership + role
  3. Input validation: Controller format → Application business → Domain invariants
  4. Rate limiting: Command 50/s, Query 200/s, Auth 10/s. See references/security/api-security-design.md

Gotchas — Common Pitfalls

DTO exposing enum→string code | Command/Query DTO mixed use→separate | null safety→handle Optional | VO passing through DB fields→view customization | missing idempotency→Idempotency-Key | error passing through stack trace→requestId | deep nesting→≤2 levels | domain object serialization→via DTO/VO

Rules

  • Command/Query DTO separation — Write operations and read operations use independent DTOs; reusing the same structure is forbidden
  • Controller protocol conversion — The Controller layer only performs HTTP protocol adaptation, and contains no business logic or domain calls
  • Unified error code prefix — Business error 5-digit code: first digit category (4=client/5=server) + next two digits HTTP + last three digits specific error
  • BFF responsibility boundaries — The BFF only performs data aggregation and format adaptation, and does not directly access the database or contain business rules
  • Response wrapping — All API responses use Result<T> wrapping, with only 204 No Content and file downloads as exceptions

FAQ

Question Answer
Can DO and DTO fields be reused if they are the same? No. DO contains behavior, DTO is pure data, and their evolution directions differ.
Do all APIs need a unified response format? Yes, only file downloads and 204 can be exceptions.
How should error codes be designed? 5 digits: first digit category + next two digits HTTP + last three digits specific error.
When is a BFF needed? When there are multiple frontend platforms or the frontend needs to combine data from multiple services.
How many levels deep can sub-resources be nested at most? At most 2 levels; more than 2 levels indicates a problem with the aggregation boundary.
Can business logic be placed in the Controller? No, it only performs protocol conversion.

Keywords

CQRS API REST endpoint design PO DO DTO VO data object transformation unified response format BFF Backend for Frontend OpenAPI Swagger API versioning API security command query separation Result<T> response wrapper input validation rate limiting idempotency pagination design

References

Examples


🧭 DDD Skills Journey

📍 Current:ddd-api-designer — Step 4: API design and data conversion

Step 1 (awesome) → Step 2 (selector) → Step 3 (架构落地) → Step 4 (领域+CQRS+API) → Step 5 (审查) → Step 6 (辅助) → Step 7 (文档)
                                                                    ↑
                                         ⭐ ddd-api-designer: 领域模型 → REST API

← Previous stop: hand off to ddd-domain-designer skill — design the API after having the domain model first (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-domain-designer). → Next stop: hand off to ddd-code-reviewer skill — review API design compliance (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-code-reviewer). 🔗 Related: hand off to ddd-cqrs-architecture skill — CQRS in depth (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-cqrs-architecture) | ddd-architecture-doc skill — OpenAPI documentation output (Install: npx skills add full-stack-skills/ddd-skills --skill ddd-architecture-doc).

Core principle: Command and Query are designed separately. Keep in mind the four-layer conversion chain PO→DO→DTO→VO: DTO is decoupled from domain objects, and VO is decoupled from the database structure.