๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ฃ ์ด์Šˆ ํ•ด๊ฒฐ ๊ธฐ๋ก

[Spring MVC] DTO๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ๋ฐ›์„ ๋•Œ๋Š” @RequestBody๋ฅผ ๊ผญ ์ ์šฉํ•˜์ž!

by dev_writer 2024. 1. 19.

๊ฐœ์š”

์ด๋ฒˆ์—๋„ ๋ฉ˜ํ† ๋ง ํ”„๋กœ์ ํŠธ ๊ฐœ๋ฐœ์„ ํ•˜๋ฉฐ ๋งˆ์ฃผ์นœ ์ด์Šˆ์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ์Šคํ”„๋ง ํ”„๋กœ์ ํŠธ๋ฅผ ์—ฌ๋Ÿฌ ๋ฒˆ ํ•˜๋ฉด์„œ ๋ณ„๋กœ ๊ฒช์ง€ ์•Š์•˜์—ˆ์ง€๋งŒ, ํ”„๋กœ์ ํŠธ๋ฅผ ์˜ค๋žœ๋งŒ์— ํ•˜๋‹ค ๋ณด๋‹ˆ ์ ‘ํ•˜๊ฒŒ ๋œ ์‹ค์ˆ˜์— ๊ฐ€๊นŒ์› ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋‹ค์‹  ๊ฐ™์€ ์‹ค์ˆ˜๋ฅผ ํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ๊ณต์œ ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค!

 

๋ฌธ์ œ ์ƒํ™ฉ

์–ด์ฉŒ๋ฉด ์ˆœ์ˆ˜ ์ž๋ฐ”๋กœ ๊ฐœ๋ฐœํ•˜๋‹ค๊ฐ€ ์Šคํ”„๋ง์œผ๋กœ ๋„˜์–ด๊ฐˆ ๋•Œ ํ•œ ๋ฒˆ์ฏค์€ ์ ‘ํ•˜์…จ์„ ์‹ค์ˆ˜์˜€์„ ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ญ๋‹ˆ๋‹ค.

 

๊ธ€ (Board) ์“ฐ๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ, ๊ธ€ ์ž‘์„ฑ์— ์‚ฌ์šฉ๋˜๋Š” ์š”์ฒญ dto๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ๋ ˆ์ฝ”๋“œ๋กœ ์ž‘์„ฑํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. (์‘๋‹ต dto๋Š” ์—ฌ๊ธฐ์— id๋„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.)

public record BoardCreateRequest(String title, String content) {
}

 

๊ทธ๋ฆฌ๊ณ  ์ƒ์„ฑ ์ฝ”๋“œ๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘์„ฑํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@PostMapping
public ResponseEntity<BoardCreateResponse> create(final BoardCreateRequest request) {
    Long newBoardId = boardService.save(request);
    BoardCreateResponse response = BoardCreateResponse.from(newBoardId);

    URI newBoardURI = URI.create("/boards" + newBoardId);

    return ResponseEntity.created(newBoardURI)
            .body(response);
    }
}

 

ํ•ด๋‹น ์ฝ”๋“œ๋Œ€๋กœ ์‹คํ–‰ํ•ด ๋ณด๋‹ˆ, id๋Š” ์ž˜ ๋‚˜์˜ค๋Š” ๋ฐ˜๋ฉด (auto-increment), ์ œ๋ชฉ๊ณผ ๊ธ€ ๋‚ด์šฉ์€ ์ œ๋Œ€๋กœ ๋‚˜์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

title, content๊ฐ€ null์ž…๋‹ˆ๋‹ค.

์›์ธ

