자바스크립트 JS - Interaction With Server

hyunnu·2021년 5월 27일
0

📖Review(21.05.27)

  • 리소스가 존재하는 곳과 리소스를 사용하는 앱을 분리시킨 것을 2-Tier 아키텍쳐, 클라이언트 - 서버 아키텍쳐라 한다.
  • 서버의 기능을 좀 더 나누어 서버를 리소스를 전달해주는 앱으로 두고 리소스 저장 공간(데이터베이스)를 따로 둔 형태를 3-Tier 아키텍쳐라 한다.

ex)

  • 클라이언트 : 웹사이트(웹 앱), 스마트폰 태블릿용 앱, 데스크탑 앱
  • 서버 : 웹 서버, 파일 서버, 메일 서버, 데이터베이스 서버

클라이언트와 서버 간의 통신은 요청응답으로 구성됩니다. (요청이 있어야 응답이 옵니다.)

HTTP(Hypertext Transfer Protocol)

요청이 있으면 반드시 응답이 온다!(request & response)

HTML 문서를 전송하기 위한 어플리케이션 계층 프로토콜, 웹 브라우저와 웹 서버 간의 통신을 위해 설계되었지만 다른 용도로도 사용할 수 있다.

  • Properties
    • Stateless(무상태성) : 서버는 두 요청 사이에 데이터(상태)를 유지하지 않는다.

Request & Response

클라이언트는 서버에게 특정 데이터나 행동을 '요청' 한다. 서버는 클라이언트의 요청을 받고 그에 따른 약속된 '응답' 을 클라이언트에게 준다. 이러한 요청과 응답은 특정 언어로 통신하겠다는 약속하에 이루어 진다. HTTP가 바로 그 약속이다.

Request(클라이언트)

Request message(요청 메세지)

HTTP를 통해 클라이언트가 서버에게 요청을 보낼때 미리 정해진 규칙(구조)에 따라 메세지를 보낸다. 요청 메세지는 다음으로 구성된다.

  • HTTP methods : 클라이언트가 서버에게 요청하는 행동
    • GET : 특정 리소스를 가져오도록 요청, 데이터를 받기만 하며 브라우저가 처음 가동될 때 처음 보내는 메서드(Read)
    • POST (form 제출할 때) : 특정 리소스를 서버에 제출할때 사용하는 메서드, 멱등성이 없으며 서버 상태의 변화를 일으킴 (Create)
    • PUT : POST와 비슷하나, 연속적인 요청시에도 같은 효과를 가져옴(멱등성 o), 기존의 데이터를 request payload(요청 페이로드)로 교체하는 용도 (Update)
    • DELETE : 리소스의 삭제를 요청 (Delete)
    • OPTIONS : 특정 리소스의 통신을 설정하는데 사용하며 CORS와 관련된다.

    그 외에
    • PATCH : 서버의 특정 리소스 중에 일정 부분만 수정하는데 사용된다.
    • HEAD : GET과 동일하지만 응답 본문을 포함하지 않는다. (응답의 헤더만 읽는다.)

멱등성? 멱등성이란 동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니는 것을 의미한다.


출처 MDN : HTTP 개요

  • 경로(Path): 서버에 라우팅이 설정되어 있다면 특정 리소스로 접근하기 위한 라우팅 경로를 표시한다.
  • 프로토콜 버전(Version of the protocol) : 현재 통신에 사용되는 프로토콜과 그 버전을 나타낸다.
  • 헤더(Headers) : 메서드, 경로, 프로토콜은 가장 윗 줄에 한줄로 표시되며 이후 내용은 헤더이다. 헤더는 필수 정보 외에 부가적인 정보를 전달해 준다.
  • 본문(Body) : 헤더 밑에 위치하는 전송되는 정보의 본문이다. 서버를 통해 얻으려는 최종적인 데이터는 본문에 표시된다. json을 비롯한 여러 형식으로 전송된다.

