이 글은 https://spring.io/guides/gs/rest-service/ 를 따라하며 스프링으로 RESTful 웹 서비스를 만드는 과정을 보여줄 것이다.
01. 우리가 만들 것은?
http://localhost:8080/greeting
에서 HTTP GET 요청을 받는 서비스를 만들 것이다. 이 요청에 대해 JSON 형식으로 다음과 같은 응답을 반환할 것이다.
{ "id" : 1, "content" : "Hello, World!" }
아래와 같이 쿼리 스트링에 있는 선택적 파라미터인 name
으로 커스터마이징 할 수 있다.
http://localhost:8080/greeting?name=User
name
의 값은 기본값인 World
를 오버라이딩하고, 아래와 같이 응답에 반영된다.
{ "id" : 1, "content", "Hello, User!" }
02. Spring Initializr 로 시작하기
1. https://start.spring.io/에 접속한다. 이 서비스는 애플리케이션을 위한 모든 의존성을 주입하고, 대부분의 세팅을 자동으로 해준다.
2. Gradle 혹은 Maven을 선택하고 사용하기 원하는 언어를 선택한다. 이 가이드는 Java를 선택하기를 권장한다.
3. Dependencies에 Spring Web을 추가한다.
4. Generate를 클릭한다.
5. ZIP 파일을 다운로드 받는다.
나는 다음과 같이 선택 및 작성했다.
- Project : Gradle - Groovy
- Spring Boot : 3.2.1
- Project Metadata
- Group : com.example
- Artifact : rest-service
- Name : rest-service
- Description : https://spring.io/guides/gs/rest-service/
- Package name : com.example.rest-service
- Packaging : Jar
- Java : 17
- Dependencies : Spring Web
03. 리소스를 표현하는 클래스 생성
서비스의 상호작용을 생각하며 과정을 시작하자.
서비스는 선택적으로 쿼리 문자열의 매개변수를 사용하여 GET
에 대한 요청을 처리한다. GET
요청은 body에 인사말을 나타내는 JSON 형식과 함께 200 OK
응답을 반환해야 한다. 다음과 같은 결과와 유사할 것이다.
{
"id" : 1,
"content" : "Hello, World!"
}
id
필드는 인사말에 대한 고유한 식별자이다. content
는 익사말의 텍스트적 표현이다.
인사말 표현을 모델링 하기 위해서, 리소스를 표현하는 클래스를 만들자. Greeting 레코드를 생성하고 아래와 같이 작성한다. (Greeting 레코드의 경로는 다음과 같다. src/main/java/com/example/restservice/Greeting.java
)
package com.example.restservice;
public record Greeting(long id, String content) { }
04. 리소스 컨트롤러 생성하기
RESTful 웹 서비스를 구축하는데에 스프링의 접근에서, HTTP 요청은 controller에 의해 처리된다. 이 요소들은 @RestController
어노테이션에 의해 식별된다. GreetingController
는 greeting
에 대한 GET
요청을 새로운 Greeting
클래스를 반환하여 처리한다.
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));
}
}
이 Controller는 간결하고 단순해 보이지만 그 내부에는 많은 일들이 발생하고 있다. 하나씩 살펴보면 다음과 같다.
1. @GetMapping
이 어노테이션은 HTTP GET 요청이 greeting
에 매핑되게 한다.
@GetMapping
은 @RequestMapping(method=GET)
와 동일하다.
2. @RequestParam
쿼리 스트링 매개변수의 값인 name
을 greeting()
메소드의 파라미터인 name
에 바인딩 한다. 만약 name
파라미터가 요청에 없다면, defaultValue
로 지정된 World
가 사용된다.
3. @RestController
이 코드에서, 스프링의 @RestController
어노테이션을 사용한다.
이 어노테이션은 클래스를 모든 메소드가 view 대신에 도메인 객체를 반환하는 컨트롤러임을 나타낸다.
@Controller
와 @ResponseBody
를 모두 포함하는 약어이다.
4. 그 외
메소드 body의 구현체는 id
와 content
속성들과 함께 새로운 Greeting
객체를 생성하고 반환한다.
전통적인 MVC 컨트롤러와 초기의 RESTful 웹 서비스 컨트롤러의 그장 큰 차이점은, HTTP response body가 생성되는 방식이다. 의존HTML에 인사말 데이터를 서버측에서 렌더링을 하고 보여주는 view 기술에 의존 하기보다,이 RESTful 웹 서비스 컨트롤러는 Greeting
객체를 채우고 반환한다. 이 객체 데이터는 HTTP 응답에 JSON 형태로 바로 작성될 것이다.
Greeting
객체는 반드시 JSON 형태로 변환되어야 한다. 하지만 스프링의 HTTP 메세지 변환의 지원 덕분에, 이러한 변환을 수동으로 할 필요는 없다. 왜냐하면 Jackson2 가 classpath에 있기 때문이다. 스프링의 MappingJackson2HttpMessageConverter
는 자동으로 Greeting
인스턴스를 JSON으로 변환되게 한다.
05. 서비스 실행하기
Spring Initializr 가 애플리케이션을 생성했으므로 더 이상 클래스를 수정할 필요가 없다. 아래 클래스와 같이 작성되어 있을 것이고, 이를 실행하면 된다.
package com.example.restservice;
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
: 애플리케이션 컨텍스트에 대한 Bean을 정의하는 소스로 클래스에 정의된다.@EnableAutoConfiguration
: 클래스 경로 설정, 기타 Bean 등 다양한 속성 설정을 기반으로 Bean 추가를 시작하도록 SpringBoot에 전달한다.@ComponentScan
: Spring 에게com/example
패키지 내의 다른 컴포넌트, 설정, 서비스를 찾도록 지시하고 컨트롤러를 찾도록 한다.
main()
메소드는 애플리케이션을 시작하기 위해 SpringBoot의 SpringApplication.run()
메소드를 사용한다. 여기에는 어떠한 XML 파일도 필요하지 않았다. web.xml
파일도 당연히 없었다. 이 웹 애플리케이션은 100% 순수한 Java로 이루어졌고, 인프라 구성에 대해 생각하지 않아도 된다.
06. 실행 가능한 JAR 파일 빌드 후 실행
터미널에서 애플리케이션을 실행할 수 있다. 필요한 모든 종속성, 클래스, 리소스가 포함된 단일 실행이 가능한 JAR 파일을 빌드하고 실행할 수도 있다. 실행 가능한 JAR 파일을 만들면 다양한 환경에서 서비스를 애플리케이션으로 쉽게 제공할 수 있고, 버전 지정 및 배포 또한 가능하다. Gradle을 사용하는 경우 빌드 후 다음과 같이 실행할 수 있다.
java -jar build/libs/rest-service-0.0.1-SNAPSHOT.jar
07. 서비스 테스트하기
http://localhost:8080/greeting
에 접속하면 다음과 같은 것을 볼 수 있다.
{"id":1, "content":"Hello, World!"}
name
쿼리 스트링을 추가해보자. http://localhost:8080/greeting?name=User
에 접속하면 된다. Hello, World!
가 Hello, User!
로 변경된 것을 볼 수 있다.
확인 결과 @RequestParam
이 예상대로 잘 작동하고 있음을 볼 수 있다. 매개변수 name
은 기본값이 지정되어 있지만 쿼리 문자열을 통해 명시적으로 재정의 될 수 있다. 또한, id
값이 변경된 것도 확인할 수 있다. 여러 요청에서 동일한 인스턴스에 대해 작업하고 있음을 알 수 있다.
'SpringBoot' 카테고리의 다른 글
SpringBoot CORS 설정 (0) | 2024.04.06 |
---|---|
스프링 부트는 무엇인가? (0) | 2023.12.29 |