HTTP 메서드 활용
- 클라이언트에서 서버로 데이터 전송
- HTTP API 설계 예시
클라이언트에서 서버로 데이터 전송
클라이언트에서 서버로 데이터를 전송하는 방식은 크게 2가지가 있다. 쿼리 파라미터(?)를 이용한 데이터 전송과 메시지 바디를 통하여 전송하는 방식이 있다. 전자인 쿼리 파라미터 방식은 GET메서드를 통하여 URI에 쿼리 파라미터를 붙여 KEY-VALUE 형식으로 데이터를 보내며 주로 정렬 필터(검색어)를 사용할 때 사용한다. 후자인 메시지 바디를 통한 방법은 POST, PUT, PATCH가 해당되며 주로 회원 가입, 상품 주문, 게시글 등록, 수정과 같은 곳에 사용된다. 이렇게 2가지 방법을 통해서 다양한 상황들이 연출되는데 예시를 통해 알아보자.
정적 데이터 조회 - 이미지, 정적 텍스트 문서
정적 데이터 조회는 따로 데이터를 보내주는 작업은 없으며 URI로 GET 메서드를 통해 접근하여 이미지나, 정적 문서를 가져오게 된다.
GET /static/붱철.jpg HTTP/1.1
Host: localhost:8080
위와 같은 경로로 리소스를 요청하게 되면 다음과 같은 이미지가 오게 될 것이다.
HTTP/1.1 200 OK
Content-Type: image/jpeg
Content-Length: 3912
image 데이터....

