티스토리 뷰

Backend/Spring

#5 GET API with DTO

RadderNepa 2023. 7. 30. 05:42

● GET API

- 아래의 4가지는 API를 이루고 있는 요소이다. 이 4가지를 직접 정해서 GET API를 만들어보자

[API Specification(API 명세) = 어떻게 API를 만들 것인가]
1. HTTP Method  →  GET
2. HTTP Path  →  /add
3. 쿼리  →  int number1 / int number2
4. API 반환 결과  →  (number1 + number2)
package com.group.libraryapp.controller.calculator;

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

@RestController
public class CalculatorController {
    @GetMapping("/add")
    public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) {
        return number1 + number2;
    }
}

1. @RestController(@Controller + @ResponseBody)

- Controller는 일종의 API의 입구 역할이다. 즉, HTTP request가 해당 class로 들어올 수 있게 해준다.(주어진 Class를 Controller로 등록)

 

2. @GetMapping(“/add”)

- (HTTP Method = GET Method), (HTTP path = /add)인 API로 지정한다.

 

3. @RequestParam

- request query에 들어있는 값을 method의 parameter에 넣는다.(연결해준다.)


- Postman을 이용해 테스트 해보자

- 크롬에서도 직접 로컬호스트에 접속해보았다.

http://localhost:8080/add?number1=10&number2=20


DTO를 이용해 @RequestParam 제거

- query에 들어가는 인자의 갯수가 많아지면 그 만큼 method의 parameter도 늘어나는데 이를 간단히 하고 싶은 욕망이 당연히 들어야한다. 따라서 객체를 이용해 client로부터 넘어오는 값을 받아보자

 

1. 객체 생성

package com.group.libraryapp.dto.calculator.request;

public class CalculatorAddRequest {
    private final int number1;
    private final int number2;

    public CalculatorAddRequest(int number1, int number2) {
        this.number1 = number1;
        this.number2 = number2;
    }

    public int getNumber1() {
        return number1;
    }

    public int getNumber2() {
        return number2;
    }
    
    // final 키워드가 있으므로 어차피 setter는 생성할 수 없다.
}

 

2. 객체를 이용해 query에서 넘어오는 값을 받도록 수정

package com.group.libraryapp.controller.calculator;

import com.group.libraryapp.dto.calculator.request.CalculatorAddRequest;
import org.springframework.web.bind.annotation.GetMapping;
// import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CalculatorController {
    @GetMapping("/add")
    // public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) {
    public int addTwoNumbers(CalculatorAddRequest request) {
        return request.getNumber1() + request.getNumber2();
    }
}

- /add API가 호출될 때 server로 넘어오는 request query가 CalculatorAddRequest 객체에 있는 필드(number1, number2)에 각각 매핑된다.

- 따라서 당연히 query와 객체의 필드명이 일치해야한다. request query의 값을 객체로 한 번 감싸서 받는 것이라고 생각하면 된다.

인프런 - 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!(최태현)

[API 흐름]
1. Postman에서 (?number1=10&number2=20) request query를 Spring boot에 보낸다.
2. Spring boot가 CalculatorAddRequest 객체에 값을 집어넣는다.
3. 값을 집어넣은 객체를 Controller에 보내준다.

cf)

- 아래 사진과 같이 query를 객체의 필드명과 다르게 하면 오류가 발생한다.


 DTO, DAO, VO

1. DTO(Data Transfer Object, 데이터 전달 객체)

- DTO는 정보를 전달하는 역할의 객체이다.

- constructor, gettter, setter를 제외한 계산(비즈니스) 로직을 가지지 않는다. 즉, 비즈니스 로직을 가지지 않는 순수한 데이터 객체(getter, setter)

- setter가 있으면 데이터 변경 가능성이 있기 때문에 아래와 같이 생성자로 값을 넣어주면 데이터 오염 현상을 막을 수 있다.(아예 setter 자체를 생성하지 않는 것)

public class myDTO {
    private String name;
    private String id;

    public myDTO(String name, String id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public String getId() {
        return id;
    }
}

 

2. DAO(Data Access Object)

- DB에 접근하기 위한 객체(DB에 CRUD 로직을 수행하기 위한 역할)

- 즉, DB 접근 로직과 비즈니스 로직을 분리하기 위해 사용한다.

- DAO는 비즈니스 로직이 없기에 DB가 변경되어도 비즈니스 로직에 큰 영향을 주지 않는다.(어차피 비즈니스 로직은 DAO에서 넘어온 값을 가지고 작업을 수행하는 것이니까)

 

3. VO(Value Object)

- DTO와 유사한 개념으로 착각할 수도 있다. 하지만 DTO와 VO의 가장 큰 차이점은 VO는 불변한 값(immutable)을 가진다는 것이다.

- DTO가 데이터 전송이 핵심인 객체라면 VO는 값 그 자체가 핵심인 객체이다.

- DTO는 setter method를 가질 수 있기에 경우에 따라 그 안에 담겨있는 값을 수정할 수 있지만 VO는 애초에 setter method를 가지면 안 된다.(setter method를 가지면 VO가 아닌것이다.)

- 따라서 VO는 한 번 생성된 후에는 내부 상태가 변경되지 않아야한다.

 

https://maenco.tistory.com/entry/Java-DTO%EC%99%80-VO%EC%9D%98-%EC%B0%A8%EC%9D%B4

 

[JAVA] DTO와 VO의 차이

데이터를 위한 객체를 만들다 보면 항상 DTO와 VO를 혼용해서 쓰고 하는데, 어떤 것이 맞는 것인지 항상 헷갈렸다. 한번 정리해보면서 이 둘의 차이는 무엇이고 어떤 상황에서 쓰는 것이 가장 이

maenco.tistory.com

 

cf) 현재 프로젝트 구조

'Backend > Spring' 카테고리의 다른 글

#7 DTO와 VO(Entity는 링크한 글을 보자)  (0) 2023.08.04
#6 POST API  (0) 2023.07.31
#4 HTTP, API, URL  (0) 2023.07.29
#3 @SpringBootApplication / 네트워크  (0) 2023.07.27
#2 API 만들기1 - Spring Project 생성  (0) 2023.07.25
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함