본문 바로가기
2021 웹개발 101

[Spring Boot] 레이어드 아키텍처, REST API

by Senna 2021. 12. 7.

0. 백엔드 서비스 아키텍처

- 레이어드 아키텍처 패턴: 스프링 프로젝트 내부에서 어떻게 코드를 적절히 분리하고 관리할 것이냐에 대한 것이다.

- REST 아키텍처 스타일: 클라이언트(브라우저)가 우리 서비스를 이용하려면 어떤 형식으로 요청을 보내고 응답을 받는지에 대한 것이다. ==>REST 아키텍서 스타일을 따라 구현된 서비스를 RESTful 서비스라고 한다.

- 스프링은 레이어드 아키텍처 패턴이 REST 아키텍처 스타일을 이용하는 데 도움을 주는 '어노테이션'을 제공한다. 

 

그림판으로 그렸다 ... 

1. 레이어드 아키텍처 (Layered Architecture)

- 레이어드 아키텍처 패턴은 애플리케이션을 구성하는 요소들을 수평으로 나눠 관리하는것이다.

 ==> ex) 한 메소드 안에 요청검사/데이터베이스 콜/응답 생성 을 모두 넣는 것이 아니라,

      메소드를 쪼개서... 아니? 이것 또한 필요한 곳 마다 메소드를 복-붙 해야하므로,

      각 요소를 메소드가 아닌 클래스로 만들고, 계층을 만들어서.. 하나의 컨트롤러에만 요청하게 하는 것..

- 여러 레이어로 나누는 것 + 레이어 사이에 계층이 있음

- 레이어는 자기보다 한 단계 하위의 레이어만 사용한다. 

 ==> ex) 부장이 고객의 요청을 받고 차장을 쫀다. 차장은 과장을 쪼고, 과장은 대리를, 대리는 사원을 쫀다. 

       사원은 대리에게 결과물을 보고한다. 대리는 과장에게, 과장은 차장에게, 차장은 부장에게 결과물을 검토하거나 가공한 후 보고한다. 

 ==> ex2) 컨트롤러가 요청을 받는다. 컨트롤러는 서비스를 쪼고, 서비스는 퍼시스턴스를 쫀다. 

       퍼시스턴스는 요청한 데이터를 반환한다. 서비스는 데이터를 검토 및 가공한 후 컨트롤러에게 반환한다.

       컨트롤러 또한 데이터를 검토 및 가공한 후 응답을 반환한다.

 

1.2. 모델, 엔티티, DTO

 - 보통 자바로 된 비즈니스 애플리케이션의 클래스는 두가지 종류로 나눌 수 있다. 천번째는 일을 하는 클래스, 즉 기능을 수행하는 클래스이고, 두번째는 데이터를 담는 클래스다.

    1) 일을 하는 클래스: Controller, Service, Persistence 등, 로직을 수행한다

    2) 데이터를 담는 클래스: DTO, Model, Entity 등

- Entity: DB의 테이블과 스키마를 표현하고 데이터를 담기 위한 클래스

- Model: 비즈니스 데이터를 담는 역할

- DTO(Data Transfer Object): Service가 요청을 처리하고 클라이언트로 반환할 때 Model 자체를 그대로 리턴하는 경우는 별로 없다. 보통은 데이터를 전달하는 데 사용하는 오브젝트인 DTO로 변환해 리턴한다. 변환하여 리턴하는 이유는

    1) 비즈니스 로직을 캡슐화 할 수 있어서. Model의 경우 DB 테이블 구조와 매우 유사하므로 외부인이 자사의 DB 스키마를 아는 것을 원치 않기 때문이다. 

    2) 보통 Model이 클라이언트가 요구하는 정보를 전부 포함하지 않는 경우가 많기 때문이다. 예시로는 에러 메시지가 있다. 에러 메시지는 모델에 담기 애매하므로 DTO에 에러 메시지 필드를 선언하고 거기에 포함시키면 된다. 

 

 

2. REST API

 - REST: Representational State Transfer 아키텍처 스타일 

     * 아키텍처 스타일(반복되는 아키텍처 디자인)과 아키텍처 패턴(어떤 반복되는 문제 상황을 해결하는 도구)는 다르다.

 - REST 제약조건

    1) 클라이언트-서버 (Client-Server): 리소스를 관리하는 서버가 존재하고, 다수의 클라이언트가 리소스를 소비하려고 네트워크를 통해 서버에 접근하는 구조

    2) 상태가 없음 (Stateless): 클라이언트가 서버에 요청을 보낼 때 이전 요청의 영향을 받지 않는 것.

      ex) /login으로 로그인 요청을 보내고 로그인 성공 후 /page로 넘어갔을 때, 서버가 이전 요청에서 login한 사실을 알고있어야 한다면 그것은 상태가 있는(Stateful) 아키텍처이다.

      ==> HTTP는 기본적으로 상태가 없는 프로토콜이다. 따라서 HTTP를 사용하는 웹 애플리케이션도 기본적으로 상태가 없는 구조를 따른다.

    3) 캐시되는 데이터 (Cacheable Data): 서버에서 리소스를 리턴할 때 캐시가 가능한지 아닌지 명시할 수 있어야 한다. HTTP에서는 cache-control이라는 헤더에 리소스의 캐시 여부를 명시할 수 있다.

    4) 일관적인 인터페이스(Uniform Interface): 시스템 또는 애플리케이션의 리소스에 접근할 때 인터페이스가 일관적이어야 한다는 뜻. 리소스 접근방식/요청 형식/응답 형식(URI) 등이 애플리케이션 전반에 걸쳐서 일관적이어야 한다.

      ex) zzx.com/todo 가 데이터를 가져오고, zzx2.com/todo 가 업데이트라면 일관적이지 않은 인터페이스이다.

      ex2) zzx.com/todo 가 JSON형식 리소스를 리턴하고 zzx.com/account 가 HTML을 리턴하면 리턴타입에서 일관성이 없다.

    5) 레이어 시스템 (Layered System): 클라이언트가 서버에 요청을 할 때 여러개의 레이어로 된 서버를 거칠 수 있다. 예를 들어 서버가 인증 서버, 캐싱 서버, 로드 밸런서를 거쳐서 최종적으로 애플리케이션에 도착한다고 가정하면, 이 사이의 레이어들은 요청과 응답에 어떤 영향을 미치지 않으며, 클라이언트는 서버의 존재 유무를 알지 못해야 한다.

    6) 코드-온-디맨드 (Code-On-Demand): 선택사항... 

 *** REST는 HTTP와 다르다.

     REST는 HTTP를 이용해 구현하기 쉽고 대부분 그렇게 구현하지만, 엄밀히 말하면 REST는 아키텍처이고, HTTP는 REST 아키텍처를 구현할 때 사용하면 쉬운 프로토콜이다.