HTTP 409와 412의 차이: 조건부 요청으로 수정 충돌 이해하기

·설명 약 6분·작성: BlogFlow automation Controller·블로그 소개

이 글에서 배우는 내용

HTTP 409 Conflict는 리소스의 현재 상태와 요청의 충돌을, HTTP 412 Precondition Failed는 요청에 포함된 조건의 불충족을 나타냅니다. ETag와 If-Match를 이용하면 문서를 읽은 뒤 다른 변경이 있었는지 확인하고, 최신 상태를 검토한 다음 수정을 판단할 수 있습니다.

목차

개념과 필요성

409 Conflict는 요청이 대상 리소스의 현재 상태와 충돌함을 나타내고, 412 Precondition Failed는 요청에 명시된 사전 조건이 충족되지 않았음을 나타냅니다. MDN: 409 Conflict와 MDN: 412 Precondition Failed는 이 구분을 설명합니다.

왜 필요한가

학습을 위한 가상 문서 편집 상황을 생각해 보겠습니다. 편집자 A가 문서를 읽고 내용을 수정하는 동안, 편집자 B가 먼저 다른 내용을 저장합니다. A가 처음 읽은 문서만 기준으로 수정 내용을 저장하면, B의 변경을 덮어쓸 위험이 있습니다. 이 문제를 이해하려면 A가 읽은 시점의 상태와 A의 수정 요청에 붙인 조건을 구분해야 합니다.

조건부 요청은 서버가 문서 상태를 확인한 뒤 변경하도록 요청하는 방법입니다. 아래 예시는 HTTP 응답 코드와 헤더의 관계를 설명하기 위한 가상 사례이며, 특정 서비스의 동작을 확인한 결과가 아닙니다. 실제로 어떤 헤더와 충돌 정책을 지원하는지는 대상 서버의 문서에서 확인해야 합니다.

조건부 수정의 원리

조건부 수정은 문서 조회, 버전 표식 기록, 조건을 담은 수정 요청, 서버의 조건 평가 순서로 이해할 수 있습니다.

내부 동작 원리

응답에 ETag가 있다면 클라이언트는 그 값을 기록하고, 수정 요청의 If-Match 헤더에 같은 값을 전달합니다. 서버는 요청의 태그와 현재 리소스의 태그를 강한 비교로 평가합니다.

MDN에 따르면 If-Match 조건이 일치하지 않으면 서버는 요청된 변경을 수행하지 않고 412 Precondition Failed를 반환합니다. If-Match는 강한 비교를 사용하므로 W/ 접두사가 붙은 약한 태그는 강한 비교에서 일치하지 않습니다. MDN: If-Match header

서로 다른 두 시점의 문서 상태가 나란히 놓여 이전 내용과 새 내용이 달라진 모습을 보여 주는 편집 일러스트

그림은 두 편집자가 관찰한 문서 상태가 달라질 수 있음을 나타냅니다. 이 차이를 요청 조건으로 확인하면, 클라이언트는 자신이 읽었던 버전이 여전히 수정의 기준으로 유효한지 판단할 수 있습니다.

동작 분석

If-Match 조건이 충족되었다고 해서 수정 요청 전체의 성공이 보장되는 것은 아닙니다. 조건의 충족 여부와 리소스 상태에 따른 충돌 여부는 구분해서 판단해야 합니다.

요청 예제로 이해하기

다음은 조회 응답에서 받은 태그를 수정 요청에 전달하는 가상의 HTTP 요청·응답이며, 실제 실행·검증 결과가 아닙니다. 서버가 ETag를 제공하고 If-Match를 평가한다는 전제를 둡니다.

최소 예제

조회와 수정 사이에 다른 편집자가 저장하여 서버의 현재 태그가 "doc-v8"로 바뀐 상황입니다. 아래 수정 요청에는 처음 조회한 태그인 "doc-v7"이 담겨 있습니다.

GET /documents/42 HTTP/1.1
Host: example.invalid

HTTP/1.1 200 OK
ETag: "doc-v7"

PUT /documents/42 HTTP/1.1
Host: example.invalid
If-Match: "doc-v7"
Content-Type: application/json

{"title":"검토한 문서"}

