사전 201 Created
에러코드

201 Created

gabury1고친 사람 github-actions[bot]

201 Created 는 서버가 요청을 받아 새 리소스를 만들었다고 알리는 값입니다. 리소스는 주문 한 건이나 게시글 한 편처럼 서버가 주소를 붙여 가리키는 대상입니다. 요청을 보낸 쪽은 응답 첫 줄의 이 값을 보고 무언가가 새로 생겼다는 것을 압니다. 새로 생긴 것의 주소는 대개 응답 헤더로 함께 받습니다.

쉽고 빠른 이해

201 Created 는 「부탁한 것을 새로 만들었고 주소는 여기 있다」는 답입니다. 쇼핑몰 서버가 주문을 받아 42번 주문을 만들면 이 값과 함께 /orders/42 라는 주소를 돌려줍니다.

이 값이 없으면 요청한 쪽은 무엇이 생겼는지 본문을 읽어 짐작해야 합니다. 주문 번호는 서버가 정하므로 미리 알 수도 없습니다. 201 과 주소 한 줄이 있으면 본문을 열지 않고 다음 요청을 보냅니다.

어떻게 도는가:

  1. 만들어 달라는 요청을 보냅니다
  2. 서버가 주문을 새로 만들고 주소를 붙입니다
  3. 서버가 201 과 그 주소를 돌려줍니다

대가가 있습니다. 201 은 다 만들었다는 뜻이라 서버는 만들기를 끝낸 뒤에야 답합니다. 오래 걸리는 일이면 그동안 요청한 쪽이 기다립니다. 그럴 때는 「받아 두었다」는 뜻의 202 를 씁니다.

상세

201 Created 는 HTTP(HyperText Transfer Protocol, 하이퍼텍스트 전송 프로토콜)의 상태 코드 가운데 하나입니다. HTTP 는 클라이언트가 서버에 요청을 보내고 응답을 받는 규약입니다. 클라이언트는 브라우저나 다른 서버처럼 요청을 보내는 쪽입니다.

상태 코드는 응답이 어떻게 끝났는지를 세 자릿수로 알리는 값입니다. 서버는 응답의 첫 줄에 이 값을 적어 보냅니다.

201 은 요청이 성공했고 그 결과로 새 리소스가 생겼다는 뜻입니다. 리소스는 게시글 한 편이나 주문 한 건처럼 서버가 주소를 붙여 가리키는 대상입니다. 회원 가입, 주문 넣기, 파일 올리기처럼 무언가를 새로 만드는 요청이 성공하면 이 값을 돌려줍니다.

맨 앞 숫자 2 는 성공이라는 표시입니다. 2 로 시작하는 코드를 묶어 2xx 계열이라고 부릅니다. 같은 2xx 계열의 200 OK는 요청을 처리했다는 뜻입니다. 201 은 그보다 좁게, 처리한 결과로 새것이 생겼다는 것까지 알립니다.

응답 한 벌로 보는 201

주문 하나를 새로 넣으면 요청과 응답이 이렇게 오갑니다. 클라이언트는 POST 메서드로 주문 목록의 주소에 새 주문의 내용을 보냅니다. POST 는 서버에 처리를 맡기는 요청 방식입니다.

http
POST /orders HTTP/1.1
Host: shop.example.com

{"item": "커피", "count": 2}

서버는 주문을 만들고 42번이라는 번호를 붙였습니다. 그리고 아래 응답을 돌려줍니다.

http
HTTP/1.1 201 Created
Location: /orders/42

{"id": 42, "item": "커피", "count": 2}

첫 줄을 상태 줄이라고 부릅니다. 프로토콜 버전 HTTP/1.1, 상태 코드 201, 설명 문구 Created 가 차례로 놓입니다.

숫자 뒤의 설명 문구를 사유 구절이라고 부릅니다. 사람이 읽으라고 붙인 글자라서 프로그램은 이 글자를 안 보고 숫자만 봅니다.

둘째 줄의 Location 이 201 과 짝을 이룹니다. 새로 생긴 주문의 주소를 알리는 줄입니다.

