Session: HTTP & RESTful HTTP API

Magit·2020년 4월 8일

Session

목록 보기
2/6

What You Will Learn

  1. HTTP란?
  2. Request? Response?
  3. headers와 body의 역할?
  4. Method란?
  5. Status-code 들은 무엇이 있을까요?
  6. RESTful HTTP API는 무엇일까요?
  7. 올바른 end-point 주소는 어떻게 작성할까요?

HTTP 구조 및 핵심 요소

HTTP

  • HyperText Transfer Protocol
  • 하이퍼텍스트(HTML) 문서를 교환하기 위해 만들어진 protocol(통신 규약).
    • 즉 웹상에서 네트워크로 서버끼리 통신을 할때 어떠한 형식으로 서로 통신을 하자고 규정해 놓은 "통신 형식" 혹은 "통신 구조" 라고 보면 된다.
    • 프론트앤드 서버와 클라이언트간의 통신에 사용된다.
    • 또한 백앤드와 프론트앤드 서버간에의 통신에도 사용된다.
  • HTTP는 TCP/IP 기반으로 되어있다.

HTTP 핵심 요소

HTTP 통신 방식

  • HTTP 기본적으로 요청/응답 (request/response) 구조로 되어있다.
    • 클라이언트가 HTTP request를 서버에 보내면 서버는 HTTP response를 보내는 구조.
    • 클라이언트와 서버의 모든 통신이 요청과 응답으로 이루어진다.
  • HTTP는 Stateless 이다.
    • Stateless 란 말그대로 state(상태)를 저장하지 않는 다는 뜻.
    • 즉, 요청이 오면 그에 응답을 할뿐, 여러 요청/응답 끼리 연결되어 있지 않다는 뜻이다. 즉 각각의 요청/응답은 독립적인 요청/응답 이다.
    • 예를 들어, 클라이언트가 요청을 보내고 응답을 받은후, 조금 있다 다시 요청을 보낼때, 전에 보낸 요청/응답에 대해 알지 못한다는 뜻이다.
    • 그래서 만일 여러 요청과응답 의 진행과정이나 데이터가 필요할때는 쿠키나 세션 등등을 사용하게 된다.

HTTP Request 구조

  • HTTP request 메세지는 크게 3부분으로 구성된다.
    • start line
    • headers
    • body

Start Line

  • 말 그대로 HTTP request의 첫 라인(이름이 너무 식상하지만, 뭐 이미 이렇게 지어졌다).

  • HTTP request의 start line또한 3부분으로 구성되어 있음.

    • HTTP Method
      • 해당 request가 의도한 action을 정의하는 부분.
      • HTTP Methods에는 GET, POST, PUT, DELETE, OPTIONS 등등이 있다.
      • 주로 GETPOST과 쓰임.
    • Request target (어디로 가는가? 306동 105호)
      • 해당 request가 전송되는 목표 uri
      • 예를 들어 /login
    • HTTP Version
      • 말 그대로 사용되는 HTTP 버젼. 버젼에는 1.0, 1.1, 2.0 등이 있다.

    GET /search HTTP/1.1

Headers

  • 해당 request에 대한 추가 정보(addtional information)를 담고 있는 부분 (메타 정보)
  • 예를 들어, request 메세지 body의 총 길이 (Content-Length) 등
  • Key:Value 값으로 되어있다 (: 이 사용됨)
    • key:value
    • HOST: google.com => Key = HOST, Value = google.com
  • Headers도 크게 3부분으로 나뉘지만(general headers, request headers, entity headers) 너무 자세한 부분임으로, 3부분 으로 구성되어 있다는것만 알고 있어도 괜찮다.
  • 자주 사용되는 header 정보에는 다음이 있다.
    • Host (타겟 주소 예)은마아파트)
      • 요청이 전송되는 target의 host url: 예를 들어, google.com

