본문 바로가기

Spring Boot/스프링 부트 핵심 가이드

[SpringBoot] 2.4-5 디자인 패턴, REST API

> Summary 
디자인 패턴 : 반복되는 유사한 문제에 대한 해결법을 패턴화 한 것
REST API : REST 구조(URI, HTTP method, JSON)로 데이터를 교환할 수 있게 설계된 API

🔍 목차


02 개발에 앞서 알면 좋은 기초 지식
     2.4 디자인 패턴
     2.5 REST API

💡 2.4 디자인 패턴


  • 애플리케이션 개발에서는 비슷한 문제들이 발생하고, 해결책도 유사한 경우가 많음 -> 패턴화 가능
  • 디자인 패턴는 이런 '유사하면서 반복적으로 일어나는' 문제들을 해결하기 위해 고안된 해결책
  • 상황에 맞는 최적의 디자인 패턴을 결정해서 사용하는 것이 바람직함
  • 디자인 패턴은 우리가 자주 사용하는 라이브러리에도 다양하게 쓰이고 있음

📌 2.4.1 디자인 패턴의 종류


  • 디자인 패턴의 대표적인 분류 방식 : GoF 디자인 패턴 (GoF 자체는 별 의미 없음)
  • 생성 패턴, 구조 패턴, 행위 패턴의 총 세 가지로 구분함
  • 생성 패턴 : 객체 생성에 사용되는 패턴 / 객체를 수정해도 호출부가 영향을 받지 않게 함
  • 구조 패턴 : 객체를 조합해서 더 큰 구조를 만드는 패턴
  • 행위 패턴 : 객체 간의 알고리즘이나 책임 분배에 관한 패턴
    / 객체 하나로는 수행할 수 없는 작업을 여러 객체로 분배하는 패턴

📌 2.4.2 생성 패턴 - 객체 생성에 사용되는 패턴


  • 추상 팩토리 : 구체적인 클래스를 지정하지 않고 상황에 맞는 객체를 생성하기 위한 인터페이스를 제공하는 패턴
  • 빌더 : 객체의 생성과 표현을 분리해 객체를 생성하는 패턴
  • 팩토리 메서드 : 객체 생성을 서브클래스로 분리해서 위임하는 패턴
  • 프로토타입 : 원본 객체를 복사해 객체를 생성하는 패턴
  • 싱글톤 : 한 클래스마다 인스턴스를 하나만 생성해서 인스턴스가 하나임을 보장하고 어느 곳에서도 접근할 수 있게 제공하는 패턴

📌 2.4.3 구조 패턴 - 객체를 조합해서 더 큰 구조를 만드는 패턴


  • 어댑터 : 클래스의 인터페이스를 의도하는 인터페이스로 변환하는 패턴
  • 브리지 : 추상화와 구현을 분리해서 각각 독립적으로 변형케 하는 패턴
  • 컴포지트 : 여러 객체로 구성된 복합 객체와 단일 객체를 클라이언트에서 구별 없이 다루는 패턴
  • 데코레이터 : 객체의 결합을 통해 기능을 동적으로 유연하게 확장할 수 있게 하는 패턴
  • 퍼사드 : 서브시스템의 인터페이스 집합들에 하나의 통합된 인터페이스를 제공하는 패턴
  • 플라이웨이트 : 특정 클래스의 인스턴스 한 개를 가지고 여러 개의 '가상 인스턴스'를 제공할 때 사용하는 패턴
  • 프락시 : 특정 객체를 직접 참조하지 않고 해당 객체를 대행(프락시)하는 객체를 통해 접근하는 패턴

📌 2.4.4 행위 패턴 - 객체 간의 알고리즘이나 책임 분배에 관한 패턴


  • 책임 연쇄 : 요청 처리 객체를 집합으로 만들어 결합을 느슨하게 만드는 패턴
  • 커맨드 : 실행될 기능을 캡슐화해서 주어진 여러 기능을 실행하도록 클래스를 설계하는 패턴
  • 인터프리터 : 주어진 언어의 문법을 위한 표현 수단을 정의하고 해당 언어로 구성된 문장을 해석하는 패턴
  • 이터레이터 : 내부 구조를 노출하지 않으면서 해당 객체의 집합 원소에 순차적으로 접근하는 방법을 제공하는 패턴
  • 미디에이터 : 한 집합에 속한 객체들의 상호작용을 캡슐화하는 객체를 정의한 패턴
  • 메멘토 : 객체의 상태 정보를 저장하고 필요에 따라 상태를 복원하는 패턴
  • 옵저버  : 객체의 상태 변화를 관찰하는 관찰자들, 즉 옵저버 목록을 객체에 등록해 
    상태가 변할 때마다 메서드 등을 통해 객체가 직접 옵저버에게 통지하게 하는 디자인 패턴
  • 스테이트 : 상태에 따라 객체가 행동을 변경하게 하는 패턴
  • 스트래티지 : 행동을 클래스로 캡슐화해서 동적으로 행동을 바꿀 수 있게 하는 패턴
  • 비지터 : 실제 로직을 가지고 있는 객체(visitor)가 로직을 적용할 객체(element)를 방문하며 실행하는 패턴
  • 템플릿 메서드 : 일정 작업을 처리하는 부분을 서브클래스로 캡슐화해서 전체 수행 구조는 바꾸지 않으면서 특정 단계만 변경해서 수행하는 패턴

