이번 포스팅에서는 RESTful 개념을 활용해 간단한 웹 서비스를 만들어보겠습니다.
실습을 위해선 Spring Tool Suite 4버전과 postman이 필요합니다.
postman은 https://www.getpostman.com에서 다운받으실 수 있습니다.
STS는 https://spring.io/tools 에서 다운받으실 수 있습니다.
REST API 서비스를 제공하기 위한 컨트롤러 클래스를 생성한다.
[ DemoRestController 클래스 생성 ]
@RestController
@RequestMapping("/api")
public class DemoRestController {
- @RestController : 현재 클래스가 REST 컨트롤러로 동작하도록 지정.
- @RequestMapping : 현재 클래스로 동작하는 컨트롤러의 엔드포인트(end point)로 컨트롤러 클래스가 제공하는 서비스의 진입점.
- 여기서는 http://localhost:8080/api 로 시작하는 URL 요청들이 처리 될 클래스임을 지정하고 있음
[ 컨트롤러 메서드 구현 ]
제공하기 원하는 기능을 메서드 단위로 지정해서 구현하면 된다. 각각의 메서드는 HTTP 메서드 중 어떤 메서드 요청을 받아들일지 명시해줘야 한다. 대표적인 메서드는 GET / POST / PUT / DELETE가 있다.
먼저 다음과 같이 GET 요청을 처리하기 위한 메서드를 하나 구현해보자.
@GetMapping("/hello")
public String hello(@RequestParam(value="msg", required=false) String msg) {
return msg;
}
- URI 는 /api/hello 로 동작하게 되며 GET 요청에만 동작.
- GET 방식의 경우 HTTP 요청에는 URL 에 파라미터 형식으로 데이터를 전송하는 방법이 사용됨.
- POST의 경우 HTTP Body 에 데이터를 전송하는 형식을 취하게 됨. 이 경우에는 @RequestBody 애너테이션이 사용되며 매핑될 자바 객체를 지정해 주어야 함.
- required=false를 명시하지 않으면 파라미터가 누락되는 경우 에러가 발생.
- 여기서는 파라미터로 전달된 msg 값을 문자열 형태로 리턴함.
실행을 하면 다음과 같다.
이제 본격적으로 실제 활용 가능한 REST API 서비스를 구현해보자. 구현할 예제는 상품정보를 제공하는 서비스로 다음의 세 가지 기능을 제공한다.
- 상품등록: JSON 구조의 상품정보를 POST 방식으로 서버에 등록.
- 전체 상품 조회: 전체 상품목록을 JSON 구조로 제공.
- 특정 상품 조회: 상품의 등록번호(등록된 순서)를 통해 해당 상품만 JSON 구조로 제공.
[ Product 클래스 구현 ]
Entity 클래스로 상품정보를 표현하는 클래스이다. 데이터베이스를 사용한다면 테이블 구조로 매핑할 수도 있다.
package com.example.rest;
public class Product {
private int id;
private String name;
private int price;
public Product() {} // 디폴트 생성자
public Product(int id, String name, int price) {
this.id = id;
this.name = name;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
[ ProductManager 클래스 구현 ]
ProductManager클래스는 상품정보를 관리하기 위한 클래스로 아직 DB와의 연동은 하지 않기 때문에 ArrayList를 사용해 데이터를 관리한다. 인스턴스 생성시 생성자에서 샘플 데이터를 4개 추가 하도록 구성한다.
package com.example.rest;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Component;
@Component
public class ProductManager {
private List<Product> datas = new ArrayList<>();
public ProductManager() {
datas.add(new Product(1, "애플 아이폰 11 pro", 1500000));
datas.add(new Product(2, "삼성 갤럭시 노트 10", 1400000));
datas.add(new Product(3, "삼성 갤럭시 폴드", 2500000));
datas.add(new Product(4, "LG G9", 1000000));
}
// 상품 추가
public void addProduct(Product p) {
p.setId(datas.size() + 1);
datas.add(p);
}
// 모든 상품정보 불러오기
public List<Product> getDatas() {
return datas;
}
// id값을 통해 해당하는 상품만 불러오기
public Product getProduct(int id) {
return datas.get(id - 1);
}
// id값을 통해 해당하는 상품 제거
public void delProduct(int id) {
datas.remove(id - 1);
}
}
- ProductManager 클래스는 @Component 애너테이션을 사용해 스프링프레임워크에서 관리할 Bean 객체로 등록.
- 이 경우 ProductManager 클래스는 자동으로 초기화 되어 스프링 컨테이너에서 관리 되며 프로젝트의 다른 클래스에서 언제든 해당 객체를 사용할 수 있음.
- addProduct() 에서는 ArrayList 의 크기를 구해 다음에 들어갈 데이터의 id 값을 구해서 적용
[ DemoRestController 클래스 업그레이드 ]
앞에서 만들었던 DemoRestController 클래스가 상품정보를 처리할 수 있도록 업그레이드를 한다.
@Autowired
ProductManager pm;
- 먼저 상품정보를 가지고 있는 ProductManager 클래스의 인스턴스를 @Autowired 를 통해 가지고 온다.
- @Autowired 는 스프링의 특징중 하나인 DI 의 사용 형태중 하나로 필요한 객체를 직접 생성하지 않고 스프링컨테이너를 통해 주입해 사용
다음으로 상품 목록을 제공하기 위한 getAll() 메서드를 작성한다. URI는 /api/product가 된다.
@GetMapping("/product")
public List<Product> getAll() {
return pm.getDatas();
}
- pm 으로 ProductManager 객체가 참조 되었기 때문에 getDatas() 메서드를 통해 List 를 리턴 하기만 하면 된다.
- 이때 스프링의 RestController 는 리턴타입이 객체형인경우 자동으로 JSON 으로 변환.
- 따라서 리턴된 결과는 JSON 구조로 전달된다. 상품의 목록 이므로 Array 형태가 됨
다음은 특정 상품을 가지고 오기 위한 getProduct() 메서드이다.
getProduct() 는 파라미터로 번호(id)를 받아 오고 해당 번호의 위치에 해당하는 상품을 리턴한다. 이때 파라미터는 Request Parameter 가 아닌 Path Variable 를 사용한다.
물론 Request Parameter 를 사용할 수 있으나 REST API 설계 원칙상 Path Variable 를 사용하는 것이 좋다. 예를 들어 1번 상품을 원한다고 하면 /api/product/1 과 같이 요청하면 된다.
@GetMapping("/product/{id}")
public Product getProduct(@PathVariable int id) {
return pm.getDatas().get(id - 1);
}
- ArrayList 의 구조상 0 부터 인덱스가 시작되기 때문에 상품번호와 일치 시키기 위해 id - 1을 해줌.
- 샘플 데이터는 1~4 로 등록 했으며 ProductManager 의 addProduct() 메서드 에서는 List 의 크기를 구해 다음 id 번호를 자동으로 부여 하도록 되어 있음
다음 포스팅에서는 POST 요청과 postman을 이용해 실행해보겠습니다.
'Programming > Spring Framework' 카테고리의 다른 글
[스프링부트] @JsonNaming, @JsonProperty는 언제 사용할까? (1) | 2021.05.12 |
---|---|
[스프링] IoC Container에 Bean 객체가 등록되는 방법 두 가지를 알아보자 (0) | 2021.01.09 |
[스프링] DI(Dependency Injection) 의존성 주입에 대해 알아보자 (0) | 2021.01.09 |
[스프링부트] postman을 활용한 간단한 RESTful 웹 서비스 만들기 - POST/DELETE 요청 (0) | 2019.09.22 |
[스프링부트] Bean 객체를 등록하는 두 가지 방법(@Component, @Bean) (4) | 2019.09.20 |