startline의 target과 headers의 host를 합치면 고유주소가 나온다.

  • User-Agent
    • 요청을 보내는 클라이언트의 대한 정보: 예를 들어, 웹브라우저(크롬)에 대한 정보.
    • Accept
      • 해당 요청이 받을 수 있는 응답(response) 타입.
    • Connection
      • 해당 요청이 끝난후에 클라이언트와 서버가 계속해서 네트워크 컨넥션을 유지 할것인지 아니면 끊을것인지에 대해 지시하는 부분.
    • Content-Type
      • 해당 요청이 보내는 메세지 body의 타입. 예를 들어, JSON을 보내면 application/json
    • Content-Length
      • 메세지 body의 길이.
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

  • 해당 request의 실제 메세지/내용
  • Body가 없는 request도 많다.
    • 예를 들어, GET request들은 대부분 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 구조

  • Response도 request와 마찬가지로 크게 3부분으로 구성되어 있다.
    • Status line
    • Headers
    • Body

Status Line

  • Response의 상태를 간략하게 나타내주는 부분. (응답을 받은 상태가 어떤 상태냐는 설명을 위한 부분이라서 status line)
  • 3부분으로 구성되어 있다.
    • HTTP 버젼
    • Status code: 응답 상태를 나타내는 코드. 숫자로 되어 있는 코드. (예를 들어, 200)
    • Status text: 응답 상태를 간략하게 설명해주는 부분. (예를 들어, Not Found)
HTTP/1.1 404 Not Found

Headers

  • Request의 headers와 동일하다. 응답에 관한 메타정보가 있는 곳. 대신 응답을 주는 주체인 서버에 대한 정보가 들어가있다.
  • 다만 response에서만 사용되는 header 값들이 있다.
    • 예를 들어, User-Agent 대신에 Server 헤더가 사용된다.

Body

  • Request의 body와 일반적으로 동일하다.
  • Request와 마찬가지로 모든 response가 body가 있지는 않다. 데이터를 전송할 필요가 없을경우 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>


자주 쓰이는 HTTP Methods

Get

  • 이름 그대로 어떠한 데이타를 서버로 부터 받아(GET)올때 주로 사용하는 Method.
  • 데이터 생성/수정/삭제 없이 받아오기만 할때 사용된다.
  • 가장 간단하고 많이 사용되는 HTTP Method
  • 언급한대로 주로 데이터를 받아올때 사용되기 때문에 request에 body를 안 보내는 경우가 많다.

POST

  • 데이터를 생성/수정/삭제 할때 주로 사용되는 Method.
  • 데이터를 생성 및 수정 할때 많이 사용하기 때문에 대부분의 경우 requst body가 포함되서 보내진다.


알고 있으면 좋은 HTTP Methods