HTTP/1.1 412 Precondition Failed

요청의 "doc-v7"과 서버의 현재 태그인 "doc-v8"이 일치하지 않아 412가 반환됩니다. 이때 서버는 요청된 변경을 수행하지 않습니다.

실전 적용 예제

가상 편집자 A는 문서를 조회해 받은 ETag를 기록하고, 수정 요청의 If-Match에 담습니다. 다른 편집자의 변경으로 서버의 현재 태그가 달라졌다면 A의 조건은 불일치합니다. 서버는 수정 내용을 반영하지 않고 412를 반환하므로, A는 최신 문서를 다시 확인한 뒤 자신의 편집 내용을 적용할지 판단합니다.

문서를 읽을 때 기록한 버전 태그와 수정 요청에 담은 태그를 나란히 대조하는 절차를 보여 주는 편집 일러스트

그림은 읽은 버전의 태그와 수정 요청의 태그를 대조하는 역할을 설명합니다. 412를 받은 뒤에는 수정 내용을 무조건 다시 보내기보다, 최신 문서에서 다른 변경이 자신의 편집과 어떻게 관계되는지 살펴야 합니다.

적용 범위와 혼동 지점

ETag와 If-Match를 함께 사용하는 조건부 수정은 다른 변경을 덮어쓰는 lost update를 예방하는 데 쓰이는 패턴입니다.

응용 패턴·한계와 흔한 실수

이 패턴은 서버의 조건부 요청 지원을 전제로 합니다. 헤더를 요청에 추가하기만 하면 보호가 적용된다고 볼 수는 없습니다.

409를 중복 글이나 잠금 오류만을 위한 응답으로 한정해서는 안 됩니다. 반대로 412를 모든 수정 충돌의 일반 응답으로 설명해서도 안 됩니다. 여기서 다룬 조건부 변경 요청에서 If-Match 조건이 일치하지 않는 경우에는 변경 없이 412가 반환됩니다. 모든 API가 같은 충돌 정책이나 헤더 지원을 갖는다고 일반화하지 말고, 서버별 세부 동작은 문서에서 확인해야 합니다.

비슷한 개념 비교

409와 412를 비교할 때는 응답 코드의 숫자만 보지 말고, 무엇이 충돌하거나 충족되지 않았는지 확인합니다. MDN의 설명을 기준으로 보면 차이는 다음과 같습니다.

  • 409 Conflict: 대상 리소스의 현재 상태와 요청 사이의 충돌을 나타냅니다. 수정 요청과 현재 리소스 사이의 충돌이 예가 될 수 있습니다.
  • 412 Precondition Failed: 요청의 사전 조건이 충족되지 않았음을 나타냅니다. If-Match가 일치하지 않는 변경 요청에서는 변경을 수행하지 않고 412를 반환합니다.
한쪽에는 리소스 상태와 요청의 충돌을, 다른 쪽에는 요청 조건의 불충족을 대비해 보여 주는 간결한 편집 일러스트

그림은 리소스 상태와 요청 조건이라는 두 판단 기준을 대비합니다.

실무 판단 기준

조건부 수정을 검토할 때는 먼저 대상 서버가 조회 응답에 ETag를 제공하는지, 변경 요청의 If-Match를 평가하는지 확인합니다.

도입 전 확인

클라이언트가 전달하는 태그는 실제 조회 응답에서 받은 값을 사용해야 합니다. 또한 If-Match의 강한 비교 특성 때문에 약한 태그는 일치로 처리되지 않는다는 점을 고려해야 합니다.

조건 실패 뒤의 판단

412 Precondition Failed를 받으면 요청한 변경이 반영되지 않았다는 점을 기준으로 최신 문서를 확인합니다. 최신 상태에 다른 변경이 있다면 자신의 수정 내용을 그 상태에 맞게 다시 판단한 뒤 새 조건으로 요청을 구성합니다. 서버별 지원 범위와 응답의 추가 세부사항은 제공된 MDN 설명만으로 정할 수 없으므로, 해당 서버의 문서를 확인해야 합니다.

이 글이 도움이 되었나요?

조회 중

새 글 받아보기

RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.

RSS 피드 구독하기

댓글 남기기