[코드 1-1]

@SpringBootApplication
public class CoffeeApplication {

    public static void main(String[] args) {
        SpringApplication.run(CoffeeApplication.class, args);
    }

}

[코드 1-1]과 같이 Spring Boot Application 클래스에 @SpringBootApplication 애너테이션을 추가하면 기본적으로 해당 애플리케이션이 Spring Boot 기반의 애플리케이션으로 동작하도록 해줍니다.

 

그렇다면 @SpringBootApplication 은 내부적으로 어떤 기능을 하는 걸까요?

@SpringBootApplication 은 다음과 같은 세 가지 기능을 활성화 하는데 사용됩니다.

  • @EnableAutoConfiguration
    • Spring Boot의 자동 구성 메카니즘을 활성화합니다.
  • @ComponentScan
    • 애플리케이션 내의 패키지에서 @Component 애너테이션이 붙은 클래스들에 대한 스캐닝을 활성화합니다.
  • @SpringBootConfiguration
    • Spring Context에 Bean을 추가적으로 등록하거나 Configuration 클래스를 추가적으로 임포트 하는 기능을 활성화합니다.
    • Spring Boot의 @*Test 애너테이션을 사용해서 테스트를 진행할 경우,  자동으로 @SpringBootConfiguration을 검색합니다.

 

@SpringBootApplication 을 무조건 붙여야 하는것은 아니며, [코드 1-2]와 @SpringBootApplication 이 지원하는 세 가지 기능을 개별적으로 적용할 수 있습니다.

[코드 1-2]

@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ CoffeeConfiguration.class, MemberConfiguration.class })
public class CoffeeApplication {

    public static void main(String[] args) {
        SpringApplication.run(CoffeeApplication.class, args);
    }

}

 

REST API란?

REST(Representational State Transfer)는 HTTP 네트워크 상의 리소스(Resource, 자원)를 정의하고 해당 리소스를 URI라는 고유한 주소로 접근하는 접근 방식을 의미하며, REST API란 REST 방식을 통해서 리소스에 접근하기 위한 서비스 API를 지칭합니다.

 

REST에서 의미하는 리소스란?

REST에서 의미하는 자원은 데이터베이스에 저장된 데이터, 문서, 이미지, 동영상 등 HTTP 통신을 통해 주고 받을 수 있는 모든 것을 의미합니다.

 

URI(Uniform Resource Identifier)와 URL(Uniform Resource Locator)

URI는 네트워크 상에 있는 특정 리소스를 식별하는 통합 자원 식별자(Uniform Resource Identifier)를 의미합니다.

URL은 인터넷에 있는 리소스를 나타내는 통합 리소스 식별자를 의미하며, 우리가 흔히들 이야기하는 웹 상의 주소를 의미합니다.

URI는 URL의 상위 개념으로 볼 수 있습니다.

URI는 리소스를 식별하는 식별자 역할을 하고, URL은 리소스의 위치를 가리킵니다. 

예) http://www.itivllage.tistory.com/manage? id = 1

위 예에서 'http://www.itivllage.tistory.com/manage'까지는 리소스의 위치를 가리키는 URL이라고 할 수 있고, 'http://www.itivllage.tistory.com/manage? id = 1'는 리소스를 식별하기 위한 'id = 1'이라는 고유 식별자 붙었으므로 URI라고 할 수 있습니다.

 

REST API URI 작성 규칙

그러면 이번에는 HTTP 상에서 REST API 서비스를 만드는 입장에서 REST API URI를 작성하는 규칙들을 살펴보도록 하겠습니다.

URI 작성 기본 규칙

  • URI의 마지막이 '/'로 끝나지 않아야 합니다.
    • better
      • http://www.itivllage.tistory.com/coffees (ㅇ)
    • worse
      • http://www.itivllage.tistory.com/coffees/ (x)
  • 동사 보다는 명사를 사용합니다.
    • better
      • http://www.itivllage.tistory.com/coffees (ㅇ)
    • worse
      • http://www.itivllage.tistory.com/coffees/update (x) 
  • 단수형 보다는 복수형 명사를 사용합니다.
    • better
      • http://www.itivllage.tistory.com/coffees (ㅇ) 
    • worse
      • http://www.itivllage.tistory.com/coffee (x)
  • URI는 기본 소문자로 사용합니다.
  • 언더스코어( _ ) 대신에 하이픈(-)을 사용합니다.
  • 파일 확장자는 URI에 포함하지 않습니다.

 

 

 

URI에서 리소스 간의 관계를 표현하는 방법

REST API를 작성하다보면 특정 리소스 간의 관계를 URI로 표현해야 할 경우가 굉장히 많습니다.

이해를 위해 예시를 살펴보도록 하겠습니다.

  • 'http://www.itivllage.tistory.com/members'는 전체 회원에 대한 리소스를 의미합니다. 
  • 'http://www.itivllage.tistory.com/members/1'는 1이라는 ID를 가지는 회원에 대한 리소스를 의미합니다.. 
  • 'http://www.itivllage.tistory.com/members/1/orders'는 1이라는 ID를 가지는 회원의 주문에 대한 리소스를 의미합니다. 

 

 

 