OPTIONS

  • 주로 요청 URI에서 사용할 수 있는 Method를 받아올때 사용된다.
  • 예를 들어, /update uri에서 어떤 method를 요청 가능한가(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

  • POST와 비슷하다. 데이터를 생성 할때 사용되는 Method.
  • POST와 겹치기 때문에 PUT을 사용하는 곳도 있고 POST로 통일해서 사용하는 곳도 있는데, 최근 몇년 사이에 POST에 밀려서 잘 사용안되는 추세.

DELETE

  • 특정 데이터를 서버에서 삭제 요청을 보낼때 쓰이는 Method
  • PUT과 마찬가지로 POST에 밀려서 잘 사용안되는 추세.

자주 쓰이는 HTTP Status Code

200 OK

  • 가장 자주 보게되는 status code.
  • 문제없이 다 잘 실행 되었을때 보내는 코드.

301 Moved Permanently

  • 해당 URI가 다른 주소로 바뀌었을때 보내는 코드.
HTTP/1.1 301 Moved Permanently
Location: http://www.example.org/index.asp

400 Bad Request

  • 해당 요청이 잘못된 요청일대 보내는 코드.
  • 주로 요청에 포함된 input 값들이 잘못된 값들이 보내졌을때 사용되는 코드.
    • 예를 들어, 전화번호를 보내야 되는데 text가 보내졌을때 등등.

401 Unauthorized

  • 유저가 해당 요청을 진행 할려면 먼저 로그인을 하거나 회원 가입을 하거나 등등이 필요하다는것을 나타내려 할때 쓰이는 코드.

403 Forbidden

  • 유저가 해당 요청에 대한 권한이 없다는 뜻.
    • 예를 들어, 오직 과금을 한 유저만 볼 수 있는 데이터를 요청 했을때 등.

401 - 로그인을 실패 (비밀번호 혹은 아이디 잘못 입력)
403 - 로그인은 했지만 대박 주식 리스트를 볼 수 없다? 그럼 403

404 Not Found

  • 요청된 uri가 존재 하지 않는다는 뜻.
  • host는 맞는데, request의 타겟이 잘못된것이다.(은마아파트인건 맞는데, 호수가 틀렸다.)
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

  • 서버에서 에러가 났을때 사용되는 코드.
  • API 개발을 하는 백앤드 개발자들이 싫어하는 코드.



RESTful HTTP API 구조 및 핵심 개념

기본 배경 지식

  • URI:
  • HTTP Method
    • HTTP request가 의도하는 action을 정의한것.
    • POST, GET 등등.
  • Payload
    • HTTP request에서 보내는 데이터 (body)

REpresentational State Transfer

  • 웹상에서 사용되는 여러 리소스를 HTTP URI로 표현하고 그 리소스에 대한 행위를 HTTP Method로 정의하는 방식.
    • 즉, 리소스(HTTP URI로 정의된)를 어떻게 한다(HTTP Method + Payload)를 구조적으로 깔끔하게 표현하는것.
    • Method는 주로 GET과 POST만 사용한다.
    • PUT과 DELETE 등도 사용하는 곳도 있지만, 그냥 GET과 POST만 사용하는 것이 단순하기 때문에 GET과 POST만 사용하는 추세.
  • 예를 들어, 삼성전자 주식 정보를 받기 위한 HTTP 요청:
  • 유저의 보유 주식 종목들을 DB에 저장하는 HTTP 요청:
  HTTP POST https://api.trueshort.com/user/portfolio

{
    "user_id" : 1,
    "stocks": [ 
        "005930",
        "298730",
        "378900"
    ]
}

RESTful API의 장점

  • 여러 장점들이 있지만, 사실 그중 가장 명확한 장점은 바로 self-descriptiveness 이다.
  • RESTful API는 그 자체만으로도 API의 목적이 쉽게 이해가 된다.
    • 예를 들어, 위의 HTTP GET https://api.trueshort.com/stock/005930 요청의 경우, 문서나 주석이 없이도 "https://api.trueshort.com 라는 API에서 삼성전자 주식에 관한 정보를 HTTP 요청을 통해 받아오는 구나" 라는 해석이 쉽게 가능하다.

RESTful API를 개발할 때 유의할 점

  • /(슬래시)는 계층 관계를 나타낼때 사용된다.
  • URI에 _(underscore)는 주로 포함하지않고 또한 영어 대문자보다 소문자를 쓴다. 그리고 너무 긴 단어는 잘 사용하지 않는다. 이 모든건 가독성을 높이기 위해서다.
  • URI는 명사를 사용한다.
    • /books/novel/stephenking 이라고 하지 /books/novel/get-stephenking 이라고 잘 하지 않는다.
    • 그 이유는 동사는 GET, POST 같은 HTTP Method를 통해 표현하기 때문이다.



1. HTTP란?

하이퍼텍스트 문서를 교환하기 위한 통신 규약. 네트워크끼리 통신을 할 때, 어떤 형식으로 서로 통신하자는 규정해 놓은 통신 구조. 쉽게 말해서 "나는 이렇게 줄 테니 넌 이렇게 받고 너가 준걸 난 그렇게 받을게" 라고 표현할 수 있다. 프론트엔드 서버와 클라이언트 / 백앤드와 프론트앤드 서버간에도 통신이 사용된다.
여기서 프로토콜 = 규약, 트랜스퍼 = 전송, 하이퍼텍스트 = 링크로 연결된 문서

규약이 왜 필요한가? 비트(2진법)을 주고 받을 때 서로가 알아들으려면 규약이 있어야한다. (비트로 구성된 텍스트로 된 메시지를 주고받는 것인데, 그 메시지를 http 규약을 지키면서 주고받는다.)

cf) www 는 규약은 아니고 그냥 전세계적으로 연결되었다는 것이다. www가 성립한건 http 같은 규약이 있어서이다.

