-
프론트엔드와 백엔드를 완전 분리해서 개발하고 있는데, 아직 관련 개념이 정확하게 잡히지 않은 것 같아서 일단 내가 보기 편한 방식으로 한 번 정리해둔다.
REST API를 고안한 사람의 의도는 HTML 페이지 없이 오는 데이터만으로도 웹 서핑이 가능하게 하는거였다고 한다(view단이 없는거라기보단 view형태가 기존의 HTML이 아니라 JSON 데이터 정도로 변경된 수준). 보통 UI를 담당하는 SPA가 따로 있고(React.js, Vue.js 등등), 그걸로 UI를 만들면 UI에서는 REST API를 호출해서 Json 데이터만 사용하는 것이다. 기존의 JSP개념과는 다른데, Spring 기준에서 말해보면, JSP든 타임리프든 view resolver가 필요없어지는 것이다.
SPA형태일 수도 있고 UI전용서버가 따로 있는 경우도 있다. 보통은 API서버와 별개로 app.domain.com, api.domain.com 이런 식으로 UI전용 서버를 따로 둔다.
API(Application Programming Interface)
: API 는 Application Programming Interface의 줄임말로, 애플리케이션(소프트웨어)간의 통신 방법을 정의하는 것을 말한다. 주로 요청(Request)과 응답(Response)으로 이루어져있으며 클라이언트와 서버 관계에서, 웹 API 또는 REST API로 많이 사용된다.
웹 프로젝트 하나 안에서 작업할 때는 JSP나 타임리프같은 템플릿 언어로 구성된 화면에서 파라미터를 통해 필요한 화면으로 보내는 방식이었지만 최근에는 프론트엔드와 백엔드를 분리해서 작업하는 방식이 많다. 프론트단에서 백단으로 데이터를 요청(Request)하고 백단에서는 요청받은 데이터를 가공하여 프론드단으로 다시 응답(Response)해주어야 한다. 이때 서로간의 규칙이 정해져있지 않으면 데이터 전달이 어렵다. 그래서 정확한 데이터 전달을 위해 다음과 같은 방식들이 사용된다.
- 요청과 응답 방식 정의 REST(Representational state transfer)
- 데이터 전달을 위한 JSON(Javascript Object Notation)
- 로그인을 위한 토큰 인증 JWT(JSON Web Token) 등등...
웹 API 흐름과 동기/비동기
웹 API의 기본적인 흐름도 1. 화면(프론트엔드)에서 서버(백엔드)로 데이터를 요청한다
2. 서버는 요청에 대한 작업을 수행한다
3. 서버는 필요할 경우 데이터 저장소(DB)와 통신하여 데이터를 가져온 후 가공한다
4. 프론트엔드의 요청에 대한 응답에 가공한 데이터를 포함하여 전송한다
API는 요청과 응답이 한 쌍이다. 서버가 요청을 받았다면 반드시 응답해야 하고 화면에서 요청을 했다면 응답을 기다려야 한다. 이렇게 기다리는 동안 다른 작업을 할 수 없을 때 이런 방식을 동기(Synchronouse)식이라고 한다.
이에 반대되는 방식이 비동기(Asynchronous)식이고 주로 Ajax를 통해 작업한다. 비동기식은 중간자의 개념이 추가된다. 중간자를 통해 요청하고 응답을 대기한다. 응답을 받았다면 화면에 전달해준다. 이렇게 화면이 멈추지 않고도(=대기상태가 되지 않고) 데이터를 주고받을 수 있다.
UI
: 사용자가 브라우저에서 접하는 화면이다. 사용자의 행위에 의해 이벤트가 발생하고 서버로 요청이 들어간다. 전통적인 방식에서는 서버에서 렌더링된 HTML을 WAS로부터 내려받아 화면을 구성하지만 SPA에서는 클라이언트에서 렌더링한 후 직접 API를 호출한다
웹애플리케이션
: 웹자원(HTML, Javascript, CSS 등)이 위치한다. 서버 렌더링의 경우, JSP 등을 이용하여 REST API를 호출한 후 백엔드로부터 전달받은 JSON 데이터를 이용하여 화면을 구성한다. 클라이언트 렌더링 방식에서는 웹애플리케이션 서버 내부 파일 시스템 대신 AWS Bucket, BitBucket 등의 오브젝트 저장소를 이용해서 Static Website를 구성할 수 있다. 이 경우 버킷의 도메인을 통해 index.html을 불러온다
API 게이트웨이
: API 게이트웨이는 시스템의 유일한 진입점을 제공하는 서버이다. 객체 지향 디자인의 Facade패턴처럼 API Gateway는 내부의 시스템 아키텍처를 은닉하고 개별 클라이언트에게 적절하게 가공된 API를 노출한다. 또한 인증처리, 모니터링, 로드밸런싱, 캐싱 등의 기능을 제공한다. API 게이트웨이는 리버스 프록시처럼 작동하여, 클라이언트로부터 요청되는 API를 모두 받아들이면서 클라이언트로 결과 값을 전송한다. 여러 요청을 합쳐서(Aggregation) 한 번에 보내줄 수 있다
Controller/Service/DAO
: 스프링의 어노테이션을 이용해 외부에서 들어오는 요청을 백엔드의 서비스와 연결하는 역할을 컨트롤러가 해준다. 클라이언트의 요청의 헤더 정보인 Content-Type을 이용해서 수신되는 데이터의 타입을 지정한다
Spring 어노테이션
: @Controller는 결과 값에 해당하는 이름에 매칭되는 view를 찾아주고 @RestController는 Json, XML 형태로 HTTP response를 직접 호출한 곳으로 보내준다. RestController는 @ResponseBody를 자동으로 붙여주는 어노테이션이라고 생각하면 된다. RestController는 view를 리턴하지 않는다(rest api는 view가 없고 당연히 view resolver를 타지 않음).
@Service, @Repository는 @Component 어노테이션에 대한 논리적인 구분으로 서비스레이어와 퍼시스턴스 레이어를 구분하기 위해 사용한다.
REST API(Representational State Transfer API)
: REST를 기반으로 만들어진 API를 의미한다.
REST : Representational State Transfer의 약자로, 자원의 이름을 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미한다. 따라서, REST는
1. HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고
2. HTTP Method(POST, GET, PUT, PATCH, DELETE 등)를 통해
3. 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미한다
웹 서비스를 설계하는 아키텍처적인 접근방법이다
CRUD Operation
: CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 말한다. REST에서의 CRUD Operation 동작 예시는 다음과 같다
Create : 데이터 생성(POST)
Read : 데이터 조회(GET)
Update : 데이터 수정(PUT, PATCH)
Delete : 데이터 삭제(Delete)
REST의 구성요소
1. 자원(Resource) : HTTP URI
2. 자원에 대한 행위(Verb) : HTTP Method
3. 자원에 대한 행위의 내용(Representations) : HTTP Message Pay Load
REST의 특징
1. Server-Client(서버-클라이언트 구조) : REST 서버는 API 제공, 클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보)등을 직접 관리하는 구조로, 각각의 역할이 확실하게 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로간 의존성이 줄어들게 된다.
2. Stateless(무상태) : REST는 무상태성 성격을 갖는다. 즉, 작업을 위한 상태 정보를 따로 저장하고 관리하지 않는다. 세션 정보나 쿠키 정보를 별도로 저장하고 관리하지 않기 때문에 API서버는 단순히 들어오는 요청만 처리하면 된다. 그래서 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않음으로써 구현이 단순해진다.
3. Cacheable(캐시 처리 가능) : HTTP라는 기존 웹 표준을 그대로 사용하기 때문에 웹에서 사용하는 기존 인프라를 그대로 활용 가능하다. 따라서 HTTP가 가진 캐싱 기능이 적용 가능하다. HTTP 프로토콜 표준에서 사용하는 Last-Modified태그나 E-Tag를 이용하면 캐싱 구현이 가능하다.
4. Self-descriptiveness(자체 표현 구조) : REST API 메시지만 보고도 이를 쉽게 이해할 수 있는 자체 표현 구조로 되어 있다.
5. Uniform Interface(인터페이스 일관성) : Uniform Interface는 URI로 지정한 리소스에 대한 조작을 통일되고 한정적인 인터페이스로 수행하는 아키텍처 스타일을 말한다.
6. 계층형 구조 : REST 서버는 다중 계층으로 구성될 수 있으며 보안, 로드 밸런싱, 암호화 계층을 추가해 구조상의 유연성을 둘 수 있고 PROXY, 게이트웨이같은 네트워크 기반의 중간매체를 사용할 수 있게 한다
REST의 장점
* HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위해 별도의 인프라를 구축할 필요가 없다
* HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다
* HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다
* Hypermedia API의 기본을 충실히 지키면서 범용성을 보장한다
* REST API 메시지가 의도하는 바를 명확하게 나타내기 때문에 쉽게 파악할 수 있다
* 여러 가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다
* 서버와 클라이언트의 역할을 명확하게 분리한다
REST의 단점
* 표준이 존재하지 않아서 정의가 필요하다
* HTTP Method 형태가 제한적이다
* 브라우저를 통해 테스트할 일이 많은 서비스면 쉽게 고칠 수 있는 URL보다 Header 정보의 값을 처리해야 하므로 전문성이 요구된다
REST API 디자인 가이드
1) URI는 정보의 자원을 표현해야 한다
2) 자원에 대한 행위는 HTTP Method(GET,POST,PUT,DELETE)로 표현한다
REST API 요청에 포함된 요소
1) 고유 리소스 식별자
: 서버는 고유한 리소스 식별자로 각 리소스를 식별한다. 일반적으로 URL(Uniform Resource Locator)를 사용하여 리소스 식별을 수행한다. 요청 엔드포인트라고도 하며 클라이언트가 요구하는 사항을 서버에 명확하게 지정한다
2) 메서드
* GET
: 특정 데이터를 조회할 때 사용한다. GET 요청에 데이터를 포함하여 보낼 수 있다. 민감하거나 중요한 정보는 포함해서 보내면 안 된다.
* POST
: 데이터를 생성할 때 사용한다. GET요청과 마찬가지로 데이터를 포함해서 보낼 수 있다. 동일한 POST 요청을 여러번 전송하면 동일한 데이터를 여러번 생성하게 되는 부작용이 있다.
* PUT
: 기존의 데이터를 수정할 때 사용한다. POST와 달리 여러 번 요청해도 결과가 동일하다. 수정요청시 모든 필드를 필요로 한다.
* PATCH
: 데이터를 수정할 때 사용하지만 PUT과 다르게 수정할 일부 필드만 필요로 한다.
* DELETE
: 데이터를 삭제할 때 사용한다
3) HTTP 헤더
: 요청 헤더는 클라이언트와 서버간에 교환되는 메타데이터이다.
: POST, PUT 및 기타 HTTP 메서드가 성공적으로 작동하기 위한 데이터가 포함될 수 있다
: 수행해야 할 작업에 대한 자세한 정보를 서버에 제공하는 파라미터가 포함될 수 있다
- URL 세부정보를 지정하는 경로 파라미터
- 리소스에 대한 추가 정보를 요청하는 쿼리 파라미터
- 클라이언트를 빠르게 인증하는 쿠키 파라미터
REST API 응답에 포함된 요소
1) 상태 표시줄
: 상태 표시줄에는 요청 성공 또는 실패를 알리는 3자리의 상태 코드가 있다
* 200 OK : 일반 성공 응답
* 201 Created : POST 메서드 성공 응답
* 400 Bad Request : 서버가 처리할 수 없는 잘못된 요청
* 500 Internal Server Error : 서버에 문제가 있음
* 503 Service Unavailable : 서버가 요청을 처리할 준비가 되어있지 않음
이외에도 여러 가지 코드들이 있다
2) 메시지 본문
: 요청 헤더에 포함된 내용을 기반으로 적절한 표현 형식을 선택하여 리소스를 표현한다
주로 JSON 형식의 리소스를 반환한다. ex) { "name" : "Jack" , "age" : 25 }
3) 헤더
: 응답에 대한 헤더 또는 메타데이터를 포함한다. 서버, 인코딩, 날짜 및 콘텐츠 유형과 같은 정보를 포함한다
REST API 인증 방법
: RESTful 웹서비스는 응답을 보내기 전에 먼저 요청을 인증해야 한다. 클라이언트는 서버와의 신뢰를 구축하기 위해 서버에 자신의 신원을 증명해야 한다.
1) HTTP 인증
* 기본 인증
: 클라이언트는 요청 헤더에 사용자 이름과 암호를 넣어 전송한다. 보안을 위해 인코딩하여 보내야 한다.
* 전달자(Bearer) 인증
: 토큰 전달자에 대한 액세스 제어를 제공하는 프로세스이다. 일반적으로 전달자 토큰은 서버가 로그인 요청에 대한 응답으로 생성하는 암호화된 문자열로 주로 JWT(Json Web Token)을 사용하여 구현한다. 클라이언트는 해당 토큰을 요청 헤더에 넣어 전송한다
2) API 키
: API 키는 REST API 인증을 위한 또 다른 옵션으로 이 접근 방식에서 서버는 고유하게 생성된 값을 최초 클라이언트에 할당한다. 클라이언트는 리소스에 액세스하려고 할 때마다 고유한 API 키를 사용하여 본인을 검증한다. API 키의 경우 클라이언트가 이 키를 전송해야 해서 네트워크 도난에 취약하기 때문에 덜 안전하다.
3) OAuth
: OAuth는 모든 시스템에 대해 안전한 로그인 액세스를 보장하기 위해 암호와 토큰을 결합한다. 서버는 먼저 암호를 요청한 다음 권한 부여 프로세스를 완료하기 위해 추가 토큰을 요청한다. 특정 범위와 수명으로 언제든지 토큰을 확인할 수 있다.
▼▼▼▼▼프엔/백엔 분리에 대해 읽어볼만한 글▼▼▼▼▼
https://okky.kr/questions/538253
OKKY - REST API로 백엔드를 분리한다는 이야기는......!?
백엔드를 REST API로 구축하고 (스프링 부트)프론트엔드를 별도로 만들면,포트가 2개가 되는건가요? 프론트엔드는 WebServer로만 띄운다고 알고 있고,백엔드는 WebServer + WAS로 구성된다고 알고 있습니
okky.kr
'Programming > 웹(Web)' 카테고리의 다른 글
웹의 동작 원리(feat.인터넷 주소창에 www.google.com을 치면 어떤 동작 과정이 일어날까?) (0) 2022.09.23 컴파일,빌드,배포의 개념과 자동화 (0) 2022.07.25 HTTP(Hypertext Transfer Protocol)란 무엇인가 (0) 2022.03.10 댓글