URI에서 가장 중요한 것은 리소스 식별입니다. 회원 등록, 조회, 수정 API에서의 리소스는 바로 회원입니다.
리소스를 식별했다면, 그 외의 행위와 분리해야합니다. (이때 리소스는 명사, 행위는 동사입니다.) 분리된 행위는 메서드라고 합니다.
✔ GET = 조회
✔ POST = 요청 데이터 처리 (주로 등록에 사용합니다.)
✔ PUT = 리소스를 대체. (해당 리소스가 없으면 생성합니다.)
✔ PATCH = 리소스 부분 변경
✔ DELETE = 리소스 삭제
✔ HEAD = 상태줄과 헤더 변환
✔ OPTIONS = 대상 리소스에 대한 통신 가능 옵션을 설명
✔ CONNECT = 클라이언트가 Proxy(대리 통신 서버)를 통해서 서버와 SSL 통신을 하고자할때 사용됩니다.
✔ TRACE = 타겟 리소스에 대한 경로를 따라 메시지 루프백 테스트를 수행합니다.
OPTIONS 부가 설명
타겟 리소스나 서버와 통신하기 위한 '통신 옵션'을 확인할 때 사용됩니다. 즉, 해당 타겟 서버나 리소스가 어떤 method, header, content type을 지원하는지 알아낼 수 있습니다. (참조) 우리가 특정 HTTP 메소드로 요청을 보내게 된다면 해당 서버로 OPTIONS를 미리 보내고 해당 응답을 확인한 후 우리가 보낸 HTTP 메소드가 지원되면 실제 요청이 이루어지게 되는 것입니다. 이 정보는 CORS에서도 사용될 수 있다. CORS는 먼저 OPTIONS 요청을 보낸 뒤, 해당 정보를 토애도 통신의 가능 여부를 파악하게 됩니다.
그렇다면 CORS란?
참조
CORS란 현재 IP가 아닌 다른 IP로 리소스를 요청하는 구조입니다. 이를 설명하기 위해선 SOP, Acess-Control-Allow-Origin에 대한 설명이 필요합니다. SOP(Same Origin Policy)는 동일한 출처의 Origin만 리소스를 공유할 수 있다는 보안 정책입니다. SOP 표준에 따라야지 XSS, CSRF와 같은 보안상의 이슈를 막을 수 있게 됩니다. 참조하지만 외부 리소스 참조는 필요하므로 외부 리소스를 사용하기 위한 SOP의 예외 조항이 필요시 되는데 이때 그 조항이 바로 CORS입니다. Simple requests인 경우에는 1. 서버로 요청을하고 2. 서버의 응답이 왔을 때 브라우저가 요청한 Origin과 응답한 헤더 Access-Control-Request-Headers의 값을 비교하여 유효한 요청이라면 리소스를 응답합니다. Preflight 요청일 경우에는 1. Origin 헤더에 현재 요청하는 origin과 Access-Control_request-Method 헤더에 요청하는 HTTP 메소드와 사용할 헤더를 OPTIONS 메소드로 서버로 요청합니다.(헤더만 전송) 2. 브라우저가 서버에서 응답한 헤더를 보고 유효한 요청인지 확인하고 유효하다면 원래 보내려던 요청을 다시 보내여 리소스를 응답 받습니다.참조
: 리소스 조회시 사용합니다. 서버에 전달하고 싶은 데이터는 query를 통해서 전달합니다. 메세지 바디를 이용해서 데이터를 전달할 수도 있지만, 지원하지 않는 곳이 많습니다.
: 요청 데이터를 처리합니다. 메세지 바디를 통해 서버로 요청 데이터를 전달하하고 서버는 요청 데이터를 처리합니다. 주로 전달되는 데이터로 신규 리소스 등록, 프로레스 처리에 사용합니다. 주로 새로운 리소스를 생성할 때 사용합니다. 좀 더 구체적으로는 부모의 하위 리소스들을 생성하는데 사용합니다. GET vs POST 비교 참조 블로그 해당 요청의 응답 데이터로 Location도 받을 수 있습니다. 즉, 생성된 URI 정보도 응답받을 수 있는 것입니다. POST는 주로 단순히 데이터를 생성하거나 변경하는 것을 넘어서 프로세스를 처리해야하는 경우 사용합니다. (ex. 결제 완료 -> 배달 시작 -> 배달 완료) 또한 다른 메서드로 처리하기 애매한 경우에도 주로 사용합니다.
: POST는 다음과 같은 기능에서 사용됩니다.
: 이러한 정보를 통해 알아낼 수 있는 것은 리소스 URI에 POST 요청이 오면 데이터를 어떻게 처리할지 리소스마다 따로 정해야한다는 것입니다.
: 리소스를 대체하고 없다면 생성합니다. 이를 위해선 클라이언트가 리소스의 위치를 알고 URI를 지정해주어야합니다. 이것이 바로 POST와의 차이점입니다.
: 리소스를 부분 변경합니다.
: 리소스를 제거합니다.
세가지의 속성이 존재합니다.
1. 안전 2. 멱등 3. 캐시가능
: 호출해도 리소스를 변경하지 않는다는 것입니다. '안전'이라는 속성은 해당 리소스만 고려합니다.
: 한 번 호출하든 두 번 호출하든 몇 번을 호출하든 결과가 똑같다는 것입니다.
: GET, PUT, DELETE가 멱등에 속합니다.
: POST의 경우 멱등이 아닌데, 두 번 호출하게 되면 결제가 중복해서 발생할 수도 있기 때문입니다.
: 멱등이라는 속성은 서버가 어떠한 이유로 인해 정상 응답을 주지 못했을 때,클라이언트가 다시 같은 요청을 해도 되는가?에 대한 판단 근거가 되어줍니다. (외부 요인으로 중간에 리소스가 변경되는 것까지는 고려 대상이 아닙니다.)
: 응답 결과 리소스를 캐시해서 사용해도 되는가에 대한 여부입니다.
: 실제로는 GET, HEAD 정도만 캐시로 사용합니다.
: POST, PATCH도 캐시 가능하지만 본문 내용까지 캐시 키로 고려해야하는데 이 부분 구현이 쉽지않아 주로 사용하지 않습니다.
방법은 두 가지가 있습니다.
1. 쿼리 파라미터를 통한 데이터 전송 (GET)
2. 메세지 바디를 통한 데이터 전송 (POST, PUT, PATCH)
데이터를 전송하는 상황은 총 네가지입니다.
1. 정적 데이터 조회
2. 동적 데이터 조회
3. HTML Form 데이터 전송
4. HTTP API 데이터 전송
: 조회이므로 GET을 사용합니다. 정적 데이터는 쿼리 파라미터 없이 리소스 경로로 단순하게 조회가 가능합니다.
: ex) GET /static/star.jpg
: 쿼리 파라미터를 사용합니다.
: 서버는 쿼리 파라미터를 기반으로 정렬 필터를 적용하여 결과를 동적으로 생성합니다.
: ex) https://www.google.com/search?q=hello&hl=ko
: 따라서 조회 결과를 정렬하는 정렬 조건에 주로 사용합니다.
: HTML Form sumit시 POST 전송합니다.
: Content-Type : application/x-www.form-urlencoded
를 사용하면 url encoding 방식과 같은 형태로 데이터를 전송할 수 있습니다. form의 내용을 메세지 바디를 통해서 전송할 수 있습니다.(key=value 형식) 전송 데이터를 url 인코딩 처리합니다.
: HTMP Form은 GET 전송도 가능합니다.(조회의 목적)
: Content-Type : multipart/form-data
를 사용하면 파일 업로드 같은 바이너리 데이터 전송시 사용 가능합니다. 여러 종류의 파일과 폼의 내용을 함께 전송할 수 있게 됩니다.
: 서버에서 서버로 통신할 때
: 앱 클라이언트가 있을 때
: 웹 클라이언트가 있을 때(HTML에서 Form 이용이 아닌 자바 스크립트를 통한 통신을 할때 -AJAX) 주로 사용합니다.
: 최근에는 json을 많이 사용하므로 Content-Type : application/json
를 씁니다.
아래는 모두 강의에서 사용된 예시들입니다.
POST/members
wHTTP/1.1 201 Created
Location: /members/100
: 이때 서버가 관리하는 리소스 디렉토리를 컬렉션이라고 합니다. 서버가 리소스의 URI를 생성하고 관리하는 것으로 상단 예제에서의 컬렉션은 /members
입니다. 컬렉션을 주로 복수로 사용합니다.
put/files/{filename}
처럼 요청해야하기 때문입니다.: 이때 클라이언트가 관리하는 리소스 저장소를 스토어라고 합니다. 클라이언트가 리소스 URI를 알고 관리하며 상단 예제에서의 스토어는 /files
입니다.
: 위에서 설명했듯 HTML FORM은 GET, POST만 지원합니다. 따라서 FORM도 하나의 리소스로 보면서 요청을 설계해야합니다.
: 즉, 동사로 된 리소스 경로를 사용해야하는 것 입니다.
: POST/members/new
POST/members/{id}/edit
과 같은 요청에서 /new
/edit
이 바로 컨트롤 URI입니다.