API URI 설계에서 가장 중요한 것은
리소스를 식별하는 것
HTTP 메서드와 특징, 이를 기반으로 한 API 설계 예시를 알아보자.
결론 : URI 설계 시, 리소스 만으로 최대한 설계해보고, 안되면 컨트롤 URI 를 사용해서 해결해보자.
리소스와 행위를 분리하자.
- URI 는 리소스만 식별 한다.
- 리소스와 해당 리소스를 대상으로 하는 행위를 분리해야 한다.
- 예시
- 리소스 : 회원
- 행위 : 조회, 등록, 삭제, 변경
- 행위 구분 방법 : HTTP 메서드
행위(메서드)
- GET: 리소스 조회
- POST: 요청 데이터 처리, 주로 등록에 사용
- PUT: 리소스를 대체, 해당 리소스가 없으면 생성
- PATCH: 리소스 부분 변경
- DELETE: 리소스 삭제
기타 메서드
- HEAD: GET과 동일하지만 메시지 부분을 제외하고, 상태 줄과 헤더만 반환
- OPTIONS: 대상 리소스에 대한 통신 가능 옵션(메서드)을 설명(주로 CORS에서 사용)
- CONNECT: 대상 자원으로 식별되는 서버에 대한 터널을 설정
- TRACE: 대상 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행
HEAD 는 본 적이 있었는데, OPTIONS , CONNECT , TRACE 는 거의 본적이 없었다.
GET Method
- 리소스 조회 시 사용
- 서버에는 query 를 통해서 전달
- body 에 데이터를 넣을 수 있으나, 권장하지 않음
POST Method
- 대상 리소스가 리소스의 고유한 의미 체계에 따라 요청에 포함된 표현을 처리하도록 요청한다.
- 메세지 BODY 를 통해 서버로 요청 데이터 전달
- 서버는 요청 데이터를 처리
- 단순히 데이터를 생성하거나 변경하는 것 외에 프로세스를 처리해야 하는 경우에도 사용됨.
- 프로세스의 상태가 변경되는 경우 (단순한 값 변경이 아님)
- POST 결과로 새로운 리소스가 생성되지 않을 수 있음
- 프로세스를 나타낼 때, 컨트롤 URI 를 활용하기도 한다. 이 경우에는 리소스만으로는 표현을 못할 수 있기 때문에 컨트롤 URI 로 표현된다.
- 신규 리소스 등록, 프로세스 처리 등에 이용된다.
- 어떠한 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 함 -> 정해진 것이 없음
- 다른 메서드로 처리하기 애매한 경우에도 사용함.
PUT Method
PATCH 와는 다르다. 리소스를 대체한다는 것
- 리소스를 대체
• 리소스가 있으면 대체
• 리소스가 없으면 생성
• 쉽게 이야기해서 덮어버림
- 클라이언트가 리소스를 식별
• 클라이언트가 리소스 위치를 알고 URI 지정
• POST와 차이점
PATCH Method
- 리소스 부분 변경 시 사용
- PATCH 지원이 안되면 POST 써도 됨.
DELETE Method
HTTP 메서드의 속성
- 안전(safety) , 멱등(idempotent) , 캐시 가능(cacheable)
안전
- 호출해도 리소스를 변경하지 않는다.
- 계속 호출해서 장애가 발생하는 경우는 고려하지 않는다.
멱등 (idempotent)
- f(f(x)) = f(x)
- 한 번 호출하든 100번 호출하든 결과가 같다.
- GET , PUT , DELETE 는 멱등하다.
- POST : 두 번 호출하면 같은 결제(또는 요청)가 중복해서 발생이 가능하다.
- 활용 예시(자동 복구 메커니즘)
- 서버가 timeout 으로 정상 응답을 못줄 때, 클라이언트가 같은 요청을 다시 해도 되는지에 대한 판단 근거에 활용이 된다.
- 외부 요인으로 중간에 리소스가 변경되는 건 멱등에 고려하지 않는다.
캐시가능 (Cacheable)
- 응답 결과 리소스를 캐시해도 사용해도 되는가?
- 가능한 메서드 : GET , HEAD , POST , PATCH
- 실제로는 GET , HEAD 정도 캐시를 사용한다.
- GET 은 URL 로 key 를 잡으면 되니까 간단함.
- POST , PATCH 는 body 까지도 key 로 고려해야 하는데, 구현하기 쉽지 않다.
클라이언트에서 서버로 데이터 전송 방식
쿼리 파라미터를 통한 데이터 전송
메세지 바디를 통한 데이터 전송
- POST, PUT, PATCH
- 회원가입, 상품 주문, 리소스 등록/변경
클라이언트에서 서버로 데이터를 전송하는 4가지 상황
1. 정적 데이터 조회
- 이미지, 정적 텍스트 문서 조회
- 리소스 경로만으로 가능
- 조회 니까 GET 사용
2. 동적 데이터 조회
- 쿼리 파라미터를 사용하여 동적 데이터를 조회한다.
- 검색, 게시판 목록, 정렬 필터, 정렬 조건 등에서 사용된다.
- 조회 니까 GET 사용
- GET 이랑 POST 만 지원한다.
- HTML Form submit시 POST 전송
이 상황에서는 웹 브라우저가 HTTP 메세지를 자동으로 생성해준다.
- Content-type default 는
x-www-form-urlencoded
- 쿼리 파라미터 처럼 key,value 형태로 만들어서 body 에 만들어준다.
- 전송 데이터를 url encoding 처리해준다.
- FORM 데이터 전송은 GET 메서드도 지원하지만, 사용하지 말자.
- 파일도 전송하고 싶다면 ?
- form 태그 안에 속성값에
enctype="multipart/form-data"
라고 추가를 해주면 됨.
- 여러 컨텐트 타입을 같이 보낼 수 있다.
4. HTTP API 데이터 전송
- 서버 to 서버
• 백엔드 시스템 통신
- 앱 클라이언트
• 아이폰, 안드로이드
- 웹 클라이언트
• HTML에서 Form 전송 대신 자바 스크립트를 통한 통신에 사용(AJAX)
• 예) React, VueJs 같은 웹 클라이언트와 API 통신
- POST, PUT, PATCH: 메시지 바디를 통해 데이터 전송
- GET: 조회, 쿼리 파라미터로 데이터 전달
- Content-Type: application/json을 주로 사용 (사실상 표준)
• TEXT, XML, JSON 등등
API 설계 예시
1. POST 기반 등록 예시
• 회원 목록 /members -> GET
• 회원 등록 /members -> POST
• 회원 조회 /members/{id} -> GET ( 객체 인스턴스 하나를 다루는 경우를 문서 라고 한다.)
• 회원 수정 /members/{id} -> PATCH, PUT, POST
• 회원 삭제 /members/{id} -> DELETE
특징
- 클라이언트는 등록될 리소스의 URI를 모른다.
• 회원 등록 /members -> POST
• POST /members
- 서버가 새로 등록된 리소스 URI를 생성해준다.
• HTTP/1.1 201 Created
Location: /members/100
- 컬렉션(Collection)
• 서버가 관리하는 리소스 디렉토리
• 서버가 리소스의 URI를 생성하고 관리
• 여기서 컬렉션은 /members
2. PUT 기반 등록 예시
딱 ! 파일 등록이라고 생각하면 된다.
• 파일 목록 /files -> GET
• 파일 조회 /files/{filename} -> GET ( 객체인스턴스 또는 파일 하나를 다루는 경우를 문서 라고 한다.)
• 파일 등록 /files/{filename} -> PUT
• 파일 삭제 /files/{filename} -> DELETE
• 파일 대량 등록 /files -> POST
특징
- 클라이언트가 리소스 URI를 알고 있어야 한다.
• 파일 등록 /files/{filename} -> PUT
• PUT /files/star.jpg
- 클라이언트가 직접 리소스의 URI를 지정한다.
- 스토어(Store)
• 클라이언트가 관리하는 리소스 저장소
• 클라이언트가 리소스의 URI를 알고 관리
• 여기서 스토어는 /files
• 회원 목록 /members -> GET
• 회원 등록 폼 /members/new -> GET ( 순수 HTML 페이지 )
• 회원 등록 /members/new, /members -> POST(순수 HTML 페이지에서 저장하기 버튼 클릭 시 요청하는 uri)
• 회원 조회 /members/{id} -> GET
• 회원 수정 폼 /members/{id}/edit -> GET ( 순수 HTML 페이지 )
• 회원 수정 /members/{id}/edit, /members/{id} -> POST (순수 HTML 페이지에서 저장하기 버튼 클릭 시 요청하는 uri)
• 회원 삭제 /members/{id}/delete(컨트롤 URI) -> POST
• 회원 등록 폼 /members/new -> GET
• 회원 등록 /members/new, /members -> POST
URL 은 웬만하면 통일해서 사용하자
POST 가 실패해서, get /members/new url 을 통해 폼으로 다시 돌아가야 할 경우, redirection 이 일어나면서 폼이 초기화 될 수도 있음.
- HTML FORM은 GET, POST만 지원
- 다른 메서드를 사용하기 위해 AJAX 같은 기술을 사용해서 해결
- 컨트롤 URI
• 문서 , 컬렉션, 스토어로 해결하기 어려운 추가 프로세스를 실행한다.
문서, 컬렉션, 스토어가 뭔지 헷갈린다면 다시 스크롤을 올려 찾아보자.
• GET, POST만 지원하므로 제약이 있음
• 이런 제약을 해결하기 위해 동사로 된 리소스 경로 사용
• POST의 /new, /edit, /delete가 컨트롤 URI
• HTTP 메서드로 해결하기 애매한 경우 사용(HTTP API 포함)