690404:1139 Modify ADR
This commit is contained in:
@@ -0,0 +1,422 @@
|
||||
# ADR-003: API Design Strategy
|
||||
|
||||
**Status:** ✅ Accepted (Implementation Ready)
|
||||
**Date:** 2026-04-04
|
||||
**Decision Makers:** Development Team, System Architect
|
||||
**Related Documents:**
|
||||
|
||||
- [API Design & Error Handling](../02-Architecture/02-04-api-design.md)
|
||||
- [Backend Guidelines](../05-Engineering-Guidelines/05-02-backend-guidelines.md)
|
||||
- [ADR-005: Technology Stack](./ADR-005-technology-stack.md)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Gap Analysis & Purpose
|
||||
|
||||
### ปิด Gap จากเอกสาร:
|
||||
- **API Design & Error Handling** - Section 2: "ระบบต้องใช้ RESTful Principles และมีความสอดคล้องกัน"
|
||||
- เหตุผล: ต้องการบันทึกการตัดสินใจเกี่ยวกับ API Design Patterns ที่ใช้จริงในระบบ
|
||||
- **Backend Guidelines** - Section 3: "การออกแบบ API ต้องรองรับ TypeScript และ NestJS Patterns"
|
||||
- เหตุผล: ต้องการทำให้ API Design สอดคล้องกับ NestJS Ecosystem
|
||||
|
||||
### แก้ไขความขัดแย้ง:
|
||||
- **REST Purity** vs **Pragmatic API Design**: ต้องการความสวยงามของ REST แต่ต้องรองรับ Business Logic ที่ซับซ้อน
|
||||
- การตัดสินใจนี้ช่วยแก้ไขโดย: ใช้ RESTful หลักแต่เพิ่ม Pragmatic Patterns สำหรับ Workflow และ Business Operations
|
||||
|
||||
---
|
||||
|
||||
## Context and Problem Statement
|
||||
|
||||
LCBP3-DMS ต้องการ API Design ที่:
|
||||
|
||||
1. **Consistent:** ทุก Endpoint ใช้ Patterns เดียวกัน
|
||||
2. **Type-Safe:** รองรับ TypeScript และ DTO Validation
|
||||
3. **Business-Ready:** รองรับ Workflow Operations และ Complex Business Logic
|
||||
4. **Document-Driven:** Auto-generate Swagger Documentation
|
||||
5. **Performance-Oriented:** รองรับ Pagination, Filtering, และ Caching
|
||||
|
||||
### Key Challenges
|
||||
|
||||
1. **Resource Naming:** การตั้งชื่อ Resources ที่สะท้อน Business Domain
|
||||
2. **Complex Operations:** Workflow transitions, Document numbering ที่ไม่ใช่ CRUD ธรรมดา
|
||||
3. **Response Consistency:** การคืนค่าที่สม่ำเสมอทั้ง Single และ Collection
|
||||
4. **Error Handling:** การจัดการ Business Exceptions และ Validation Errors
|
||||
5. **Versioning:** การเตรียมพร้อมสำหรับ API Evolution
|
||||
|
||||
---
|
||||
|
||||
## Decision Drivers
|
||||
|
||||
- **Developer Experience:** ง่ายต่อการใช้งานและ Debug
|
||||
- **Type Safety:** ป้องกัน Runtime Errors ด้วย TypeScript
|
||||
- **Business Alignment:** API สะท้อน Business Processes จริง
|
||||
- **Performance:** รองรับ High-volume Operations
|
||||
- **Documentation:** Auto-generated และ Up-to-date
|
||||
- **Testing:** ง่ายต่อการ Unit Test และ Integration Test
|
||||
|
||||
---
|
||||
|
||||
## Considered Options
|
||||
|
||||
### Option 1: Pure REST with Resource Endpoints Only
|
||||
|
||||
**แนวทาง:** ใช้ REST Resources เท่านั้น ไม่มี Action Endpoints
|
||||
|
||||
**Pros:**
|
||||
|
||||
- ✅ RESTful purity
|
||||
- ✅ Simple to understand
|
||||
- ✅ Standard HTTP semantics
|
||||
|
||||
**Cons:**
|
||||
|
||||
- ❌ Difficult for complex business operations
|
||||
- ❌ Workflow transitions become awkward
|
||||
- ❌ Document numbering doesn't fit resource model
|
||||
|
||||
### Option 2: RPC-style with Action Endpoints
|
||||
|
||||
**แนวทาง:** ใช้ Action Endpoints สำหรับทุก Business Operation
|
||||
|
||||
**Pros:**
|
||||
|
||||
- ✅ Clear business intent
|
||||
- ✅ Easy for complex operations
|
||||
- ✅ Direct mapping to use cases
|
||||
|
||||
**Cons:**
|
||||
|
||||
- ❌ Not RESTful
|
||||
- ❌ Inconsistent patterns
|
||||
- ❌ Hard to document with Swagger
|
||||
|
||||
### Option 3: **Hybrid REST + Action Endpoints** ⭐ (Selected)
|
||||
|
||||
**แนวทาง:** REST สำหรับ CRUD และ Action Endpoints สำหรับ Business Operations
|
||||
|
||||
**Pros:**
|
||||
|
||||
- ✅ **Best of Both Worlds:** REST ที่เหมาะสม + Actions ที่ชัดเจน
|
||||
- ✅ **Business Clarity:** Workflow actions อยู่ใน endpoints ที่เข้าใจง่าย
|
||||
- ✅ **Type Safety:** DTOs สำหรับทุก operation
|
||||
- ✅ **Documentation:** Swagger สามารถ document ได้ทั้งสองแบบ
|
||||
- ✅ **Consistency:** Clear naming conventions
|
||||
|
||||
**Cons:**
|
||||
|
||||
- ❌ Slightly more complex
|
||||
- ❌ Requires developer discipline
|
||||
|
||||
---
|
||||
|
||||
## Decision Outcome
|
||||
|
||||
**Chosen Option:** Option 3 - Hybrid REST + Action Endpoints
|
||||
|
||||
### Rationale
|
||||
|
||||
เลือก Hybrid Approach เนื่องจาก:
|
||||
|
||||
1. **Business Reality:** DMS มี Operations ที่ซับซ้อน (Workflow, Numbering) ที่ไม่ fit กับ pure REST
|
||||
2. **Developer Experience:** Actions ชัดเจนกว่าการยัด business logic ลงใน PATCH
|
||||
3. **Maintainability:** แยก concerns ระหว่าง data access และ business operations
|
||||
4. **Scalability:** สามารถเพิ่ม business operations ได้โดยไม่ทำให้ REST resources ซับซ้อน
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Impact Analysis
|
||||
|
||||
### Affected Components (ส่วนประกอบที่ได้รับผลกระทบ)
|
||||
|
||||
| Component | Level | Impact Description | Required Action |
|
||||
|-----------|-------|-------------------|-----------------|
|
||||
| **API Controllers** | 🔴 High | ต้องใช้ Hybrid Pattern สำหรับทุก Module | Refactor controllers |
|
||||
| **DTOs** | 🔴 High | ต้องสร้าง DTOs สำหรับทุก Endpoint | Create comprehensive DTOs |
|
||||
| **Documentation** | 🟡 Medium | Swagger ต้อง cover ทั้ง REST และ Actions | Update Swagger config |
|
||||
| **Frontend API Client** | 🟡 Medium | ต้องรองรับทั้งสอง pattern | Update API service calls |
|
||||
| **Testing** | 🟡 Medium | ต้อง test ทั้ง resource และ action endpoints | Add integration tests |
|
||||
|
||||
### Required Changes (การเปลี่ยนแปลงที่ต้องดำเนินการ)
|
||||
|
||||
#### 🔴 Critical Changes (ต้องทำทันที)
|
||||
- [x] **Define API Standards** - สร้างมาตรฐานการตั้งชื่อและ patterns
|
||||
- [ ] **Refactor Correspondence API** - ใช้ hybrid pattern
|
||||
- [ ] **Update RFA API** - ใช้ action endpoints สำหรับ workflow
|
||||
- [ ] **Create Base Controller** - shared patterns และ utilities
|
||||
|
||||
#### 🟡 Important Changes (ควรทำภายใน 1 สัปดาห์)
|
||||
- [ ] **Update API Documentation** - Swagger พร้อม examples
|
||||
- [ ] **Create API Client Library** - frontend TypeScript client
|
||||
- [ ] **Add Integration Tests** - test ทุก endpoint patterns
|
||||
- [ ] **Performance Testing** - ตรวจสอบ response times
|
||||
|
||||
#### 🟢 Nice-to-Have (ทำถ้ามีเวลา)
|
||||
- [ ] **API Versioning Strategy** - prepare for v2
|
||||
- [ ] **OpenAPI Generator** - auto-generate clients
|
||||
- [ ] **API Analytics** - track usage patterns
|
||||
|
||||
---
|
||||
|
||||
## Implementation Details
|
||||
|
||||
### API Design Patterns
|
||||
|
||||
#### 1. Resource Endpoints (REST)
|
||||
|
||||
```typescript
|
||||
// Standard CRUD operations
|
||||
GET /api/v1/correspondences // List with pagination
|
||||
GET /api/v1/correspondences/:id // Get by UUID
|
||||
POST /api/v1/correspondences // Create
|
||||
PUT /api/v1/correspondences/:id // Full update
|
||||
PATCH /api/v1/correspondences/:id // Partial update
|
||||
DELETE /api/v1/correspondences/:id // Soft delete
|
||||
```
|
||||
|
||||
#### 2. Action Endpoints (Business Operations)
|
||||
|
||||
```typescript
|
||||
// Workflow actions
|
||||
POST /api/v1/correspondences/:id/submit
|
||||
POST /api/v1/correspondences/:id/approve
|
||||
POST /api/v1/correspondences/:id/reject
|
||||
POST /api/v1/correspondences/:id/forward
|
||||
|
||||
// Document numbering
|
||||
POST /api/v1/document-numbering/reserve
|
||||
POST /api/v1/document-numbering/generate
|
||||
|
||||
// Bulk operations
|
||||
POST /api/v1/correspondences/bulk-update
|
||||
POST /api/v1/correspondences/bulk-approve
|
||||
|
||||
// Reports and exports
|
||||
GET /api/v1/reports/correspondence-summary
|
||||
GET /api/v1/exports/correspondences/:format
|
||||
```
|
||||
|
||||
### Response Format Standards
|
||||
|
||||
#### Success Response (Single Resource)
|
||||
|
||||
```typescript
|
||||
{
|
||||
"data": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000", // UUID (ADR-019)
|
||||
"documentNumber": "LCBP3-CORR-2024-0001",
|
||||
"subject": "Meeting minutes",
|
||||
"status": "SUBMITTED",
|
||||
"createdAt": "2024-01-01T00:00:00Z",
|
||||
"updatedAt": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"version": "1.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Success Response (Collection)
|
||||
|
||||
```typescript
|
||||
{
|
||||
"data": [
|
||||
{ "id": "...", "documentNumber": "...", ... },
|
||||
{ "id": "...", "documentNumber": "...", ... }
|
||||
],
|
||||
"meta": {
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"total": 100,
|
||||
"totalPages": 5
|
||||
},
|
||||
"filters": {
|
||||
"status": "SUBMITTED",
|
||||
"dateFrom": "2024-01-01"
|
||||
},
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Action Response
|
||||
|
||||
```typescript
|
||||
{
|
||||
"data": {
|
||||
"action": "approve",
|
||||
"result": "SUCCESS",
|
||||
"nextStatus": "APPROVED",
|
||||
"workflow": {
|
||||
"id": "wf-123",
|
||||
"currentState": "APPROVED",
|
||||
"previousState": "PENDING_APPROVAL"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"processedBy": "user-456"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Error Response Format
|
||||
|
||||
```typescript
|
||||
{
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "Validation failed on input data",
|
||||
"statusCode": 400,
|
||||
"timestamp": "2024-01-01T00:00:00Z",
|
||||
"path": "/api/v1/correspondences",
|
||||
"details": [
|
||||
{
|
||||
"field": "subject",
|
||||
"message": "Subject is required and must be at least 10 characters",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
#### URL Paths
|
||||
|
||||
- **Resources:** Plural nouns, kebab-case
|
||||
- `/correspondences`, `/projects`, `/organizations`
|
||||
- **Actions:** Verb-noun pattern, kebab-case
|
||||
- `/correspondences/:id/submit`, `/document-numbering/generate`
|
||||
- **Nested Resources:** Parent-child relationship
|
||||
- `/projects/:id/contracts`, `/contracts/:id/correspondences`
|
||||
|
||||
#### JSON Properties
|
||||
|
||||
- **Properties:** camelCase
|
||||
- `documentNumber`, `createdAt`, `primaryOrganizationId`
|
||||
- **Enums:** UPPER_SNAKE_CASE
|
||||
- `"SUBMITTED"`, `"IN_REVIEW"`, `"APPROVED"`
|
||||
- **Booleans:** is/has prefix
|
||||
- `isActive`, `hasAttachments`, `canEdit`
|
||||
|
||||
### DTO Examples
|
||||
|
||||
#### Create DTO
|
||||
|
||||
```typescript
|
||||
import { IsString, IsOptional, IsEnum, IsUUID } from 'class-validator';
|
||||
|
||||
export class CreateCorrespondenceDto {
|
||||
@IsString()
|
||||
@MinLength(10)
|
||||
subject: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
content?: string;
|
||||
|
||||
@IsEnum(['LETTER', 'RFI', 'MEMO', 'NOTICE'])
|
||||
type: CorrespondenceType;
|
||||
|
||||
@IsUUID()
|
||||
@IsOptional()
|
||||
originatorId?: string;
|
||||
|
||||
@IsUUID()
|
||||
projectId: string;
|
||||
|
||||
@IsArray()
|
||||
@IsUUID(4, { each: true })
|
||||
recipientIds: string[];
|
||||
}
|
||||
```
|
||||
|
||||
#### Action DTO
|
||||
|
||||
```typescript
|
||||
export class ApproveCorrespondenceDto {
|
||||
@IsString()
|
||||
@MaxLength(1000)
|
||||
comment?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsArray()
|
||||
@ValidateNested({ each: true })
|
||||
@Type(() => AttachmentDto)
|
||||
attachments?: AttachmentDto[];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
1. ✅ **Business Clarity:** Actions สะท้อน business operations ชัดเจน
|
||||
2. ✅ **Type Safety:** DTOs ป้องกัน runtime errors
|
||||
3. ✅ **Consistency:** Standard patterns ทั่วทั้ง API
|
||||
4. ✅ **Documentation:** Auto-generated Swagger ครบถ้วน
|
||||
5. ✅ **Maintainability:** แยก concerns ระหว่าง data และ business logic
|
||||
6. ✅ **Testing:** ง่ายต่อการ test ทุก endpoint
|
||||
|
||||
### Negative
|
||||
|
||||
1. ❌ **Learning Curve:** ต้องเรียนรู้ hybrid patterns
|
||||
2. ❌ **Documentation Complexity:** ต้องอธิบายทั้ง REST และ Actions
|
||||
3. ❌ **API Surface Area:** มี endpoints มากขึ้น
|
||||
|
||||
### Mitigation Strategies
|
||||
|
||||
- **Learning Curve:** Create comprehensive API guidelines and examples
|
||||
- **Documentation:** Use Swagger groups and descriptions
|
||||
- **API Surface:** Group related endpoints และใช้ consistent patterns
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Review Cycle & Maintenance
|
||||
|
||||
### Review Schedule
|
||||
- **Next Review:** 2026-10-04 (6 months from creation)
|
||||
- **Review Type:** Scheduled (API Strategy Review)
|
||||
- **Reviewers:** System Architect, Backend Team Lead, Frontend Team Lead
|
||||
|
||||
### Review Checklist
|
||||
- [ ] ยังคงตอบโจทย์ Business Requirements หรือไม่?
|
||||
- [ ] มี API patterns ใหม่ที่ควรพิจารณาหรือไม่?
|
||||
- [ ] มีปัญหา Performance หรือ Usability หรือไม่?
|
||||
- [ ] ต้องการ Update หรือ Deprecate patterns ใดหรือไม่?
|
||||
|
||||
### Version History
|
||||
| Version | Date | Changes | Status |
|
||||
|---------|------|---------|--------|
|
||||
| 1.0 | 2026-04-04 | Initial version - Hybrid REST + Action Strategy | ✅ Accepted |
|
||||
|
||||
---
|
||||
|
||||
## Compliance
|
||||
|
||||
เป็นไปตาม:
|
||||
|
||||
- [API Design & Error Handling](../02-Architecture/02-04-api-design.md)
|
||||
- [Backend Guidelines](../05-Engineering-Guidelines/05-02-backend-guidelines.md)
|
||||
- [ADR-019: Hybrid Identifier Strategy](./ADR-019-hybrid-identifier-strategy.md)
|
||||
|
||||
---
|
||||
|
||||
## Related ADRs
|
||||
|
||||
- [ADR-005: Technology Stack](./ADR-005-technology-stack.md) - NestJS framework choice
|
||||
- [ADR-010: Logging & Monitoring](./ADR-010-logging-monitoring-strategy.md) - API request logging
|
||||
- [ADR-016: Security Authentication](./ADR-016-security-authentication.md) - API security
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [NestJS Documentation](https://docs.nestjs.com/)
|
||||
- [OpenAPI Specification](https://swagger.io/specification/)
|
||||
- [REST API Design Best Practices](https://restfulapi.net/)
|
||||
Reference in New Issue
Block a user