leehyeon-dv 님의 블로그

RESTful 웹 서비스 구축 본문

spring/spring Boot

RESTful 웹 서비스 구축

leehyeon-dv 2024. 11. 21. 23:24

이 가이드에서는 spring을 사용하여 "Hello, World" RESTful 웹 서비스를 만드는 과정을 안내합니다

 

🔑Table of Contents

  1. 모델생성
  2. 인사말 나타내는 자바 클래스 생성
  3. 리소스 컨트롤러 생성
  4. 서비스 실행
  5. 빌드시작
  6. 스프링부트 RESTful 서비스를 테스트하는 방법
  7. 궁금한점

HTTP GET요청을 수락하는 서비스를 빌드합니다

http://localhost:8080/greeting

 

📌 1. 모델생성

목표 = 아래 response 응답받기

{
    "id" : 1,
    "content": "Hello, World!"
}
  • id : 식별 값으로, 요청 시 자동 증가
  • content : "Hello, {{ name }}!" 텍스트 반환 (default : Hello, wolrd!)

📌 2. 인사말 나타내는 자바 클래스 생성

package com.example.demo;

public record Greeting(long id, String content) { }
  • 레코드 구조 
    • 레코드는 클래스를 간결하게 표현해 생성자, getter, toString, equals, hashCode등을 자동으로 제공한다
    • 위에서는 id와 content라는 두개의 필드가 생성된다
    • *주의* 자바 14이상에서 사용가능하다
    • 이 애플리케이션은 jackson JSON 라이브러리를 사용해 자동으로 type인스턴스를 Greeting JSON으로 마샬링함

📌 3.리소스 컨트롤러 생성

RESTful 웹 서비스를 구축하는 Spring의 접근방식에서 HTTP요청은 컨트롤러에 의해 처리됩니다. 

이러한 구성요소는 @RestController 주석으로 식별되고 @GreetingController 클래스의 새 인스턴스를 반환해 get요청을 처리한다

package com.example.restservice;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

	private static final String template = "Hello, %s!";
	private final AtomicLong counter = new AtomicLong();

	@GetMapping("/greeting")
	public Greeting greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
		return new Greeting(counter.incrementAndGet(), String.format(template, name));
	}
}
  • @RequestParam 
    • HTTP 요청의 쿼리 문자열에 포함된 매개변수를 메서드의 파라미터로 바인딩
      • 예: 클라이언트가 /greeting?name=Alice로 요청을 보내면 nameAlice가 바인딩됨
      • defaultValue 속성을 사용하면 쿼리 매개변수가 없는 경우 기본값이 사용됩니다
        • /greeting 요청 시 name의 기본값 "World"가 사용됩니다
  • Greeting 객체생성
    • 요청이 들어오면 다음을 기반으로 Greeting 객체가 생성
      • id : 요청마다 고유한 식별값(AtomicLong을 사용하여 증가)
      • content : 템플릿(template)에 name값을 삽입해 포맷된 문자열
        • 예 : 템플릿 "Hello, %s!"name = "Alice"를 삽입하면 "Hello, Alice!"가 된다
    • 생성된 Greeting 객체는 JSON으로 변환해 응답 본문에 포함된다

📌 4. 서비스 실행

Spring Initializr는 사용자를 위해 애플리케이션 클래스를 생성한다. 이경우 클래스를 더 수정할 필요가 없다

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

 

  • @SpringBootApplication : 스프링 부트에서 제공하는 편리한 어노테이션으로, 다음 세가지 기능을 결합한다
    • @Configuration : 클래스를 spring의 구성클래스로 표시한다, 이 클래스에서 정의된 Bean들이 애플리케이션 전반에서 사용된다
    • @EnableAutoConfiguration 
      • 스프링부트의 자동 구성을 활성화
      • 스프링 부트는 클래스 경로에 존재하는 설정과 라이브러리에 따라 자동으로 Bean을 생성하고 설정을 추가함
      • 예를들어 클래스경로에 spring-webmvc있으면
        • 애플리케이션이 자동으로 웹 애플리케이션으로 설정됨
        • DispatcherServlet이 설정되고, 웹 애플리케이션에 필요한 기본 설정이 추가된다
    • @ComponentScan
      • 지정된 패키지에서 spring의 컴포넌트(Bean)을 검색한다
      • 스프링은 @Component, @Service, @Repository, @Controller로 표시된 클래스를 찾아 자동으로 스프링 Context에 등록한다
      • 기본적으로 @SpringBootApplication이선언된 클래스의 패키지와 그 하위 패키지에서 검색한다