HTTP는 요청과 응답이 하나의 통신이다. 각각의 통신은 독립적이다. 즉, 100번째 통신은 자기밖에 몰라서 99번째 통신에 대해서는 모른다. 이전의 통신에 대해서 모른다는 의미이다.
그로인해 단점이 있다. 만약 로그인을 했는데, stateless 라서 상태를 저장하지 않으므로, 로그인을 계속 하게된다. 그래서 이 문제를 해결하려면 요청을 보낼 때 이 요청에 대한 응답에 필요한 정보를 모두 첨부해서 요청에 보낸다. 즉, 예를 들면 이 사람은 이미 로그인을 한 사람이다라는 요청을 보내줘야한다. 그리고 그 정보를 쿠키, 세션이 저장하게 된다.
그렇다면 그 다음에 요청을 보낼 때 쿠키, 세션에 담긴 정보를 같이 담아서 요청을 보내게된다.

2. Request? Response?

HTTP 프로토콜로 데이터를 주고 받기 위해서는 요청(Request)과 응답(Response)를 받아야한다. 자세한 설명은 위에 설명되있다. 간단히 설명해서 request에는 URL과 요청 메서드가 담겨져있고, response 에는 상태코드와 응답데이터가 담겨져있다.

3. headers와 body의 역할?

위에 자세한 설명이 되있다. 간단히 말해서 headers는 key:value 값으로 되있는 메타정보를 담고있는 부분이다. body는 실제 데이터가 존재하는 공간이다. 그러나 body에 정보를 없는 경우도 있다.(GET)

4. Method란?

해당 request가 의도한 action을 정의하는 부분이다. 예를 들어, Get은 이 내용 주세요 / Post는 이 내용 생성, 삭제 등을 해주세요.

5. Status-code 들은 무엇이 있을까요?

위에 자세한 설명이 있다. 200/301/400/401/403/500 등이 있다.

6. RESTful HTTP API는 무엇일까요?

참고 동영상
그런 REST API로 괜찮은가

REST는 분산 시스템 설계를 위한 아키텍쳐 스타일 즉, 제약 조건의 집합이라고 할 수 있다.
RESTful은 제약 조건의 집합을 모두 만족하는 것을 말한다. REST라는 아키텍쳐 스타일이 있고 RESTful API라는 말은 REST 아키텍쳐 원칙을 모두 만족하는 API라는 뜻이다.

  • 용어
    • Resource : 어떤 것의 대표 혹은 객체. 관련 데이터를 갖고 있고 이를 운용하기 위한 메소드 집합을 가질 수 있다. (예. animals, schools, employees 는 resources이고 delete, add, update는 이 resources들에게 수행되는 operations이다.)
    • Collections : resources의 집합이다. (예. Companies는 Company resource의 집합이다.)
    • URL(Uniform Resource Locator) : 어느 resource가 어디에 위치할 수 있고, 어떤 action들이 수행될 수 있는지를 나타내는 경로

7. 올바른 end-point 주소는 어떻게 작성할까요?

펌 사이트
(번역) RESTful API Designing guidelines — The best practices

더 이해하기 위해서 Employees를 가진 Companies에 대한 API를 작성해보자. /getAllEmployees 는 employees의 리스트를 response하는 API이다. Company에 관련된 API는 다음과 같은 것이 존재할 수 있다.

  • /addNewEmployee
  • /updateEmployee
  • /deleteEmployee
  • /deleteAllEmployees
  • /promoteEmployee
  • /promoteAllEmployees

그리고 다른 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를 전달하여 접근할 수 있다.

  • method GET path /companies 는 companies의 모든 목록을 가져온다.
  • method GET path /companies/34 는 company 34의 상세 내용을 가져온다.
  • method 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의 상세 내용을 리턴한다.
    이와 같은 API가 더 일관성 있고 정확하지 않은가?

결론: path는 resources의 복수형을 포함해야 하고, HTTP 메소드는 해당 resource를 대상으로 수행되는 action의 종류를 정의해야 한다.


profile
이제 막 배우기 시작한 개발자입니다.

0개의 댓글