feat: 공식 문서 근거자료, 브랜치 기능 문서 작성

This commit is contained in:
DongHyeonka
2026-07-29 18:05:17 +09:00
parent cfd84875bf
commit 58515ab0f3
251 changed files with 31470 additions and 109 deletions
@@ -0,0 +1,90 @@
---
title: GraphQL over HTTP (draft) — 상태 코드와 errors 처리
source_type: official-doc
url: https://graphql.github.io/graphql-over-http/draft/
archive_url:
related_branches: [feature-frontend-multi-protocol-api-transport-contract]
related_projects: [ca-skeleton-frontend]
tags: [frontend, graphql, http, api, protocol]
created: 2026-07-28
---
# GraphQL over HTTP (draft) — 상태 코드와 errors 처리
> Layer: `raw/` — 외부 자료의 **원문 발췌·출처 기록**.
> ⚠️ **draft 문서다.** 확정 표준이 아니며 내용이 바뀔 수 있다. 아래 claim 을 `official-reference` 로 쓰되 "draft" 라는 사실을 함께 인용해야 한다.
## 활용 branch (필수, 최소 1개+)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| `[[raw/branch-notes/feature-frontend-multi-protocol-api-transport-contract]]` | GraphQL 성공 판정을 상태 코드가 아니라 본문으로 하는 근거(`D4`), `errors` 가 있는 응답을 실패로 정규화하는 것이 **규격과 다른 우리 정책**임을 밝히는 근거(`D3`) |
## 출처
- 원본 URL: https://graphql.github.io/graphql-over-http/draft/
- 보조 URL: https://spec.graphql.org/draft/#sec-Handling-Field-Errors
- 아카이브 URL:
- 저자 / 조직: GraphQL Foundation (GraphQL over HTTP working draft)
- 발행일: (draft, 지속 갱신)
- 마지막 확인일: 2026-07-28
## 왜 저장했는지
branch 가 "`200 OK` + `errors[]` 를 실패로 정규화한다" 고 적어 두었는데 두 가지를 확인해야 했다. (a) 그 응답이 정말 `200` 으로 오는가, (b) 규격이 그 상황을 어떻게 부르는가. 결과는 둘 다 예상과 달랐다. 데이터와 errors 가 함께 있으면 규격은 `294` 를 권고하고, 규격 자신은 그 상황을 **"successful execution"** 이라고 부른다. 즉 우리 결정은 규격을 따르는 것이 아니라 **의도적으로 다르게 가는 것**이며, 그 사실을 문서에 밝히지 않으면 다음 사람이 규격 준수로 오해한다.
## 핵심 인용
> [§6.4] "If the GraphQL response contains the data entry and it is not null, then the server MUST reply with a `2xx` status code."
> [§6.4] "If the GraphQL response contains the data entry and does not contain the errors entry, then the server SHOULD reply with a `200` status code."
> [§6.4] "If the GraphQL response contains both the data entry (even if it is null) and the errors entry, then the server SHOULD reply with a `294` status code."
> [§6.4] "If the GraphQL response does not contain the data entry then the server MUST reply with an appropriate `4xx` or `5xx` status code:"
> [§6.4] "Clients should process a response using the `application/graphql-response+json` media type as a well-formed GraphQL response independent of the HTTP status code."
> [§6.4 Note] "There are no circumstances where the GraphQL specification allows for a response having data as null without errors being present."
> [§6.4.1] "The GraphQL specification differentiates field errors from request errors and refers to the situation wherein a GraphQL field error occurs as a partial response; it still indicates successful execution."
> [§6.1] "If the `Accept` header does not indicate support for one of the server's preferred media types but does indicate support for `application/json` ... any response that produces a `2xx` status code should replace the `Content-Type` header with `Content-Type: application/json`."
## 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| C1 | 데이터와 `errors` 가 함께 있는 응답에 규격이 권고하는 상태 코드는 `200` 이 아니라 **`294`** 다 | [§6.4] "then the server SHOULD reply with a `294` status code." | `official-reference` (draft) | `application/graphql-response+json` | 모든 서버가 `294` 를 보낸다는 것 — SHOULD 이며 draft 다 |
| C2 | data 가 있으면 상태 코드는 반드시 `2xx` 다 | [§6.4] "then the server MUST reply with a `2xx` status code." | `official-reference` (draft) | data 가 non-null 인 응답 | `2xx` 이면 성공이라는 것 |
| C3 | 클라이언트는 응답을 **HTTP 상태 코드와 무관하게** 잘 형성된 GraphQL 응답으로 처리해야 한다 | [§6.4] "independent of the HTTP status code" | `official-reference` (draft) | `application/graphql-response+json` 소비자 | 상태 코드를 아예 무시해도 된다는 것 |
| C4 | 규격은 field error 상황을 **partial response 이며 "successful execution"** 이라고 부른다 | [§6.4.1] "it still indicates successful execution." | `official-reference` (draft) | field error | 애플리케이션이 이를 성공으로 취급해야 한다는 것 — 규격의 명명일 뿐 |
| C5 | data 가 없으면 `4xx` 또는 `5xx` 여야 한다 | [§6.4] "MUST reply with an appropriate `4xx` or `5xx` status code" | `official-reference` (draft) | request error | 어떤 코드인지의 세부 |
| C6 | `data: null` 이면서 `errors` 가 없는 응답은 규격상 존재할 수 없다 | [§6.4 Note] "There are no circumstances where the GraphQL specification allows for a response having data as null without errors being present." | `official-reference` (draft) | 모든 GraphQL 응답 | 서버가 그 규칙을 실제로 지킨다는 것 |
| C7 | 구식 클라이언트가 `application/json` 만 받으면 `2xx` 응답의 Content-Type 이 `application/json` 으로 바뀐다 | [§6.1] "should replace the `Content-Type` header with `Content-Type: application/json`" | `official-reference` (draft) | legacy Accept 협상 | 그 경우에도 상태 코드가 같다는 것 |
## 적용 경계
- 이 자료가 직접 증명하는 것:
- `C1`~`C3`: GraphQL 성공 판정에 상태 코드만 쓰면 안 되며, `200` 만 검사하는 구현은 `294` 를 놓친다
- `C4`: 규격은 부분 응답을 "성공" 으로 분류한다
- `C5`·`C6`: data 유무가 request error 와 field error 를 가르는 축이다
- 이 자료가 증명하지 않는 것:
- `errors` 가 있는 응답을 **애플리케이션이 실패로 취급해야 한다**는 것 — 오히려 `C4` 는 반대 방향이다. 실패 취급은 우리 정책이다
- 서버가 `294` 를 실제로 보낸다는 것 (SHOULD + draft)
- GraphQL 클라이언트 라이브러리들의 기본 동작
- 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
- 우리 backend 가 `application/graphql-response+json` 을 쓰는지, `294` 를 보내는지
- 부분 데이터를 버리는 정책이 제품에서 수용 가능한지
## 메모
- 인용 1 해석 후보 (미검증): `C1`+`C3` 때문에 adapter 의 성공 판정은 **상태 코드가 아니라 본문의 `data`·`errors` 구조**를 봐야 한다. "`200` 인지 확인" 하는 구현은 `294` 응답을 실패로 오분류하거나, `2xx` 만 보고 errors 를 놓친다.
- 인용 2 해석 후보 (미검증): `C4` 는 우리 `PARTIAL_RESULT_FAILURE` 결정이 **규격 이탈**임을 뜻한다. 이탈 자체는 문제가 아니지만, 문서에 "규격은 성공이라 부르지만 우리는 실패로 다룬다" 를 명시하지 않으면 근거를 오해하게 된다.
- 추가로 봐야 할 동일 출처 페이지: §5 (GET/POST 와 persisted document), §6.2 (media type 협상)
## 관련
- 같은 주제 다른 official-doc: `[[raw/official-docs/grpc-connect-status-codes-error-model]]`, `[[raw/official-docs/zod-runtime-schema-validation-official]]`
- 이 자료를 인용한 wiki 요약: 생성 전