์›์ธ์€ ์œ„์—์„œ ์ž‘์„ฑํ–ˆ๋“ฏ @RequestBody๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„ ๋ฒŒ์–ด์ง„ ์ผ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์Šคํ”„๋ง ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด, ์Šคํ”„๋ง MVC์—์„œ @RequestBody๋ฅผ ์‚ฌ์šฉํ•ด์•ผ HttpMessageConverter๋ฅผ ํ†ตํ•ด ์š”์ฒญ์˜ ํƒ€์ž…์„ ๋ฉ”์„œ๋“œ ์ธ์ˆ˜๋กœ ํ•ด๊ฒฐํ•ด ์ค€๋‹ค๊ณ  ๋‚˜์™€์žˆ์Šต๋‹ˆ๋‹ค.

์Šคํ”„๋ง ๊ณต์‹ ๋ฌธ์„œ

๊น€์˜ํ•œ ๋‹˜์˜ ์Šคํ”„๋ง MVC 1ํŽธ์—์„œ๋„ ๊ด€๋ จ๋œ ๋‚ด์šฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

@RequestBody
@RequestBody๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด HTTP ๋ฉ”์‹œ์ง€ ๋ฐ”๋”” ์ •๋ณด๋ฅผ ํŽธ๋ฆฌํ•˜๊ฒŒ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ ํ—ค๋” ์ •๋ณด๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด HttpEntity๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ @RequestHeader๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

ํ•ด๊ฒฐ ์ดํ›„

๊ทธ๋ž˜์„œ BoardCreateRequest ์ „, @RequestBody๋ฅผ ๋ถ™์˜€๋”๋‹ˆ ๋‹คํ–‰์Šค๋Ÿฝ๊ฒŒ ์ž˜ ์ €์žฅ๋  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ž˜ ์ €์žฅ๋œ ์‘๋‹ต ๊ฒฐ๊ณผ

์ถ”๊ฐ€์ ์œผ๋กœ ์•Œ๊ฒŒ ๋œ ์‚ฌ์‹ค

๋ณดํ†ต ๋‹ค๋ฅธ ๊ธ€๋“ค์„ ๋ณด๋ฉด, DTO๋ฅผ ๋ ˆ์ฝ”๋“œ๋กœ ์ •์˜ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ๋Š” ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜์„œ Lombok์˜ @NoArgsConstructor๋ฅผ ๋ง๋ถ™์ธ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์—ˆ๋Š”๋ฐ์š”, ์ €๋Š” DTO๋ฅผ ๋ ˆ์ฝ”๋“œ๋กœ ์„ค์ •ํ•ด์„œ ์ด๊ฒƒ์„ ํ•˜์ง€ ์•Š์•„๋„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

 

์ด ์ ์€ ์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค ํ”„๋ฆฌ์ฝ”์Šค๋ฅผ ํ•˜๋ฉฐ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋˜ ๊ธ€์—์„œ๋„ ์•Œ์ง€ ๋ชปํ–ˆ๋˜ ๋‚ด์šฉ์ธ๋ฐ, ๋ ˆ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ฝ”๋“œ๋ฅผ ๊นŒ๋ณด๋‹ˆ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ protected๋กœ ์„ ์–ธ๋˜์–ด ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

protected๋กœ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์„ ์–ธ๋˜์–ด ์žˆ๊ณ , ์œ„์˜ API ์ฐธ๊ณ  ์‚ฌํ•ญ ๊ธ€์„ ๋ณด๋ฉด record ํด๋ž˜์Šค๋Š” Serializable์„ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์ง๋ ฌํ™”์— ๋ฌธ์ œ ์—†์Šต๋‹ˆ๋‹ค.

 

์ด๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์–ด ๋” DTO๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ž๋ฐ” ๋ฒ„์ „์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋ ˆ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ๋” ํŽธํ•œ ๊ฒƒ์ž„์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์งง์€ ๊ณผ์ •์ด์—ˆ์ง€๋งŒ ์ด๋ฒˆ์—๋„ ์ƒˆ๋กญ๊ฒŒ ๋ชฐ๋ž๋˜ ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์–ด ํฅ๋ฏธ๋กœ์› ์Šต๋‹ˆ๋‹ค ๐Ÿ˜€

 

Reference