Response(서버)

  • 프로토콜 버전(Version of the protocol) : 응답에 사용되는 프로토콜 버전을 명시한다.
  • 상태 코드(Status code) : 클라이언트 요청에 대한 서버의 응답을 함축적으로 나타내어 주는 3개 숫자다.
    100 : 임시적인 응답이며 지금까지의 상태가 괜찮다는 것을 의미한다.
    200 : 요청에 대해 성공하였음을 의미한다.
    200 OK : 요청이 성공적으로 되었음을 의미한다. 성공은 HTTP 메서드에 따라 의미가 달라진다.
    201 Created : 요청이 성공적 이었으며 새로운 리소스가 서버에 생성 되었음을 의미한다.
    300 : 요청에 대해서 하나 이상의 응답이 가능하다. 클라이언트 에서 이 중 하나를 반드시 선택해야 한다.
    400 : 서버가 요청을 이해할 수 없다는 것을 의미한다. 클라이언트단의 잘못된 요청
    403 Forbidden : 클라이언트가 컨텐츠에 접근할 권리가 없다는 의미
    404 Not Found : 요청받은 리소스를 찾을 수 없다.
    500 : 서버가 처리 방법을 모르는 상황이 발생, 서버단의 잘못 혹은 서버 연결이 안되었을 경우를 의미한다.
    502 : Bad Gateway : 게이트웨이가 잘못되어 잘못된 응답을 수신했다는 의미
    504 : Gateway Timeout : 서버 연결시간이 초과 되었다는 의미
  • 상태 메세지(Status message) : 상태 코드와 함께 오는 메세지로 OK, Created, Not Found 등이 있다.
  • 헤더(Headers) : CORS 상황일때는 CORS preflight에 대한 응답으로 Access-Control-Allow를 헤더에 실어 보낸다. 본문의 형식도 헤더에 적혀 있다.(Content-Type)
  • 본문(Body)

Content-Type

응답 헤더의 구성 요소 중 Content-Type은 응답 본문이 어떤 형식인지 알려준다. 일종의 '확장자' 개념인데 파일을 저장하거나 열어 볼 때 확인할 수 있는 확장자는 파일이 어떤 형태를 가지고 있는지 정보를 대략적으로 알려준다.(notepad-.txt, JavaScript-.js, Content-Type-MIME 타입)

MIME 타입

MIME 타입은 클라이언트에게 전송된 문서의 형태를 알려주기 위한 메커니즘, 각 문서와 함께 올바른 MIME 타입을 전송하도록 서버가 정확히 설정하는 것이 중요!

일반적인 MIME 타입의 구조는 : type/subtype

ex)

  • application/json
  • text/plain
  • image/jpeg
  • audio/ogg
  • video/mp4

API(Application Programming Interface)

서버 자원을 잘 쓸 수 있는 메뉴판 , 서버의 요구사항

클라이언트와 서버와의 통신에 있어서 서버가 보내는 응답은 서버를 설계한 백엔드 개발자의 특정 목적에 따라 특정 데이터를 취사 선택하여 특정 형태로 보낸다. 이때 해당 정보를 클라이언트 에이전트에 구현해야 하는 프런트엔드 개발자는 응답에 대하여 사전 정보가 없으면, 혹은 요청을 할 때 해당 자료로 접근하기 위한 경로라던가 메서드를 알지 못한다면 접근 불가하다.

이때 API는 일종의 '설명서' 역할을 한다.

API(Application Programming Interface 애플리케이션 프로그래밍 인터페이스, 응용 프로그램 프로그래밍 인터페이스)는 응용 프로그램에서 사용할 수 있도록, 운영 체제나 프로그래밍 언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스를 뜻한다. 주로 파일 제어, 창 제어, 화상 처리, 문자 제어 등을 위한 인터페이스를 제공한다.

