반응형
HTTP URI 설계
- URI (Uniform Resource Identifier) : 리소스 식별자
- 회원을 등록하고 수정하고 조회하는게 리소스가 아니다.
- 미네랄을 캐라 -> 캐라가 아닌 미네랄이 리소스이다.
- 리소스 식별, URI 계층 구조 활용
- 회원 목록 조회 /members
- 회원 조회 /members/{id}
- 회원 등록 /members/{id}
- 회원 수정 /members/{id}
- 회원 삭제 /members/{id}
- URI는 리소스만 식별
- 리소스는 해당 리소스를 대상으로하는 행위를 분리
- 리소스 : 회원
- 행위 : 조회, 등록, 삭제, 변경
- 행위 (메서드는) HTTP 메서드로 구분한다
HTTP 메서드
주요 메서드
- GET : 리소스 조회
- POST : 요청 데이터 처리, 주로 등록
- PUT : 리소스를 대체, 해당 리소스가 없으면 생성
- 기존에 파일이 있으면 덮고, 없으면 생성
- PATCH : 리소스 부분 변경
- 회원의 이름 바꾸기와 같이 특정 필드 변경
- DELETE : 리소스 삭제
- 최근 스펙에서는 리소스가 아닌 Representation으로 되어있다.
기타 메서드
- HEAD : GET과 동일하지만 메시지 부분을 제외하고 상태 줄과 헤더만 반환
- OPTIONS : 대상 리소스에 대한 통신 가능 옵션(메서드)울 설명 (주로 CORS에서 사용)
- CONNECT : 대상 자원으로 식별되는 서버에 대한 터널을 설정
- TRACE : 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행
GET
- 리소스 조회
- 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)을 통해 전달
- GET /search?q=hello&hl=ko HTTP 1.1
- 메시지 바디를 사용해서 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않는다.
POST
- 메시지 바디를 통해 서버로 요청 데이터 전달
- { "username" : "yy", "age" : 20}
- 서버는 요청 데이터를 처리
- 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
- 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용
- 스펙 : 대상 리소스가 리소스의 고유 한 의미 체계에 따라 요청에 포함 된 표현을 처리하도록 요청
- HTML 양식에 입력된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공 (FORM에 입력한 정보로 가입, 주문 등)
- 게시판, 뉴스 그룹, 메일링 리스트, 블로그 등 유사 그룹에 메시지 게시 (게시판 글쓰기, 댓글 달기 등)
- 서버가 아직 식별하지 않은 새 리소스 생성 (회원 가입 등)
- 기존 자원에 데이터 추가 (한 문서에 내용 추가)
- 리소스 URI에 POST 요청이 오면 요청을 어떻게 처리할지 리소스마다 따로 정해야한다. (정해진 것이 없이 여러 기능을 한다)
- 정리
- 새 리소스 생성 (등록)
- 서버가 아직 식별하지 않은 새 리소스 생성
- 요청 데이터 처리
- 단순히 데이터를 생성하거나, 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우
- 예 ) 주문에서 결제 -> 배달 -> 완료 처럼 단순히 값 변경을 넘어 프로세스 상태가 변경되는 경우
- POST의 결과로 새로운 리소스가 생성되지 않을 수 있다
- 예 ) POST /orders/{orderId}/start-delivery (컨트롤 URI)
- 다른 메서드로 처리하기 어려운 경우
- 예 ) JSON으로 조회 데이터를 넘겨야하는데 GET 메서드를 사용하기 어려운 경우
- 애매하면 POST를 사용하자
- 새 리소스 생성 (등록)
PUT
- 리소스를 대체
- 있으면 대체 (필드가 2개인 리소스에 필드 1개로 요청하면 없는 필드는 삭제된다)
- 즉, PUT은 갈아치우는 용도로 사용
- 없으면 생성
- 파일이 있으면 덮고 없으면 생성하는 것과 같다
- 있으면 대체 (필드가 2개인 리소스에 필드 1개로 요청하면 없는 필드는 삭제된다)
- 클라이언트가 리소스를 식별 (POST와 차이)
- 클라이언트가 리소스 위치를 알고 URI 지정
- PUT /members/100 와 같이 100번임을 클라이언트가 알고 있다.
- POST의 경우는 /members 까지만 지정
- 클라이언트가 리소스 위치를 알고 URI 지정
PATCH
- 리소스 부분 변경
- PUT 과 달리 필드2개인 곳에 필드1개만 수정하면 사라지지 않고 그 필드만 변경된다
- 예 ) username : young, age: 50 에서 age:20만 보내면 username : young, age : 20 으로 부분변경
- PATCH가 HTTP에서 지원을 못하는 경우가 있는데 그럴 때는 POST를 사용하자 (POST는 무적)
DELETE
- 리소스 제거
HTTP 메서드 속성
- GET 은 요청에 Body를 넣을 수 있긴 하지만 권장하지 않는다.
안전 (Safe Methods)
- 여러번 호출했을 때 변경이 일어나지 않는 것을 안전하다고 한다. (GET, HEAD 등)
- 장애가 발생했을 경우는 고려하지않고 해당 리소스만 고려한다.
멱등 (Idempotent Methods)
- f(f(x)) = f(x)
- 한번 호출하든 여러번 하든 결과가 똑같다
- 멱등 메서드
- GET : 조회 결과가 항상 같다
- PUT : 결과를 대체한다. 같은 요청을 여러번해도 최종 결과는 같다. (똑같은 요청)
- DELETE : 결과를 삭제한다. 여러번 같은 요청을 해도 결과는 똑같다.
- POST : 멱등이 아니다. 두 번 호출하면 같은 결제가 중복 발생이 가능할 수 있다.
- 활용
- 자동 복구 메커니즘
- 서버가 정상 응답을 못주었을 때, 같은 요청을 해도 되는 가를 판단하는 근거로 사용
- 재요청 중간에 다른 곳에서 리소스를 변경하는 경우엔 데이터가 바뀔 수 있지만 이 부분은 고려하지 않는다.
- 예 ) GET 재요청 중 중간에 PUT을 사용하는 경우
캐시가능 (Cacheable)
- 응답 결과 리소스를 캐시에서 사용해도 되는가?
- GET, HEAD, POST, PATCH 캐시 가능
- 실제로는 GET, HEAD 정도만 캐시로 사용
- POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데, 구현이 쉽지가 않다
HTTP 메서드 활용
클라이언트 -> 서버 데이터 전송
- 쿼리 파라미터를 통한 데이터 전송
- GET
- 주로 정렬 필터 (검색어)
- 메시지 바디를 통한 데이터 전송
- POST, PUT, PATCH
- 회원 가입, 상품 주문, 리소스 등록, 리소스 변경 등
- 정적 데이터 조회
- 이미지, 정적 텍스트 문서
- 동적 데이터 조회
- 주로 검색, 게시판 목록에서 필터
- Form 데이터 전송 (POST) - 메시지 바디에 정보를 넣음
- urlencoded : 한글 같은것들은 %가 들어가서 인코딩이 된다.
- abc김 -> abc%EA%B9%80
- Form 데이터 전송(GET)
- Form 데이터 전송 (Multipart/form-data) - ----xxx 는 웹브라우저에서 자동으로 잘라서 해결해준다
- Content-Type의 디폴트 값은 application/x-www-form-urlencoded
- form의 내용을 메시지 바디를 통해서 전송 (key=value, 쿼리 파라미터 형식)
- 전송 데이터를 url encoding 처리 (한글 %)
- Content-Type : multipart/form-data
- 파일 업로드 같은 바이너리 데이터 전송 시 사용
- 다른 종류의 여러 파일과 폼의 내용 함께 전송 가능 (그래서 이름이 multipart)
- HTML Form 전송은 GET, POST만 지원
HTTP API 데이터 전송
- 서버 TO 서버
- 백엔드 시스템 통신
- 앱 클라이언트
- 아이폰, 안드로이드
- 웹 클라이언트
- HTML에서 FORM 전송 대신 자바 스크립트를 통한 통신에 사용 (AJAX)
- 예 ) React, VueJs 와 같은 웹 클라이언트와 API 통신
- POST, PUT, PATCH : 메시지 바디를 통해 데이터 전송
- GET : 조회, 쿼리 파라미터로 데이터 전달
- Content-Type : application/json을 주로 사용 (사실상 표준)
- TEXT, XML, JSON 등
HTTP API 설계 예시
- HTTP API - 컬렉션
- POST 기반 등록
- 예 ) 회원관리 API 제공
- HTTP API - 스토어
- PUT 기반 등록
- 예 ) 정적 컨텐츠 관리, 원격 파일 관리
- HTML FORM 사용
- 웹 페이지 회원 관리
- GET, POST만 지원
회원 관리 시스템
- API 설계 - POST 기반 등록(컬렉션) , PUT 기반 등록 (스토어)
- 회원 목록 /members -> GET
- 회원 등록 /members -> POST
- 회원 조회 /members/{id} -> GET
- 회원 수정 /members/{id} -> PATCH, PUT, POST
- PUT : 아예 덮어버림 (이런 상황은 드뭄, 파일등록 같은 상황) - 클라이언트가 리소스 URI를 알고 있어야한다.
- PUT /files/star.jpg : 클라이언트가 직접 리소스 URL를 관리
- 스토어 : 클라이언트가 관리하는 것을 의미, 여기서 스토어는 files
- PATCH : 부분 수정 가능 (개념적으론 제일 좋긴하다.)
- POST : 이것도 저것도 애매할 때 사용 - 클라이언트가 리소스 URI를 모르고 서버가 관리한다
- POST /members : 클라이언트는 리소스 URI를 모름 (컬렉션)
- PUT : 아예 덮어버림 (이런 상황은 드뭄, 파일등록 같은 상황) - 클라이언트가 리소스 URI를 알고 있어야한다.
- 회원 삭제 /members/{id} -> DELETE
- 대부분 POST를 사용 (컬렉션 기반), 파일 같은 예외적인 경우만 PUT (스토어)를 사용
- HTML FORM은 GET, POST만 지원하기 때문에 이런 제약은 컨트롤 URI를 사용하여 해결
- /new, /delete 등 동사로 된 리소스 경로를 사용
- HTTP 메서드로 해결하기 애매한 경우 사용 (HTTP API 포함)
URI 설계 개념 (참고)
- 문서(document)
- 단일 개념(파일 하나, 객체 인스턴스, 데이터베이스 row)
- 예) /members/100, /files/star.jpg
- 컬렉션(collection) - POST (주로 사용)
- 서버가 관리하는 리소스 디렉터리
- 서버가 리소스의 URI를 생성하고 관리
- 예) /members
- 스토어(store) - PUT (파일)
- 클라이언트가 관리하는 자원 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- 예) /files
- 컨트롤러(controller), 컨트롤 URI
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
- 동사를 직접 사용
- 예) /members/{id}/delete
본 포스팅은 인프런 김영한님 강의(모든 개발자를 위한 HTTP 웹 기본 지식)를 토대로 정리한 내용입니다.
반응형