더 읽을 거리

 

REST - 위키백과, 우리 모두의 백과사전

대한민국의 힙합 음악가에 대해서는 R-EST 문서를 참고하십시오. REST(Representational State Transfer)는 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이다. 이

ko.wikipedia.org

 

7 Rules for REST API URI Design - DZone Integration

URIs, or Uniform Resource Identifiers, should be designed to be readable and clearly communicate the API resource model. These rules will help you succeed.

dzone.com

 

웹 API 디자인 모범 사례 - Azure Architecture Center

플랫폼 독립성과 서비스 진화를 지원하는 웹 API 설계를 위한 모범 사례를 알아봅니다.

docs.microsoft.com

 

'Java Backend 개발자 되기 > RESTful API' 카테고리의 다른 글

Postman 기본 사용법  (0) 2022.04.18

Handler 용어의 의미

핸들(Handle) 이라고 하면 일반적으로 자동차의 핸들을 제일 먼저 떠올릴 수 있는데, 자동차의 핸들은 운전자가 직접 핸들을 움직이면서 직접적으로 자동차의 주행을 처리하는 역할을 합니다.

Spring MVC에서는 자동차의 핸들과 마찬가지로 클라이언트의 요청을 처리하는 처리자Handler라고 합니다.

그렇다면 Spring MVC에서 Handler는 누구일까요?
Spring MVC에서의 요청 Handler는 바로 여러분들이 작성하는 Controller 클래스를 의미합니다. 그리고 Controller 클래스에 있는 @GetMapping, @PostMapping 같은 애너테이션이 붙어 있는 메서드들을 핸들러 메서드라고 합니다.

HandlerMapping이란 의미는 결국 사용자의 요청과 이 요청을 처리하는 Handler를 매핑해주는 역할을 하는 것입니다.

그렇다면, 사용자의 요청과 Handler 메서드의 매핑은 어떤 기준으로 이루어질까요?
@GetMapping(”/coffee”) 처럼 HTTP Request Method(GET, POST 등)와 Mapping URL을 기준으로 해당 Handler와 매핑이 되는데 Spring 에서는 여러가지 유형의 HandlerMapping 클래스를 제공하고 있습니다.

실무에서는 Spring에서 디폴트로 지정한 ‘RequestMappingHandlerMapping’을 대부분 사용하는데 원한다면 얼마든지 HandlerMapping 전략을 바꿀 수 있습니다. 

 

Adapter의 의미

Java에서 사용하는 클래스나 인터페이스의 이름을 살펴보다 보면 흥미로운 용어들이 많이 나옵니다.
Adapter라는 용어도 그 중에 하나라고 볼 수 있습니다.

우리말로 아답터, 어댑터(Adapter, Adaptor)하면 220V 전압을 110V 전압으로 또는 그 반대로 바꿔주는 어댑터(일명, 돼지코)나 USB 충전기를 떠올릴 수 있습니다.

220V를 5V 전압으로 바꿔주는 USB 충전기 예

 

이처럼 Adapter는 무언가를 다른 형식이나 형태로 바꿔주는 역할을 합니다.

그렇다면 HandlerAdater는 무엇을 바꿔줄까요?

Spring은 객체지향의 설계 원칙을 잘 따르는 아주 유연한 구조를 가지는 프레임워크입니다.
따라서 Spring이 제공하는 Spring MVC에서 지원하는 Handler를 사용해도 되지만 다른 프레임워크의 Handler를 Spring MVC에 통합할 수 있습니다.

이처럼 다른 프레임워크의 핸들러를 Spring MVC에 통합하기 위해서 HandlerAdapter를 사용할 수 있습니다.

 

ViewResolver의 의미

’Resolve’는 무언가를 해석하고, 해결해주다라는 뜻이 있습니다.

ViewResolver는 DispatcherServlet에서 ‘이런 이름을 가진 View를 줘’ 라고 요청하면 DispatcherServlet에서 전달한 View 이름을 해석한 뒤 적절한 View 객체를 리턴해주는 역할을 합니다.

객체 지향 설계 원칙이란?

  • 수많은 사람들이 고민하고 시행착오를 겪으면서 만든 원칙입니다.
  • 좀 더 유지보수하기 쉽고, 유연하고, 확장이 쉬운 소프트웨어를 만들 수 있습니다.
  • 코드 베이스뿐만 아니라 아키텍쳐 설계에 이르기까지 다양하게 적용할 수 있습니다.

 

높은 응집력이란?

  • 비슷한 일을 하는 기능 즉, 하나의 책임에 포함되는 기능들이 잘 뭉쳐있다면 높은 응집력을 가진다고 볼 수 있습니다.
  • 하나의 기능을 변경하는데 여기저기 변경해야 될 곳이 많다면 응집력이 낮다고 볼 수 있습니다.

 