Spring Boot의 main() 메서드

  • spring 부트의 애플리케이션의 main() 메서드는 springApplication.run()을 호출하여 애플리케이션을 실행한다
  • 스프링 애플리케이션 컨텍스트를 초기화하고 내장된 웹서버를 시작해 애플리케이션이 요청을 처리할 준비를 한다
  • XML 파일을 사용하지 않는다

실행가능한 JAR파일 생성

  • 스프링 부트 애플리케이션은 하나의 실행가능한 JAR파일로 패키징할 수 있다
  • 애플리케이션을 쉽게 배포가 가능하고 다양한 환경에서 실행가능하다
    • 이 JAR파일에는 애플리케이션의 모든 의존성, 클래스, 리소스가 포함된다
    • 단일 파일로 실행할 수 있어 배포 및 버전관리가 간단해진다

5. 빌드 시작

실행버튼을 누르면 

빌드 성공!

 

6. 스프링 부트 RESTful 서비스를 테스트하는 방법

  • 테스트 준비
    • 서비스가 정상적으로 실행 중이어야 한다 (http://localhost:8080 에서 서버가 실행됨)
    • 기본요청 : Postman , curl 등 HTTP 클라이언트를 사용하여 다른 URL에 접근 : 

  • 테스트 _ 쿼리 매개변수 사용
    • URL에 name 매개변수를 추가해 요청 : http://localhost:8080/greeting?name=User
    • 결과(다음과 같은 JSON응답을 받는다) 
      • id : 2
      • content : Hello, User!

📍?<궁금한점>📍

🔎AtomicLong역할

  • java.util.concurrent.atomic.AtomicLong클래스는 동시성환경에서 long값을 안전하게 업데이트할 수 있는 기능을 제공
  • 일반적인 long타입변수는 여러 스레드에서 동시에 값을 변경하면 데이터 불일치 문제가 발생할 수 있지만, atomicLong은 이를 방지한다
  • 내부적으로 CAS알고리즘을 사용해 값을 원자적으로 업데이트한다
  • HTTP 요청이 들어올때마다 atomicLong의 값을 증가시키며 고유한 id를 생성한다
  • 요청이 동시에 발생해도 각 요청마다 중복되지 않는 고유한 값이 보장된다
  • 메서드
    • incrementAndGet() : 값을  1 증가시킨 뒤, 증가된 값 반환
    • getAndIncrement() : 현재값을 반환한 뒤 증가
    • addAndGet(long delta) : 지정한 값만큼 더하고 결과 반환
    • compareAndSet(long expect, long update) : 현재값이 기대값과 다를때만 새로운 값으로 설정

🔎 JSON 변환의 자동처리

  • Spring Boot는 요청이나 응답 데이터를 JSON형식으로 자동변환한다
  • 이를 위해 Jackson2 라이브러리를 사용한다
    • 클래스 경로에 jackson 라이브러리가 있으면 Spring이 이를 감지하고 객체를 JSON으로 변환한다
    • MappingJackson2HttpMessageConverter를 통해 변환이 이루어진다
    • 예 : Greeting객체 → JSON
  • 개발자는 객체를 반환하기만 하면되고, 별도로 JSON 변환 코드를 작성할 필요가 없습니다

🔎MVC 컨트롤러와 RESTful 컨트롤러의 차이점

    기존 MVC 컨트롤러

  • 서버에서 HTML 뷰를 생성하여 클라이언트에게 반환한다
  • HTML을 사용해 UI를 생성하는 것이 목적이다
    • RESTful 웹 서비스 컨트롤러
      • 데이터를 객체(JSON) 형태로 반환한다
      • UI 대신 클라이언트가 데이터를 처리할 수 있도록 설계
      • @RestController @Controller @ResponseBody의 약어로, JSON 데이터를 HTTP 응답 본문으로 반환한다

'spring > spring Boot' 카테고리의 다른 글

스프링 환경 갖추기  (0) 2024.12.18
RESTful 웹 서비스 사용  (0) 2024.11.25
스프링 시작!  (2) 2024.11.15