HTTP 통신 방식
HTTP Request 구조
Start Line
말 그대로 HTTP request의 첫 라인(이름이 너무 식상하지만, 뭐 이미 이렇게 지어졌다).
HTTP request의 start line또한 3부분으로 구성되어 있음.
GET, POST, PUT, DELETE, OPTIONS 등등이 있다.GET 과 POST과 쓰임.GET /search HTTP/1.1
Headers
startline의 target과 headers의 host를 합치면 고유주소가 나온다.
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json
Content-Length: 257
Host: google.com
User-Agent: HTTPie/0.9.3
Body
POST /payment-sync HTTP/1.1 # 메소드 / 타겟 / 버젼
Accept: application/json
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 83
Content-Type: application/json
Host: intropython.com
User-Agent: HTTPie/0.9.3
# 메타정보
{
"imp_uid": "imp_1234567890",
"merchant_uid": "order_id_8237352",
"status": "paid"
} # 바디
그렇다면 이 사람은 로그인한 사람이다! 라는 정보를 갖고있는 쿠키정보는 어디에 넣을까? headers나 body 모두 가능하지만, 부가적 정보이므로 headers에 넣는다.(body에 넣어도 되긴된다.)
Http Response 구조
Status Line
200)Not Found)HTTP/1.1 404 Not Found
Headers
Body
HTTP/1.1 404 Not Found #스테이터스 라인 (버젼 / 코드 / 코드 설명)
# 이 밑 네 줄은 헤더
Connection: close
Content-Length: 1573
Content-Type: text/html; charset=UTF-8
Date: Mon, 20 Aug 2018 07:59:05 GMT
# 이 밑은 바디(실제 데이터)
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
<style>
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(//www.google.com/images/errors/robot.png) 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(//www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png) no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat 0% 0%/100% 100%;-moz-border-image:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(//www.google.com/images/branding/googlelogo/2x/googlelogo_color_150x54dp.png) no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
</style>
<a href=//www.google.com/><span id=logo aria-label=Google></span></a>
<p><b>404.</b> <ins>That’s an error.</ins>
<p>The requested URL <code>/payment-sync</code> was not found on this server. <ins>That’s all we know.</ins>
Get
POST
OPTIONS
http -v OPTIONS http://example.org
OPTIONS / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 0
Host: example.org
User-Agent: HTTPie/0.9.3
HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Content-Length: 0
Date: Mon, 20 Aug 2018 08:37:45 GMT
Expires: Mon, 27 Aug 2018 08:37:45 GMT
Server: EOS (vny006/0450)
PUT
DELETE
200 OK
301 Moved Permanently
HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/index.asp
400 Bad Request
401 Unauthorized
403 Forbidden
401 - 로그인을 실패 (비밀번호 혹은 아이디 잘못 입력)
403 - 로그인은 했지만 대박 주식 리스트를 볼 수 없다? 그럼 403
404 Not Found
http -v google.com/no-such-uri
GET /no-such-uri HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: google.com
User-Agent: HTTPie/0.9.3
HTTP/1.1 404 Not Found
Content-Length: 1572
Content-Type: text/html; charset=UTF-8
Date: Mon, 20 Aug 2018 08:46:48 GMT
Referrer-Policy: no-referrer
500 Internal Server Error
HTTP POST https://api.trueshort.com/user/portfolio
{
"user_id" : 1,
"stocks": [
"005930",
"298730",
"378900"
]
}
HTTP GET https://api.trueshort.com/stock/005930 요청의 경우, 문서나 주석이 없이도 "https://api.trueshort.com 라는 API에서 삼성전자 주식에 관한 정보를 HTTP 요청을 통해 받아오는 구나" 라는 해석이 쉽게 가능하다.하이퍼텍스트 문서를 교환하기 위한 통신 규약. 네트워크끼리 통신을 할 때, 어떤 형식으로 서로 통신하자는 규정해 놓은 통신 구조. 쉽게 말해서 "나는 이렇게 줄 테니 넌 이렇게 받고 너가 준걸 난 그렇게 받을게" 라고 표현할 수 있다. 프론트엔드 서버와 클라이언트 / 백앤드와 프론트앤드 서버간에도 통신이 사용된다.
여기서 프로토콜 = 규약, 트랜스퍼 = 전송, 하이퍼텍스트 = 링크로 연결된 문서
규약이 왜 필요한가? 비트(2진법)을 주고 받을 때 서로가 알아들으려면 규약이 있어야한다. (비트로 구성된 텍스트로 된 메시지를 주고받는 것인데, 그 메시지를 http 규약을 지키면서 주고받는다.)
cf) www 는 규약은 아니고 그냥 전세계적으로 연결되었다는 것이다. www가 성립한건 http 같은 규약이 있어서이다.
HTTP는 요청과 응답이 하나의 통신이다. 각각의 통신은 독립적이다. 즉, 100번째 통신은 자기밖에 몰라서 99번째 통신에 대해서는 모른다. 이전의 통신에 대해서 모른다는 의미이다.
그로인해 단점이 있다. 만약 로그인을 했는데, stateless 라서 상태를 저장하지 않으므로, 로그인을 계속 하게된다. 그래서 이 문제를 해결하려면 요청을 보낼 때 이 요청에 대한 응답에 필요한 정보를 모두 첨부해서 요청에 보낸다. 즉, 예를 들면 이 사람은 이미 로그인을 한 사람이다라는 요청을 보내줘야한다. 그리고 그 정보를 쿠키, 세션이 저장하게 된다.
그렇다면 그 다음에 요청을 보낼 때 쿠키, 세션에 담긴 정보를 같이 담아서 요청을 보내게된다.
HTTP 프로토콜로 데이터를 주고 받기 위해서는 요청(Request)과 응답(Response)를 받아야한다. 자세한 설명은 위에 설명되있다. 간단히 설명해서 request에는 URL과 요청 메서드가 담겨져있고, response 에는 상태코드와 응답데이터가 담겨져있다.
위에 자세한 설명이 되있다. 간단히 말해서 headers는 key:value 값으로 되있는 메타정보를 담고있는 부분이다. body는 실제 데이터가 존재하는 공간이다. 그러나 body에 정보를 없는 경우도 있다.(GET)
해당 request가 의도한 action을 정의하는 부분이다. 예를 들어, Get은 이 내용 주세요 / Post는 이 내용 생성, 삭제 등을 해주세요.
위에 자세한 설명이 있다. 200/301/400/401/403/500 등이 있다.
참고 동영상
그런 REST API로 괜찮은가
REST는 분산 시스템 설계를 위한 아키텍쳐 스타일 즉, 제약 조건의 집합이라고 할 수 있다.
RESTful은 제약 조건의 집합을 모두 만족하는 것을 말한다. REST라는 아키텍쳐 스타일이 있고 RESTful API라는 말은 REST 아키텍쳐 원칙을 모두 만족하는 API라는 뜻이다.
펌 사이트
(번역) RESTful API Designing guidelines — The best practices
더 이해하기 위해서 Employees를 가진 Companies에 대한 API를 작성해보자. /getAllEmployees 는 employees의 리스트를 response하는 API이다. Company에 관련된 API는 다음과 같은 것이 존재할 수 있다.
그리고 다른 operations을 위해서 아주 많은 API endpoints가 존재할 수 있다. 이는 많은 중복을 포함하고 있고, 이러한 API endpoints는 수가 증가함에 따라서 유지보수가 힘들어진다.
URL은 오직 resources(명사)만 포함해야 하며 동사나 actions를 포함해서는 안된다. API path /addNewEmployee 는 action 인 addNew 를 resource 이름은 Employee와 함께 포함하고 있다.
/companies endpoint는 action을 포함하지 않는 좋은 예시이다. 그럼 이럴 땐 어떻게 서버에게 해당 companies resource에 대해서 add, delete, update와 같은 actions을 수행하도록 알려줄 수 있을까?
이는 동사인 HTTP 메소드 (GET, POST, DELETE, PUT)가 그 역할을 수행할 수 있다.
resource는 언제나 API endpoint에서 복수형 이어야 한다. 그리고 만약 resource의 특정 인스턴스에 접근하고 싶다면 URL에 id를 전달하여 접근할 수 있다.
GET path /companies 는 companies의 모든 목록을 가져온다.GET path /companies/34 는 company 34의 상세 내용을 가져온다.DELETE path /companies/34 는 company 34를 삭제한다.몇 가지 다른 사용 사례에서 resource 아래에 여러 개의 resources가 있는 경우 (예 : 회사의 직원들), API endpoint는 아래와 같을 수 있다.
GET /companies/3/employees 는 company 3에 속하는 employees 전체 목록을 가져온다.GET /companies/3/employees/45 는 company 3에 속하는 employee 45의 상세 내용을 가져온다.DELETE /companies/3/employees/45 는 company 3에 속하는 employee 45를 삭제한다.POST /companies 는 새로운 company를 생성하고, 생성된 company의 상세 내용을 리턴한다.결론: path는 resources의 복수형을 포함해야 하고, HTTP 메소드는 해당 resource를 대상으로 수행되는 action의 종류를 정의해야 한다.