127 lines
9.1 KiB
Markdown
127 lines
9.1 KiB
Markdown
---
|
|
title: JSON:API v1.1 — Error Objects
|
|
source_type: official-doc
|
|
url: https://jsonapi.org/format/#errors
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
tags: [ca-error-envelope, json-api, spec, rest-api, error-format, official-doc]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
related_branches: [feature-operational-error-observability-foundation, feature-boundary-validation-mapping-contract, feature-business-rule-validation-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# JSON:API v1.1 — Error Objects
|
|
|
|
> Layer: `raw/official-docs/` — JSON:API v1.1 specification, "Error Objects" section verbatim.
|
|
> ca-tmpl Topic 4 (Error Envelope) 의 **대안 3 (JSON:API errors)** 비교 근거. `source.pointer` (JSON Pointer) 로 필드 단위 오류를 가리키는 패턴의 1차 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-operational-error-observability-foundation]] | ca-tmpl Topic 4 (Error Envelope) 대안 비교 — JSON:API `errors[]` array + `source.pointer` 패턴의 표준 근거 |
|
|
| [[raw/branch-notes/feature-boundary-validation-mapping-contract]] | 경계(boundary) 입력 검증 실패 시 field-level 오류 표현 옵션으로 `source.pointer` (JSON Pointer) 비교 근거 |
|
|
| [[raw/branch-notes/feature-business-rule-validation-contract]] | business rule 실패의 `code`/`title`/`detail` 분리 패턴 비교 — JSON:API 의 `title` (불변) vs `detail` (가변) 모델 근거 |
|
|
|
|
## 컨텍스트 / 왜 저장했는지
|
|
|
|
RFC 7807 (ProblemDetail) 과 함께 자주 비교되는 또 다른 표준. `source.pointer` (JSON Pointer) 로 필드 단위 오류를 가리키는 방식이 GitHub 의 `errors[].field` 와 ca-tmpl 의 `details` 에 시사점 있음. ca-tmpl 이 custom envelope 을 채택했을 때 JSON:API 의 `errors[]` array + `source.pointer` 모델을 왜/얼마나 포기/대체했는지를 평가하기 위한 1차 근거.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://jsonapi.org/format/#errors
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: JSON:API working group
|
|
- 발행일: JSON:API v1.1 (current stable)
|
|
- 마지막 확인일: 2026-05-27
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Error Objects — Top-level placement] "Error objects MUST be returned as an array keyed by `errors` in the top level of a JSON:API document."
|
|
|
|
> [§Error Objects — Members list] "An error object MAY have the following members, and MUST contain at least one of: `id`, `links`, `status`, `code`, `title`, `detail`, `source`, `meta`"
|
|
|
|
> [§Error Objects — source.pointer] "`pointer`: a JSON Pointer to the value in the request document that caused the error [e.g. `\"/data\"` for a primary data object]"
|
|
|
|
> [§Error Objects — source composition] "It SHOULD include one of the following members or be omitted: `pointer`, `parameter`, `header`"
|
|
|
|
> [§Error Objects — title] "`title`: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem"
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| JSONAPI-ERR-C1 | JSON:API 응답에서 error objects 는 top-level `errors` 키 아래 **array** 로 반환되어야 함 (단일 오류여도 array) | [§Error Objects — Top-level placement] "Error objects MUST be returned as an array keyed by `errors` in the top level of a JSON:API document." | `official-standard` | JSON:API v1.1 준수 응답 | top-level 에 `data` 와 `errors` 가 공존 가능하다는 뜻이 아님 (spec 별도 §) |
|
|
| JSONAPI-ERR-C2 | error object 는 다음 멤버 중 **최소 1개** 를 가져야 함: `id`, `links`, `status`, `code`, `title`, `detail`, `source`, `meta` | [§Error Objects — Members list] "An error object MAY have the following members, and MUST contain at least one of: `id`, `links`, `status`, `code`, `title`, `detail`, `source`, `meta`" | `official-standard` | error object 의 멤버 구성 | 모든 응답에서 이 8개 필드가 모두 채워져야 한다는 뜻은 아님 (MAY) |
|
|
| JSONAPI-ERR-C3 | `source.pointer` 는 **JSON Pointer (RFC 6901)** 로 request document 안에서 오류 발생 위치를 가리킴 (예: `"/data"`, `"/data/attributes/title"`) | [§Error Objects — source.pointer] "`pointer`: a JSON Pointer to the value in the request document that caused the error [e.g. `\"/data\"` for a primary data object]" | `official-standard` | request body field-level 오류 표현 | query string parameter 오류 표현이 아님 — query 는 `source.parameter`, header 는 `source.header` |
|
|
| JSONAPI-ERR-C4 | `source` 객체는 `pointer`, `parameter`, `header` 중 **하나** 를 포함하거나 생략 (SHOULD) | [§Error Objects — source composition] "It SHOULD include one of the following members or be omitted: `pointer`, `parameter`, `header`" | `official-standard` | source 객체 멤버 선택 | 셋이 동시에 와도 안 되는지 (MUST NOT) 는 본 인용 범위 밖 — SHOULD only |
|
|
| JSONAPI-ERR-C5 | `title` 은 **같은 종류의 문제에 대해 호출마다 변하지 않는** 짧은 사람 대상 요약 (SHOULD NOT change from occurrence to occurrence) | [§Error Objects — title] "`title`: a short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem" | `official-standard` | `title` vs `detail` 분리 정책 | `detail` 의 호출별 가변성 자체를 본 인용이 직접 정의하지 않음 — title 의 불변성만 명시 |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `JSONAPI-ERR-C1`: top-level `errors[]` array 구조 (단일/다중 오류 모두 array)
|
|
- `JSONAPI-ERR-C2`: error object 의 허용 멤버 8개와 최소 1개 요구사항
|
|
- `JSONAPI-ERR-C3`: `source.pointer` 가 JSON Pointer 표기법을 사용한다는 사실
|
|
- `JSONAPI-ERR-C4`: source 가 pointer/parameter/header 중 하나를 가진다는 정책
|
|
- `JSONAPI-ERR-C5`: `title` 의 occurrence-invariance SHOULD
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- `category` / `retryable` 같은 운영 친화적 1급 필드의 표준 존재 (JSON:API spec 에 없음 → ca-tmpl 의 `meta` 에 해당)
|
|
- HTTP status code 와 error object `status` (문자열) 의 정확한 동기화 규칙 — `status` 가 문자열이라는 점은 spec 다른 부분
|
|
- 성공 응답 envelope 모양 (별도 §, top-level `data` 정의)
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- ca-tmpl 의 단일 `error` 객체 vs JSON:API 의 `errors[]` array 전환 시 client 마이그레이션 비용 (별도 평가)
|
|
- 부분 채택 (errors 만 JSON:API, success 는 custom) 의 일관성 손실 정도 (실측 필요)
|
|
- `links.about` 의 error catalog URL 운영 (RFC 7807 의 `type` URI 와 동일 역할인지 별도 ` ca-error-envelope` 비교)
|
|
|
|
## 메모 / Notes (내 프로젝트 해석)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
|
|
|
- 응답 shape 예시 (해석/구성):
|
|
```json
|
|
{
|
|
"errors": [
|
|
{
|
|
"id": "8c4f7b...",
|
|
"status": "422",
|
|
"code": "INVALID_TITLE",
|
|
"title": "Invalid Attribute",
|
|
"detail": "Title must be at least 3 characters.",
|
|
"source": { "pointer": "/data/attributes/title" },
|
|
"links": { "about": "https://example.com/docs/errors/INVALID_TITLE" },
|
|
"meta": { "retryable": false }
|
|
}
|
|
]
|
|
}
|
|
```
|
|
- **장점 (해석)**:
|
|
- `source.pointer` 로 form 필드 매핑이 가장 표준적
|
|
- `title` (불변) vs `detail` (가변) 분리 — 카탈로그링 친화적
|
|
- 다중 오류 표현이 자연스러움 (`errors[]`)
|
|
- **단점 (해석)**:
|
|
- 전체 JSON:API spec (리소스 객체 구조, sparse fieldsets 등) 채택 부담 → 부분 채택 시 일관성 깨짐
|
|
- `category`, `retryable` 이 1급 아님 — `meta` 로 빠짐
|
|
- 성공 응답은 별도 `data` 레이아웃 강제 → ca-tmpl 의 envelope 과 직접 충돌
|
|
- **ca-tmpl custom envelope 와의 차이 (해석)**:
|
|
- JSON:API: `errors[]` array, ca-tmpl: 단일 `error` 객체. 다중 오류 표현이 ca-tmpl 은 `details` 에 의존
|
|
- `category`/`retryable` 을 JSON:API 는 1급 X → ca-tmpl 이 더 운영 친화적
|
|
- **표준 준수 / lock-in / client 호환성 (해석)**:
|
|
- 표준 준수 ↑, 부분 채택 시 표준성 손실. JS 진영의 client lib (ember-data 등) 풍부
|
|
- **localization / i18n 지원 여부 (해석)**:
|
|
- spec 자체에 i18n 없음. `meta` 로 처리
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc / company-tech-blog:
|
|
- [[raw/official-docs/spring-problem-detail]] (대안 1 구현체 — RFC 7807/9457)
|
|
- [[raw/official-docs/google-api-error-format]] (대안 2 — gRPC `google.rpc.Status`)
|
|
- [[raw/official-docs/graphql-errors-spec]] (대안 4 — GraphQL errors)
|
|
- [[raw/company-tech-blogs/stripe-error-format]] (대안 5 — Stripe custom envelope)
|
|
- canonical contract 섹션:
|
|
- [[raw/project-notes/ca-skeleton-operational-contract]] §3 Structured API Response Contract, §6 Operational Error Category
|
|
- 본 source 의 위치: ca-tmpl Topic 4 — Error Envelope, **대안 3: JSON:API errors**
|
|
- 인용하는 wiki: (미작성)
|