💡 2.5 REST API


📌 2.5.1 REST 란?


  • 'Representational State Transfer'의 약자
  • HTTP를 잘 사용하기 위한 아키텍쳐 스타일
  • REST는 자원 / 행위 / 메세지로 구성됨
  • 각각 자원 - URI / 행위 - HTTP 메소드 / 메서지 - JSON 에 대응됨
  • URI를 통해 어떤 자원에 접근할 것인지를 나타내고, 
    HTTP 메소드로 어떤 행위를 할 것인지 나타내고,
    JSON으로 자원에 대한 추가 정보를 전달함
  • REST의 원칙을 지키면서 API의 의미를 표현하고 쉽고, 파악하기 쉽게 하는것을 Restful하다고 함

📌 2.5.2 REST API 란?


  • REST 구조의 데이터를 상호 교환할 수 있게 설계된 API
  • cf. API는 'Application Programming Interface'의 약자로, 애플리케이션에서 제공하는 인터페이스를 의미함
  • API를 통해 서버 또는 프로그램 사이를 연결할 수 있음
    => REST API로 통신 가능

📌 2.5.3 REST 의 특징


  • 유니폼 인터페이스
    유니폼 인터페이스란 '일관된 인터페이스'를 의미함
    REST 서버는 HTTP 표준 전송 규약을 따르기 때문에
    프로그래밍 언어 / 플랫폼 / 기술에 종속되지 않고 호환될 수 있음
  • 무상태성 (stateless)
    무상태성이란, 서버에 상태 정보를 따로 보관하거나 관리하지 않는다는 것
    즉, 서버는 클라이언트가 보낸 요청에 대해 세션 or 쿠키 정보를 별도 보관하지 않음
    때문에 한 클라이언트가 여러 요청을 보내든 여러 클라이언트가 각각 하나의 요청을 보내든 동일하게 처리할 수 있음
    무상태성의 장점 : 서버가 불필요한 정보를 관리하지 않으므로 비즈니스 로직의 자유도가 높고 설계가 단순함
    클라이언트가 서버에 종속적이지 않으므로, scale out한 상황에서도 용이함
  • 캐시 가능성
    REST는 HTTP 표준을 그대로 사용하므로 HTTP의 캐싱 기능을 적용할 수 있음
    이 기능을 이용하기 위해서는 응답과 요청이 모두 캐싱 가능한지(Cacheable) 명시 필요
    캐싱이 가능한 경우 클라이언트의 캐시에 저장해두고 같은 요청에 대해 클라이언트에 저장한 캐시 데이터를 사용
    => 서버의 트랜잭션 부하가 줄어 효율적이며 사용자 입장에서 성능이 개선됨
  • 레이어 시스템
    REST 서버는 네트워크 상의 여러 계층으로 구성될 수 있지만,
    서버의 복잡도와 관계없이 클라이언트는 서버와 연결되는 포인트만 알면 되므로 간편
  • 클라이언트-서버 아키텍처
    REST 서버는 API를 제공하고 클라이언트는 사용자 정보를 관리하는 구조로 분리해 설계할 수 있음
    이 구성은 서로에 대한 의존성을 낮추게 함

📌 2.5.4 REST의 URI 설계 규칙 


  • URI의 마지막에는 '/'를 포함하지 않는다.
    옳은 예) http://localhost.com/product
    잘못된 예) http://localhost.com/product//
  • 언더바는 사용하지 않는다. 대신 하이픈(-)을 이용한다.
    옳은 예) http://localhost.com/provider-company-name 
    잘못된 예) http://localhost.com/provider_company_name
  • URL에는 동사가 아닌 명사를 사용한다.
    URL은 자원의 개념이므로 명사를 써야 한다. 행위는 HTTP 메서드로 나타낼 수 있어야 한다.
    옳은 예) http://localhost.com/product/123
    잘못된 예) http://localhost.com/delete-product/123
  • URI는 소문자로 작성한다.
    URI 리소스 경로에는 대문자 사용을 피하는 것이 좋다.
  • 파일의 확장자는 URI에 포함하지 않는다.
    HTTP에서 제공하는 Accept 헤더를 사용하는 것이 좋다.
    옳은 예) http://localhost.com
    잘못된 예) http://localhost.com/index.html

  •  cf. HTTP 헤더의 Content-Type과 Accept의 차이점 
    둘 다 데이터 타입을 다루는 헤더이지만, 용도가 다르다.
    Content-Type : 현재 전송하는 데이터가 어떤 타입인지에 대한 설명 (클라이언트 ↔ 서버 양방향에 적용)
    Accept : 클라이언트 → 서버로 데이터를 전송할 때 사용 / 서버에게 '나는 이런 타입만 받을 수 있다'를 말해줌

  • cf. URI와 URL의 차이점
    URI는 Identifier(식별자)이고, URL은 Location(정확한 위치)이다.
    예를들어 '씨에씨에 마라탕'은 URI이고, '인천시 미추홀구 인주대로 4번길 10 1층 씨에씨에 마라탕'은 URL이다.
    yonsodev.tistory.com은 URI이고, https://yonsodev.tistory.com 는 URL이다.

 

 

※ 이 글은 [스프링   부트 핵심 가이드] 책의 내용을 정리한 글입니다. ※