RESTful API (Representational State Transfer)

  • REST의 정의
    • "Representational State Transfer"의 약자
    • 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미
    • 즉, 자원(resource)의 표현(representation)에 의한 상태 전달
      a. 자원(resource)의 표현
      • 자원: 해당 소프트웨어가 관리하는 모든 것
        EX) 문서, 그림, 데이터, 해당 소프트웨어 자체 등
      • 자원의 표현: 그 자원을 표현하기 위한 이름
        EX) DB의 학생 정보가 자원일 때, 'students'를 자원의 표현으로 정한다.
      b. 상태(정보) 전달
      • 데이터가 요청되어지는 시점에서 자원의 상태(정보)를 전달한다.
      • JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.
  • REST의 구체적인 개념
    • HTTP URO(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP MEthod(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다. 즉, HTTP Method를 통해 Resource를 처리하도록 설계된 아키텍쳐를 의미한다.
    • 웹 사이트의 이미지, 텍스트, DB 내용 등의 모든 자원에 고유한 ID인 HTTP URI를 부여한다.

REST의 장단점

  • 장점
    • HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구출할 필요가 없다.
    • HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.
    • HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
    • REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악할 수 있다.
    • 여러가지 서비스 디자인에서 생길 수 있는 문제를 최소화
    • 서버와 클라이언트의 역할을 명확하게 분리한다.
  • 단점
    • 표준이 존재하지 않는다.
    • 사용할 수 있는 메소드가 4가지 밖에 없다.

REST 구성 요소

  1. 자원(Resource) : URI
    • 모든 자원에 고유한 ID가 존재하고, 이 자원은 Server에 존재한다.
    • 자원을 구별하는 ID는 '/groups/:group_id'와 같은 HTTP URI다.
    • Client는 URI를 이용해서 자원을 지정하고 해당 자원의 상태(정보)에 대한 조작을 Server에 요청한다.
  2. 행위(verb): HTTP Method
    • HTTP 프로토콜의 Method를 사용한다.
    • HTTP 프로토콜은 GET, POST, PUT, DELETE와 같은 메서드를 제공한다.
  3. 표현(Representation of Resource)
    • Client가 자원의 상태(정보)에 대한 조작을 요청하면 Server는 이에 적절한 응답(Representation)을 보낸다.
    • REST에서 하나의 자원은 JSON, XML, TEXT, RSS 등 여러 형태의 Representation으로 나타내어 질 수 있다.
    • JSON 혹은 XML를 통해 데이터를 주고 받는 것이 일반적이다.

REST API의 특징

  • 사내 시스템들도 REST 기반으로 시스템을 분산해 확장성과 재사용성을 높여 유지보수 및 운용을 편리하게 할 수 있다.
  • REST는 HTTP 표준을 기반으로 구현하므로, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있다.

6가지 제약

  1. Client - Server : 요청이 HTTP를 통해 이루어지는 클라이언트-서버 아키텍쳐
  2. Stateless : 각 요청과 응답이 이전의 요청과 응답과 연결되어 있지 않고 관계가 없는 상태
  3. Cacheable : 캐싱가능해야 한다.
  4. Layered System : 서버는 다중 계층으로 구성될 수 있으며, 프록시나 게이트웨이 같은 네트워크 기반의 중간 매체를 사용할 수 있고 로드 밸런싱을 두어 구조상의 유연성을 둘 수도 있다.
  5. Code on Demend : 사용자의 요구에 따라 그 요구에 따른 코드가 호출되어야 한다.(Optional)
  6. Uniform interface : URI로 지정한 리소스에 대한 동작을 통일되고 한정적인 인터페이스로 수행해야 한다.

6가지의 제약중 4번까지의 제약은 HTTP를 통해 만족할 수 있다. 5번 제약은 자바스크립트로 구현 가능하다. RESTful API를 구현하기 위해 개발자가 주의해야 할 제약은 6번째이다.

REST API 설계 기본 규칙

참고 리소스 원형

도큐먼트 : 객체 인스턴스나 데이터베이스 레코드와 유사한 개념
컬렉션 : 서버에서 관리하는 디렉터리라는 리소스
스토어 : 클라이언트에서 관리하는 리소스 저장소

  1. URI는 정보의 자원을 표현해야 한다.

    • resource는 동사보다는 명사를, 대문자보다는 소문자를 사용한다.
    • resource의 도큐먼트 이름으로는 단수 명사를 사용해야 한다.
    • resource의 컬렉션 이름으로는 복수 명사를 사용해야 한다.
    • resource의 스토어 이름으로는 복수 명사를 사용해야 한다.
      Ex) GET /Member/1 -> GET /members/1
  2. 자원에 대한 행위는 HTTP Method(GET, PUT, POST, DELETE 등)로 표현한다.

    • URI에 HTTP Method가 들어가면 안된다.
      Ex) GET /members/delete/1 -> DELETE /members/1
    • URI에 행위에 대한 동사 표현이 들어가면 안된다.(즉, CRUD 기능을 나타내는 것은 URI에 사용하지 않는다.)
      Ex) GET /members/show/1 -> GET /members/1
      Ex) GET /members/insert/2 -> POST /members/2
    • 경로 부분 중 변하는 부분은 유일한 값으로 대체한다.(즉, :id는 하나의 특정 resource를 나타내는 고유값이다.
      Ex) student를 생성하는 route: POST /students
      Ex) id=12인 student를 삭제하는 route: DELETE /students/12

Uniform interface

