forked from baron/baron-sso
122 lines
5.7 KiB
Markdown
122 lines
5.7 KiB
Markdown
# Baron SSO API Design Policy
|
|
|
|
## 1. 개요 (Overview)
|
|
본 문서는 Baron SSO 시스템의 백엔드 API 설계 원칙과 규약을 정의합니다. 모든 API 개발은 이 문서를 따름으로써 시스템의 일관성, 가독성, 유지보수성을 확보해야 합니다.
|
|
|
|
## 2. API 버전 관리 및 URL 구조 (Versioning & URI)
|
|
|
|
### 2.1 URL 구조
|
|
모든 API는 아래의 기본 구조를 따릅니다.
|
|
|
|
`[GET|POST|...] /api/{version}/{namespace}/{resource}[/{id}][/{action}]`
|
|
|
|
* **Version**: `v1`, `v2` 등 메이저 버전 단위로 관리합니다.
|
|
* **Namespace**: API의 사용 목적과 권한 범위를 구분합니다.
|
|
* `/auth`: 인증, 로그인, 비밀번호 찾기 등 (Public/User context)
|
|
* `/user`: 사용자 마이페이지, 프로필 수정 (Self-service, User context)
|
|
* `/admin`: 시스템 관리자 기능 (Admin context, Tenant aware)
|
|
* `/dev`: 개발자 포털 기능 (Developer context, RP management)
|
|
* **Resource**: 리소스명은 **복수형(Plural)** 명사를 사용합니다. (예: `clients`, `audit-logs`)
|
|
|
|
### 2.2 명명 규칙 (Naming Conventions)
|
|
* **URL Path**: **kebab-case** (소문자, 하이픈 사용)
|
|
* `GET /api/v1/audit-logs` (O)
|
|
* `GET /api/v1/auditLogs` (X)
|
|
* **Query Parameters**: **snake_case** 또는 **camelCase**를 허용하되, **camelCase**를 권장합니다.
|
|
* `GET /clients?clientId=...`
|
|
* **JSON Fields**: **camelCase**를 엄격히 준수합니다. (프론트엔드 JS/TS/Dart 표준 준수)
|
|
* `{ "clientId": "...", "createdAt": "..." }` (O)
|
|
* `{ "client_id": "...", "created_at": "..." }` (X)
|
|
* *예외:* DB 모델을 직접 반환해야 하는 불가피한 레거시(ClickHouse 로그 등)는 예외를 두되, 가급적 DTO 변환을 권장합니다.
|
|
|
|
## 3. HTTP 메서드 (HTTP Methods)
|
|
|
|
리소스에 대한 행위는 HTTP 메서드로 표현합니다.
|
|
|
|
| 메서드 | 용도 | 멱등성(Idempotent) | 예시 |
|
|
| :--- | :--- | :--- | :--- |
|
|
| **GET** | 리소스 조회 | O | `GET /clients` (목록), `GET /clients/:id` (상세) |
|
|
| **POST** | 리소스 생성, 또는 복잡한 액션 | X | `POST /clients` (생성), `POST /auth/login` (액션) |
|
|
| **PUT** | 리소스 전체 수정 (대체) | O | `PUT /users/:id` |
|
|
| **PATCH** | 리소스 일부 수정 | O (권장) | `PATCH /clients/:id/status` |
|
|
| **DELETE**| 리소스 삭제 | O | `DELETE /clients/:id` |
|
|
|
|
## 4. 요청 및 응답 형식 (Request & Response)
|
|
|
|
### 4.1 목록 조회 (List Response)
|
|
목록 조회 시 반드시 페이지네이션 메타데이터를 포함해야 합니다.
|
|
|
|
```json
|
|
{
|
|
"items": [
|
|
{ "id": "1", "name": "Resource A" },
|
|
{ "id": "2", "name": "Resource B" }
|
|
],
|
|
"limit": 50,
|
|
"offset": 0,
|
|
"total": 120 // 선택적 (성능 이슈 시 제외 가능)
|
|
}
|
|
```
|
|
|
|
### 4.2 단건 조회/생성/수정 (Single Resource Response)
|
|
데이터를 바로 반환하거나, 필요 시 래핑할 수 있습니다. 일관성을 위해 루트 객체로 반환하는 것을 권장합니다.
|
|
|
|
```json
|
|
{
|
|
"id": "1",
|
|
"name": "Resource A",
|
|
"status": "active"
|
|
}
|
|
```
|
|
|
|
### 4.3 에러 응답 (Error Response)
|
|
모든 에러는 일관된 포맷을 유지해야 합니다. 프로덕션 환경에서는 내부 스택 트레이스를 노출하지 않아야 합니다.
|
|
|
|
**HTTP Status Code 활용:**
|
|
* `400 Bad Request`: 입력값 검증 실패
|
|
* `401 Unauthorized`: 인증 토큰 없음/만료
|
|
* `403 Forbidden`: 권한 부족 (토큰은 있으나 접근 불가)
|
|
* `404 Not Found`: 리소스 없음
|
|
* `409 Conflict`: 데이터 충돌 (중복 생성 등)
|
|
* `429 Too Many Requests`: 레이트 리밋 초과
|
|
* `500 Internal Server Error`: 서버 내부 오류 (상세 내용 마스킹)
|
|
* `503 Service Unavailable`: 외부 의존성(Hydra, DB 등) 연결 실패
|
|
|
|
**JSON Body:**
|
|
```json
|
|
{
|
|
"error": "사람이 읽을 수 있는 에러 메시지",
|
|
"code": "MACHINE_READABLE_CODE", // 1차 표준 필드 (예: invalid_session, rate_limited)
|
|
"details": { ... } // 선택적 (Validation error 필드별 상세 등)
|
|
}
|
|
```
|
|
|
|
- `code`는 프론트 분기 기준이므로 신규/변경 API에서는 포함을 기본값으로 합니다.
|
|
|
|
## 5. 헤더 및 보안 (Headers & Security)
|
|
|
|
### 5.1 인증 (Authentication)
|
|
* **Authorization**: `Bearer {token}` 형식을 사용합니다.
|
|
* Backend는 Gateway 또는 Middleware에서 토큰을 검증하고 `User Context`를 생성해야 합니다.
|
|
|
|
### 5.2 테넌트 격리 (Multi-tenancy)
|
|
* **X-Tenant-ID**: 관리자 API(`admin`) 호출 시, 대상 테넌트를 식별하기 위해 필수적으로 사용합니다.
|
|
* 슈퍼 어드민이 아닐 경우, 요청자의 권한과 헤더의 테넌트가 일치하는지 검증해야 합니다.
|
|
|
|
### 5.3 요청 추적 (Tracing)
|
|
* **X-Request-ID**: 모든 요청/응답에 고유 ID를 포함하여 로그 추적성을 확보합니다. 클라이언트가 보내지 않으면 서버가 생성합니다.
|
|
|
|
## 6. 개발 가이드라인 (Implementation Guidelines)
|
|
|
|
### 6.1 DTO 사용
|
|
* DB 모델(Gorm, ClickHouse struct)을 그대로 API 응답으로 내보내지 마십시오.
|
|
* 반드시 **Response DTO** 구조체를 별도로 정의하여 `json` 태그를 통해 명명 규칙(camelCase)을 적용하고, 민감한 정보(비밀번호 해시, 내부 ID 등)를 필터링해야 합니다.
|
|
|
|
### 6.2 핸들러 구조
|
|
* 핸들러는 `Service` 레이어를 호출하고, HTTP 요청/응답 처리(파싱, 상태 코드 매핑)에만 집중해야 합니다.
|
|
* 비즈니스 로직은 `Handler`가 아닌 `Service` 또는 `Domain` 레이어에 위치해야 합니다.
|
|
|
|
### 6.3 로깅 정책
|
|
* 요청/응답 로그는 미들웨어 레벨에서 처리합니다.
|
|
* 에러 발생 시 `slog.Error`를 통해 스택 트레이스와 컨텍스트를 남기고, 클라이언트에게는 정제된 메시지만 전달합니다.
|