빈 줄 아래는 응답 본문입니다. 201 의 본문에는 대개 새 리소스의 내용이나 그 리소스로 가는 링크를 담습니다. 위 응답은 만들어진 주문의 내용을 담았습니다. 본문을 비워 보내도 됩니다.

Location 헤더가 알리는 새 주소

헤더는 상태 줄 아래에 「이름: 값」 꼴로 붙는 부가 정보입니다. Location 헤더는 그 가운데 새 리소스가 어디 있는지를 알리는 헤더입니다.

이 헤더가 필요한 까닭은 새 주소를 서버가 정하기 때문입니다. 주문 번호 42 는 서버가 주문을 만드는 순간에 붙였습니다. 클라이언트는 요청을 보낼 때 이 번호를 알 수 없습니다.

클라이언트는 받은 주소로 GET 요청을 보내 새 주문을 다시 읽습니다. GET 은 리소스를 가져오는 요청 방식입니다. 아래 그림은 주문을 만들고 다시 읽기까지의 순서입니다.

sequenceDiagram
    participant 클라이언트
    participant 서버
    클라이언트->>서버: POST /orders
    Note over 서버: 주문 42 를 만든다
    서버-->>클라이언트: 201 Created, Location /orders/42
    클라이언트->>서버: GET /orders/42
    서버-->>클라이언트: 200 OK, 주문 42 의 내용

서버가 처음 돌려주는 응답이 201 입니다. 클라이언트는 본문을 해석하지 않고 헤더에서 주소만 꺼내 다음 요청을 만듭니다.

Location 값은 위처럼 서버 이름을 뺀 경로만 적어도 됩니다. 그러면 클라이언트는 요청을 보낸 주소를 기준으로 전체 주소를 채웁니다. https://shop.example.com/orders 로 보낸 요청이면 새 주소는 https://shop.example.com/orders/42 입니다.

Location 이 없는 201 도 있습니다. 그때는 요청을 보낸 주소 자체가 새 리소스의 주소입니다. 아래에서 볼 PUT 으로 만든 경우가 그렇습니다.

200 대신 201 을 돌려주는 까닭

201 과 200 은 둘 다 성공입니다. 그래도 둘을 가르는 까닭은 응답을 받은 클라이언트가 할 일이 달라지기 때문입니다.

201 을 받은 클라이언트는 새것이 생겼다는 것을 본문 없이 압니다. 새 주소는 Location 에서 꺼내 다음 요청에 씁니다.

200 만 받았다면 본문을 열어 무엇이 생겼는지 찾아야 합니다. 그런데 본문의 모양은 API(Application Programming Interface, 프로그램끼리 기능을 불러 쓰는 약속)마다 다릅니다. 새 주소를 찾는 코드도 API 마다 새로 짜야 합니다. 201 과 Location 은 이 수고를 약속된 값 둘로 덜어 줍니다.

201 과 이웃한 코드

201 을 쓸지 말지는 두 기준으로 갈립니다. 새 리소스가 생겼나, 그리고 그 일이 응답 전에 끝났나입니다.

상황 코드 뜻
새 리소스를 다 만들었다 201 Created 만들었고 주소는 Location 에 있다
만들기를 받아 두기만 했다 202 Accepted 처리는 아직이다. 결과는 나중에 따로 확인한다
새로 만든 것 없이 처리만 했다 200 OK 결과를 본문에 담았다
새로 만든 것도 돌려줄 본문도 없다 204 No Content 처리했고 본문은 비었다
같은 것이 이미 있어 만들지 않았다 409 Conflict 요청이 서버의 지금 상태와 부딪혔다

표의 첫 두 줄은 시점으로 갈립니다. 201 은 만들기가 끝났다는 약속입니다. 그래서 서버는 리소스를 다 만든 뒤에야 201 을 보낼 수 있습니다.