동적 데이터 조회 - 쿼리 파라미터 사용
GET /search?q=이동욱&oq=이동욱 HTTP/1.1
Host: www.google.com
구글에 이동욱을 검색하면 우리는 검색 목록 데이터를 받아볼 수 있다. 검색할 때 쿼리 파라미터를 사용하여 검색어를 key-value 형태로 보내주게 된다. 주로 검색, 게시판 목록에서 정렬 필터를 사용할 때 사용한다. GET은 쿼리 파라미터를 통해 데이터를 전달한다.(GET도 메시지 바디를 가질 수 있지만 지원하지 않는 서버도 많고 실무에서는 권장하지 않는다)
HTML Form 데이터 전송 - POST 전송 저장
application/x-www-form-urlencoded
다음과 같은 정보를 서버에 저장하고 싶다.
username: 이동욱
age: 20
웹 페이지에서 정보를 form 태그에 넣고 "localhost:8080/save"라는 URI로 전송하게 되면 웹 브라우저는 form 태그를 읽어 알아서 다음과 같이 POST 요청을 만들게 된다.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
username=이동욱&age=20
위의 경우를 다음과 같이 GET 메서드 쿼리 파라미터를 사용할 수도 있다. 하지만 GET 메서드는 조회에만 사용하는 것이 좋고 데이터를 수정하는 일에는 사용하지 않는 것이 좋으므로 다음과 같이 사용하지 않는다.
GET /members?username=이동욱&age=20 HTTP/1.1
Host: localhost:8080
multipart/form-data
만약 이미지를 전송하게 되면 이 또한 웹 브라우저가 알아서 boundary를 포함하여 요청 HTTP 메시지를 작성해준다.
POST /save HTTP/1.1
Host: localhost:8080
Content-Type: multipart/form-data; boundary=----XXX
Content-Length: 102329
------XXX
Content-Disposition: form-data; name="username"
붱철
------XXX
Content-Disposition: form-data; name="age"
23
------XXX
Content-Disposition: form-data; name="file1", filename="붱철이사진.png"
Content-Type: Image/png
1234ad0f9egjkic98geeg9dg0wh...
------XXX--
HTML Form 데이터 전송 정리
회원 가입, 게시글 작성 등의 작업을 처리할 때 HTML Form을 사용하고 submit시 POST 전송을 하게 된다다. 이 때 웹브라우저는 요청을 만들게 되는데 Content-Type을 application/x-www-form-urlencoded로 설정하고 메시지 바디는 UTF8을 url encoding하여 key-value 형식으로 작성하여 POST 요청을 만들게 된다. 또한, HTML Form은 GET 전송도 가능하다.
파일 업로드와 같은 바이너리 데이터를 전송해야 할 경우가 생기게 되면 multipart/form-data 라는 컨텐트 타입으로 작성하여 여러 파일과 폼의 내용을 함께 전송할 수 있다.
이러한 HTML Form 전송은 GET, POST만 지원한다는 특징이 있다.
HTTP API 데이터 전송
안드로이드 앱과 같은 환경에서처럼 클라이언트에서 서버로 직접 데이터를 넘겨야 하는 경우에는 HTTP API 데이터 전송을 해야할 것이다. 이 경우에는 Content-Type을 application/json 타입으로 설정하여 데이터를 보내주면 된다.
POST /members HTTP/1.1
Content-Type: application/json
{
"username": "Donguk",
"gender": "male"
}
HTTP API 데이터 전송 정리
HTTP API 데이터 통신을 하는 경우는 보통 다음과 같다.
- 서버 to 서버
- 백엔드 시스템 통신
- 기계끼리 통신하기 때문
- 앱 클라이언트
- 안드로이드, 아이폰
- 웹 클라이언트
- HTML에서 Form 전송 대신 자바 스크립트를 통한 통신에 사용(AJAX)
- 예) React, VueJs 같은 웹 클라이언트와 API 통신
HTTP API의 경우에도 POST, PUT, PATCH는 메시지 바디를 통해 데이터를 전송하며 GET은 조회, 쿼리 파라미터로 데이터를 전송한다. 컨텐츠 타입은 주로 application/json을 사용하는데 사실상 표준이다. TEXT, XML을 사용할 수도 있다.
HTTP API 설계 예시
HTTP API 설계에 대한 예시는 다음 3가지 상황에 보통 들어가게 된다. 자세히 하나씩 알아보자.
- HTTP API - 컬렉션
- POST 기반 등록
- 예) 회원 관리 API 제공
- HTTP API - 스토어
- PUT 기반 등록
- 예) 정적 컨텐츠 관리, 원격 파일 관리
- HTML FORM 사용
- 웹 페이지 회원 관리
- GET, POST만 지원
API 설계 - POST 기반 등록
POST 메서드를 사용하여 등록하게 된다면 우리는 `localhost:8080/members`의 URI로 요청 메세지를 보낼 것이다. 이 때 POST 등록 방식의 특징이 드러나는데 클라이언트는 단순히 우리가 등록해야할 리소스 정보에 대해서만 보내주며 서버가 이를 받아 처리한 후 저장된 리소스의 위치를 Location 헤더 속성에 넣어 응답해준다. 혹은 ID를 메시지 바디에 넣어 응답해주게 된다. 이 응답을 받은 클라이언트는 새로 등록된 리소스의 URI를 응답 메세지에서 받아 알 수 있다.
HTTP/1.1 200 Created
Location: /members/100
이 때, members는 컬렉션이 된다.
API 설계 - PUT 기반 등록 예시 : 파일 관리 시스템
PUT 기반의 등록의 예제로는 파일 관리 시스템이 있다. 만약 클라이언트가 서버에 파일을 등록하고 관리하려면 다음과 같은 URI가 필요할 것이다.
- 파일 목록 /files -> GET
- 파일 조회 /files/{filename} -> GET
- 파일 등록 /files/{filename} -> PUT
- 파일 삭제 /files/{filename} -> DELETE
- 파일 대량 등록 /files -> POST
이 때 PUT의 기능이 사용된다. PUT은 기존의 리소스가 없을 때는 신규 등록을 하고 있을 때는 덮어써버리므로 파일 저장 시스템에 필요한 기능이다. 따라서 파일 등록을 할 때 PUT 메서드를 사용한다면 적절한 사용 예시가 될 것이다.
하지만, 이 경우에는 POST 기반 등록 방식과는 다르다. 그 이유는 조금 생각해보면 알 수 있는데 이 방식은 클라이언트가 파일 이름을 알아야지만 관리를 할 수 있다. 즉 클라이언트가 리소스 URI를 지정하여 파일을 등록하고 관리할 수 있다.
이 경우에서 `/files`라는 경로는 리소스의 컬렉션이 아닌 스토어 역할을 한다.
HTML FORM 사용
HTML FORM을 사용하는 경우에 대해서 알아보자. 물론, Javascript를 사용하면 AJAX를 통해 API 통신에 다양한 메서드를 사용할 수 있다. 하지만 순수한 HTML만을 사용하게 되면 GET, POST만 지원한다는 사실을 알아야한다. 이렇게 될 때 수정(PUT), 삭제(DELETE) 메서드는 사용할 수 없기 때문에 다음과 같은 복잡한 API를 사용해야 정상적인 CRUD 기능을 구현할 수 있을 것이다.
- 회원 목록. /members -> GET
- 회원 등록 폼 /members/new -> GET
- 회원 등록 /members/new, /members -> POST
- 회원 조회 /members/{id} -> GET
- 회원 수정 폼 /members/{id}/edit -> GET
- 회원 수정 /members/{id}/edit, /members/{id} -> POST
- 회원 삭제 /members/{id}/delete -> POST
이 경우에는 CRUD를 위한 메서드가 없기 때문에 `/members/{id}/delete`과 같은 컨트롤 URI를 사용해야만 한다.
실무에서는 컨트롤 URI를 무조건 쓰는 것이 아니라 기본적인 메서드를 사용하고 기능 구현이 불가능한 경우에만 쓰는 것을 지향하자. 컨트롤 URI는 동사를 사용하면 된다.
JSP & Servlet 공부를 떠올려 보면 Front Controller(Servlet)를 앞에 두어 command라는 쿼리 파라미터를 받았고 command에 따라 앞에 Action 요청을 팩토리 패턴으로 분류하여 비즈니스 로직을 처리할 수 있도록 개발했었다.
GitHub - Moveuk/2021_JSP: Learning about basic JSP
Learning about basic JSP. Contribute to Moveuk/2021_JSP development by creating an account on GitHub.
github.com
HTTP API 설계 정리
POST 등록을 사용하게 되면 클라이언트는 URI에 대해서 몰라도 된다. 하지만, PUT 등록 방식은 클라이언트가 리소스의 경로를 알고 관리해야한다는 점이 큰 차이점임을 기억하자.(대부분 POST 방식을 사용하며 PUT 방식은 거의 사용할 일이 없다.) 순수 HTML만을 사용하게 되면 GET, POST만을 사용하게 되며 불가피한 경우 컨트롤 URI를 사용하지만 사용을 지양하자.
참고하면 좋은 URI 설계 개념
- 문서(document)
- 단일 개념(파일 하나, 객체 인스턴스 데이터베이스 row)
- 예) /members/100, /files/star.jpg
- 컬렉션(Collection)
- 서버가 관리하는 리소스 디렉터리
- 서버가 리소스의 URI를 생성하고 관리
- 예) /members
- 스토어(Store)
- 클라이언트가 관리하는 자원 저장소
- 클라이언트가 리소스의 URI를 알고 관리
- 예) /files
- 컨트롤러(Controller), 컨트롤 URI
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
- 고객이 주문한 상품을 배송으로 처리하도록 하는 api
- /orders/{ordersID}/delivery
- order와 delivery를 분리하기가 힘듬.
- 동사를 직접 사용
- 예) /members/{id}/delete
- 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
https://restfulapi.net/resource-naming/
REST Resource Naming Guide
In REST, having a strong and consistent REST resource naming strategy – will prove one of the best design decisions in the long term.
restfulapi.net
'노트 정리 > 모든 개발자를 위한 HTTP 웹' 카테고리의 다른 글
| [HTTP 웹] 7. HTTP 헤더 (0) | 2022.10.30 |
|---|---|
| [HTTP 웹] 6. HTTP 상태 코드 (0) | 2022.10.29 |
| [HTTP 웹] 4. HTTP 메서드 (0) | 2022.10.27 |
| [HTTP 웹] 3. HTTP 기본 (0) | 2022.10.26 |
| [HTTP 웹] 2. URI와 웹 브라우저 요청 흐름 (0) | 2022.10.25 |