낮은 결합도란?

  • 클래스 간에 의존성이 낮다면 낮은 결합도를 가진다고 볼 수 있습니다.
  • 하나의 클래스를 수정하는데 의존하는 다른 클래스를 모두 수정해야 한다면 결합도가 높다고 할 수 있습니다.

SOLID 원칙

  • SRP, OCP, LSP, ISP, DIP의 첫 글자를 딴것이 SOLID 입니다.

SRP(Single Responsibility Principle, 단일 책임의 원칙)

  • 클래스가 제공하는 기능들은 하나의 책임을 수행하는데 집중해야 한다는 원칙입니다.
  • SRP를 지키지 않는다면?
    • 응집력이 낮아지고, 결합도는 높아집니다.
    • 서로 다른 애플리케이션에 배포될 때 사용하지 않는 기능도 포함됩니다. 즉, 왕따가 발생합니다.
    • 변수 레벨
      • 하나의 속성이 여러 의미를 가지는 경우
    • 메서드 레벨
      • if 문이 많을 경우
  • SRP를 잘 지킨다면?
    • 응집력이 높아지고, 결합도는 낮아집니다.
    • 코드 가독성도 좋아집니다.
    • 테스트 범위도 작아집니다. 즉 유지보수도 편해집니다.
  • AOP는 별도의 부가 기능을 핵심 로직에서 분리했기 때문에 SRP의 원칙을 지킨 방식이라고도 할 수 있습니다.

SRP를 지키는 역할 분리의 예)  Kevin이라는 클래스가 있다면?

  • 남편의 역할
    • 자주 전화해주기
    • 기념일 챙기기
  • 아빠의 역할
    • 놀아주기
    • 씻겨주기
    • 재워주기
    • 먹여주기
    • 책 읽어주기
  • 아들의 역할
    • 건강 체크하기
    • 용돈 주기
    • 안부 전화하기
    • 자주 방문하기
  • 사위의 역할
    • 건강 체크하기
    • 용돈 주기
    • 안부 전화하기
    • 자주 방문하기
  • 친구의 역할
    • 안부 전화하기
    • 술 마시기
    • 고민 들어주기
  • 직원의 역할
    • 출근하기
    • 열심히 일하기
    • 회의하기
    • 퇴근하기

 

OCP(Open Close Principle, 개방폐쇄의 원칙)

  • 확장에는 열려있고(Open), 변경에는 닫혀 있어야 한다(Close)는 원칙입니다.
  • 변하는것과 변하지 않는것을 잘 구분하면 OCP를 지키기 용이합니다. 변하는것은 Open, 변하지 않는 것은 Close에 해당됩니다.
  • 변하지 않는것은 변하는 것의 구현에 의존하지 않고, 인터페이스를 통해 느슨하게 의존하게 만듭니다.
  • 디자인 패턴 중에서 전략패턴의 전략 인터페이스는 OCP의 Open에 해당되고 Context는 OCP의 Close에 해당됩니다.
  • 예)
    • 자동차라는 객체에서 변하지 않는 동작
      • 움직이는 것
    • 자동차 객체에서 변하는 동작
      • 수동 모드, 오토메이션 모드, 크루즈컨트롤 모드

 

LSP(The Liskov Substitution Principle, 리스코브 치환의 원칙)

  • subclass의 객체는 superclass의 참조 변수에 대입해서 superclass의 역할을 수행하는데 문제가 없어야 한다는 원칙입니다.
  • OCP 원칙의 기반이 된다고 생각됩니다.

 

ISP(Interface Segregation Principle, 인터페이스 분리의 원칙)

  • 인터페이스의 단일 책임을 위한 원칙입니다.
  • 즉, 일반적인 하나의 인터페이스를 조금 더 구체적인 인터페이스로 쪼개는것이 낫다는 것입니다.
  • 예)
    • 새의 행동(일반적인 하나의 인터페이스)
    • 날수 있는 행동(구체적인 인터페이스)
    • 울수 있는 행동(구체적인 인터페이스)

 

DIP(Dependency Inversion Principle, 의존성 역전의 원칙)

  • 자주 변경되는 구체 클래스에 의존하지 않고, 추상화(일반화) 된 클래스에 의존하는 것을 의미합니다.
  • 구체 클래스가 추상 클래스에 의존하므로 의존 관계가 역전된 형태입니다.
  • 예)
    • Spring framework의 IOC 컨테이너
      • 직접 객체를 생성하는것이 아니라 프레임워크에서 객체를 제공해줍니다.
    • 느슨한 연결 측면에서의 DIP
      • 추상 클래스에서 구체 클래스의 hook 메서드를 호출하는 것
        • hook 메서드 호출 시, 구체 클래스가 무엇인지 알 필요가 없습니다.
    • 이벤트 드리븐 방식
      • 이벤트 리스너를 등록하고 hook 메서드를 통해 해당 이벤트를 처리합니다.
        • hook 메서드 호훌 시, 구체적인 이벤트 리스너가 무엇인지 알 필요가 없습니다.

+ Recent posts

출처: http://large.tistory.com/23 [Large]