동영상 변환처럼 오래 걸리는 작업이면 그동안 클라이언트가 응답을 기다립니다. 이럴 때는 202 로 먼저 답합니다. 작업은 그 뒤에 따로 돌립니다. 클라이언트는 202 를 보고 결과를 나중에 따로 확인해야 한다는 것을 압니다.

마지막 줄의 409 는 맨 앞 숫자가 4 입니다. 4 로 시작하는 4xx 계열은 요청 쪽에 문제가 있다는 뜻입니다. 가입하려는 아이디가 이미 있을 때처럼 새로 만든 것이 없으면 201 을 쓰지 않습니다. 이때 흔히 409 를 돌려줍니다.

POST 와 PUT 에서의 201

새 리소스를 만드는 요청 방식은 대개 둘입니다. 앞에서 본 POST 와 PUT 입니다. 둘은 새 주소를 누가 정하느냐로 갈립니다.

PUT 은 「이 주소에 이 내용을 놓아라」는 요청 방식입니다. 클라이언트가 PUT /users/kim 처럼 주소를 직접 정해 보냅니다. 그래서 PUT 이 만든 리소스의 주소는 클라이언트가 이미 압니다. 이 때문에 PUT 이 돌려주는 201 에는 Location 이 없어도 됩니다.

메서드 새 주소를 정하는 쪽 201 을 돌려줄 때 201 이 아닐 때
POST 서버 새 리소스를 만들었다. Location 에 새 주소를 싣는다 새로 만든 것이 없으면 200 이나 204
PUT 클라이언트 그 주소에 없던 리소스를 새로 만들었다 있던 리소스를 바꿨으면 200 이나 204

표의 PUT 줄이 201 의 쓸모를 보여 줍니다. PUT 요청은 모양이 같아도 결과가 둘로 갈립니다. 클라이언트는 201 인지 200·204 인지를 보고 방금 새로 만든 것인지 있던 것을 바꾼 것인지 압니다.

응답이 사라진 201

POST 로 만들기를 요청했는데 201 응답이 도중에 사라질 수 있습니다. 서버는 주문을 만들었지만 클라이언트는 성공했는지 모릅니다. 클라이언트가 같은 요청을 다시 보내면 서버는 주문을 하나 더 만들고 또 201 을 돌려줍니다.

이 일은 POST 가 멱등하지 않아서 생깁니다. 멱등하다는 것은 같은 요청을 여러 번 보내도 한 번 보낸 것과 결과가 같다는 뜻입니다.

PUT 은 멱등합니다. 같은 주소에 같은 내용을 두 번 놓아도 리소스는 하나입니다. 첫 요청에는 201 이 옵니다. 다시 보낸 요청은 있던 것을 바꾼 셈이므로 200 이나 204 를 받습니다.

POST 의 중복을 막는 흔한 방법은 요청마다 고유한 값을 붙이는 것입니다. 이 값을 멱등성 키라고 부릅니다. 서버는 같은 키로 다시 온 요청을 새로 처리하지 않고 처음 만든 결과를 돌려줍니다.

관련 항목

201 이 속하는 상위 분류

상태 코드 · 상태 코드 등급 · 성공 응답 · HTTP · HTTP 응답

201 과 함께 응답을 이루는 구성 요소

상태 줄 · 사유 구절 · 헤더 · Location 헤더 · 응답 본문 · Content-Type · ETag

201 대신 고르는 다른 상태 코드

200 OK · 202 Accepted · 204 No Content · 303 See Other · 409 Conflict

201 을 돌려받는 요청 메서드

요청 메서드 · POST · PUT · PATCH · GET

201 이 알리는 새 리소스의 주소 체계

자원 · URI · 상대 URI · 요청 대상 · 자원 지향 설계

201 응답이 사라졌을 때 쓰는 중복 방지 장치

멱등성 · 멱등성 키 · 재시도 · 중복 요청 · 타임아웃

201 을 두고 내리는 설계 판단

API 설계 · REST · 비동기 작업 · 오류 응답 본문 · 하이퍼미디어

다른 이름: 201 · HTTP 201 · 201 (Created) · 상태 코드 201