HTTP API를 만들어 보자
- (예제) 회원 정보 관리 API를 만든다고 생각해 보자
- 설계에서 가장 중요한 것: 리소스 식별
- 리소스란?: 회원 자체가 리소스
- 회원을 등록/수정/조회는 리소스가 아니다.
- DB의 엔티티 같은 걸까? 요구사항 명세서의 명사? (O)
- 리소스를 어떻게 식별하는 게 좋을까?
- 회원을 등록하고 수정하고 조회하는 것을 모두 배제: 회원만 리소스로 남음
- 회원만 리소스로 두고 동작에 대한 요청을 URI로 표현할 때 생기는 문제:

- 리소스와 행위를 분리: URI는 리소스만 식별
- 리소스: 회원
- 행위: 조회, 등록, 삭제, 변경, ...
- 리소스는 보통 명사, 행위는 보통 동사
- 행위(동사)는 HTTP 메서드로 구분
- 조회/등록/삭제/변경해! 라는 요청은 메서드가 구분하게 된다.
- 어떤 리소스에 대해서 어떤 메서드 요청을 보낼 건지만 결정하면 됨.
HTTP 메서드 - GET, POST
- 가장 많이 사용하는 GET/POST
- HTTP 메소드: 클라이언트가 서버에 요청을 보낼 때 기대하는 행동
GET 리소스 조회
- 서버에 전달하고 싶은 데이터는 query를 통해서 전달
- 메세지 바디를 사용해서 데이터를 전달할 수도 있지만 지원하지 않는 곳이 많아서 권장되지 않음
POST 요청 데이터 처리, 주로 등록에 사용
- 메세지 바디를 통해 서버로 요청 데이터 전달
- 클라이언트에서 서버로 요청을 보낼 때 '데이터를 줄 테니까 이 데이터를 받아서 처리해줘'라고 요청하는 것임
- 메세지 바디로 들어온 데이터를 처리하는 모든 기능을 수행함
- 주로 신규 등록 같은 것에 많이 사용함
- POST 메서드로 요청을 보냈을 때 서버가 데이터를 어떻게 처리할지 클라이언트와 서버가 미리 뭔가 약속해둠
- 신규로 자원을 생성하면 응답 패킷의 status line에 201 Created라고 많이 쓴다 (200 OK 해도 ㄱㅊ)
- 신규 생성했을 경우 보통 생성된 데이터의 위치(Path)를 Location field에 담아서 같이 보낸다.
- 리소스 URI에 POST 요청이 오면 데이터를 어떻게 처리할지 리소스마다 미리 정해둬야 함
POST의 사용처:
(1) 새 리소스 생성
(2) 요청 데이터 처리 (프로세스 처리, 서버에서 큰 변화가 일어나는): control URI, 행위를 URI에 포함시키는 경우
(3) 다른 메서드로 처리하기 애매한 경우 (JSON으로 데이터를 넘겨야 하는데, (메세지 바디 등... 때문에) GET을 쓰기 어려운 경우)
POST는 사실 모든 것을 할 수 있다.
- 다만 조회할 때는 GET을 쓰는 게 유리 (캐싱 등의 측면에서)
- GET을 쓸 수 없거나, 서버에서 프로세스가 진행돼야 하거나, 다른 것을 쓰기 애매하거나... 불가피할 때에 쓴다.
기타 메서드:
- HEAD: GET과 동일하지만 메세지를 제외하고 status line과 header만 반환
- OPTIONS: 대상 리소스에 대한 통신 가능 옵션을 설명 (이런게 있다 정도만 알고 계세요)
- CONNECT: 대상 자원으로 식별되는 서버에 대한 터널을 설정 (거의 안씀)
- TRACE: 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행 (거의 안씀)
HTTP 메서드 - PUT, PATCH, DELETE
PUT 리소스 대체, 해당 리소스가 없으면 사용
- 파일을 폴더에 넣을 때 기존 파일이 있으면 덮어쓰고 없으면 새로 생기는 느낌
- 리소스가 있으면 완전히 대체 & 리소스가 없으면 생성 (덮어쓰기)
- 중요!
PUT의 중요한 성질
(1) 기존 리소스를 완전히 대체한다.
- 기존의 리소스를 완전히 삭제하고 요청 보낸 리소스로 대체한다.
- 일부 필드만 수정하고 싶을 때에는, 기존 필드 & 기존 필드 값을 그대로 보내고, 수정할 필드만 수정해서 보내야 한다.
- 수정할 필드만 띡 보내면 다 사라지고 그 필드만 남음.
- 리소스를 수정하는 게 아니라 갈아치우기 위한 것
(2) 클라이언트가 리소스를 식별한다.
- 클라이언트가 요청을 보낼 때부터 구체적인 리소스의 경로를 알고 있음
- POST와의 차이점
PATCH 리소스 부분 변경
- 리소스를 부분적으로 변경 (회원의 이름 변경과 같이 특정 필드 변경할 때에 사용)
- PUT이 있다가 PATCH가 새로 나옴. 리소스의 일부 필드만을 변경할 수 있음.
- 바디에 일부 필드만 적어 보내도 다른 필드가 사라지지 않는다.
- 요청을 보낸 필드만 수정이 일어난다.
- PATCH를 지원하지 않는 서버도 있다 (!) 그럴 때는 POST를 쓰면 됨.
DELETE 리소스 삭제
- 구체적인 리소스의 경로를 적어 보내면 리소스가 삭제된다.
HTTP 메서드의 속성
안전 (Safe Methods)
- 호출해도 리소스를 변경하지 않는다.
- GET, HEAD: 불러오기만 하니까 안전함
- POST, PUT, DELETE...: 변경이 일어나니까 안전하지 않음
- 여러 번 호출해서, 로그가 쌓여 서버가 터져도 안전함? -> 안전함이라는 것은 리소스의 변화에만 집중한다. 상관 X
멱등 (Idempotent)
- 한 번 호출하든 두 번 호출하든 100번 호출하든 결과가 똑같다. (똑같아야 한다.)
- 멱함수의 멱이겠구만
- GET(불러온 결과), PUT(덮어쓴 결과), DELETE (삭제 후 아무것도 없는 상태): 멱등
- POST: 멱등하지 않음 > 결제, 배송, ... 을 두 번 호출하면 결과가 달라진다.
멱등의 활용:
- 자동 복구 매커니즘
- 서버가 TIMEOUT 등으로 정상 응답하지 못했을 때, 클라이언트가 같은 요청을 다시 해도 되는가를 판단
- (참고) 멱등은 외부 요인으로 중간에 리소스가 변경되는 것까지는 고려하지 않는다. 같은 클라이언트가 같은 요청을 했을 때 같은 결과가 나오는지만 판단함
캐시 가능
- 응답 결과를 캐시해서 사용해도 되는가?: 웹 브라우저가 내부에 정보를 저장하고 있는 것 (로드할 때 시간을 줄이기 위해서)
- GET, HEAD, POST, PATCH 캐시 가능
- 실제로는 GET, HEAD 정도만 사용 (HEAD는 잘 안 쓰니까 사실상 거의 GET만 사용하는 것임)
- POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데 구현이 쉽지 않음
- 캐시를 사용하려면 캐시 키를 맞춰야 한다.