이를 구현하기 위한 조건은 다음과 같다.

  • Identification of resources : API의 URI는 자원을 표현하는데 중점을 두어야 한다. 행위를 표현하는 것은 옳지 않다.(자원의 식별) URI에서 리소스를 나타낼때는 명사를 사용해야 한다.
  • Manipulation of resources through representation : 표현을 통한 자원의 수정 ⇒ 자원에 대한 행위는 HTTP 메서드로 표현해야 한다.
  • Self-descriptive messages : RESTful API 메세지만 보고도 요청과 응답이 무엇을 하려하는가를 이해할 수 있어야 한다.
  • Hypermedia As The Engine Of Application State(HATEOAS) : 클라이언트가 특정 리소스에 접근하기를 원한다면, 리턴되는 지시자에 의해 구별될 수 있어야 한다. ⇒ wikipedia의 글을 읽던 도중 관련된 URI로 연결되는 하이퍼텍스트 링크가 예시

Best Practice

RESTful API를 구현하기 위해 참고해야 하는 가장 효율적인 주의사항은 다음과 같다.

  1. 리소스를 나타내는데 명사를 사용해야 한다.
  2. 일관성을 지켜야 한다.
    • 슬래시 구분자(/)는 계층 관계를 나타낼때 사용한다.
    • URI 마지막 문자로 슬래시(/)를 포함하지 않는다.
    • 하이픈(-)은 URI 가독성을 높이는데 사용한다.
    • 언더바(_)는 URI에 사용하지 않는다.
    • URI 경로에는 소문자가 적합하다.
    • 파일 확장자는 URI에 포함시키지 않는다.
  3. CRUD는 URI에 사용하지 말아야 한다.
  4. filter가 필요하면 query component를 사용해야 한다.

REST API 설계 예시

CORS(Cross-Origin Resource Sharing)

초기의 클라이언트는 단일 서버에게서 모든 정보를 받았다. 페이지 구성에 대한 정보(HTML)와 디자인(CSS) 그리고 데이터는 모두 단일 서버에 저장되어 있었고 클라이언트는 서버의 응답을 표시해주기만 했으므로 클라이언트에 의한 서버로의 위협은 상대적으로 작았다.

서버에서 내려준 정보만을 가지고 읽고 쓰기 때문에 해당 출처는 안전하였다.

But 최근 웹은 단일 서버에서 모든 정보를 받지 않는다. HTML과 CSS를 구현하는 웹서버와 데이터의 처리를 담당하는 Database와 서버단이 분리되어 있고 필요에 따라 여러 출처에서 데이터를 가져온다. 이와 같이 서버가 신용할 수 없는 출처에 대해 접근해야 하기에 서버의 안정성이 취약해 졌다.
보안상의 문제를 해소하기 위해 브라우저에선 서버에게 무작정 요청을 보내지 않고 현재 클라이언트와 서버가 다른 출처를 따른다면 미리 서버에게 '지금 데이터를 보내도 괜찮아'라고 물어보도록 하게 된다.

동일 출처 정책(Same-Origin Policy)

동일한 출처(Origin)에서 온 요청인지 확인하는 기준은 동일 출처 정책을 따른다. SOP에 따르면 동일 출처는

프로토콜과 포트, 호스트(도메인) 3가지가 모두 동일하면 동일 출처로 본다.

SOP에 따라 동일 출처가 아니라면 CORS 상황이 발생한다.

CORS preflight

SOP에 반하여 동일하지 않은 출처로 판단이 될 경우 '브라우저'는 서버에게 본 요청을 보내기 전에 미리 사전 요청을 보낸다. '내가 지금 이걸 보낼 건데 괜찮아?'라는 메세지를 서버에게 미리 보내고 서버는 해당 '요청'에 대해 Access-Control-Allow-Origin과 같은 Access-Control-Allow 헤더로 '응답'한다.

Access-Control-Allow 헤더

CORS preflight에 대한 서버의 응답은 헤더에 다음 4가지의 서버 규칙을 클라이언트로 전송하게 된다.

  • Access-Control-Allow-Origin : 서버가 허용하는 도메인을 알려준다.
    • * : 모든 도메인에 대해 허용한다.
    • 특정 도메인 주소 : 해당하는 도메인만 허용한다.
  • Access-Control-Allow-Methods : 서버가 허용하는 HTTP 메서드를 알려준다.
  • Access-Control-Allow-Headers : 서버가 허용하는 헤더를 알려준다.
  • Access-Control-Max-Age : 동일 preflight 요청에 대한 수락 유지 시간을 알려준다. 초단위로 되어있다.
profile
Data Engineer / Back-End Developer

0개의 댓글