🚧

[JPA둜 REST API λ§Œλ“€κΈ°] Module κ³Ό Model 생성

purpplee 2021. 11. 24. 15:44

λͺ¨λ“ˆμ΄λž€?

우리의 Todo list λŠ” κΈ°λŠ₯이 λ‹¨μˆœνžˆ todo λ₯Ό CRUD ν•˜λŠ” 것 λΏμ΄μ§€λ§Œ, λ§Œμ•½ μ—¬λŸ¬ νšŒμ›μ„ κ΄€λ¦¬ν•˜λŠ” κΈ°λŠ₯κΉŒμ§€ μΆ”κ°€ν–ˆλ‹€λ©΄ ν•œ νŒ¨ν‚€μ§€ μ•ˆμ— κ°œλ°œν•˜λŠ” 건 λΉ„νš¨μœ¨μ μ΄λ‹€. λ”°λΌμ„œ κΈ°λŠ₯λ³„λ‘œ λͺ¨λ“ˆμ„ λ‚˜λˆˆλ‹€. λͺ¨λ“ˆμ€ μ΄λ ‡κ²Œ κΈ°λŠ₯별, μ—­ν• λ³„λ‘œ λΆ„λ¦¬ν•œ 것을 λ§ν•œλ‹€. 각각의 λͺ¨λΈμ€ 각각의 컨트둀러, μ„œλΉ„μŠ€, λͺ¨λΈμ„ κ°€μ§ˆ 수 μžˆλ‹€.

 

todo λͺ¨λ“ˆ

νŒ¨ν‚€μ§€ μ•ˆμ— todo νŒ¨ν‚€μ§€λ₯Ό 생성해쀀닀.

 

Todo list μ—μ„œ λΉ„μ¦ˆλ‹ˆμŠ€ λͺ¨λΈμ€ λ°”λ‘œ todo item 이닀. 할일을 μ λŠ” ν…μŠ€νŠΈ title κ³Ό μ™„λ£Œν–ˆλŠ”μ§€ μ•„λ‹Œμ§€ μ²΄ν¬ν•˜λŠ” done. 그리고 각 item 을 κ΅¬λΆ„ν•˜λŠ” id 둜 κ΅¬μ„±λ˜μ–΄ μžˆλ‹€. 이 λΉ„μ¦ˆλ‹ˆμŠ€ λͺ¨λΈμ„ μ²˜λ¦¬ν•˜κΈ° μœ„ν•œ ν΄λž˜μŠ€λ“€μ„ 생성해쀄 것이닀. νŒ¨ν‚€μ§€ μ•„λž˜μ— model νŒ¨ν‚€μ§€λ₯Ό 생성해쀀닀.

/model/TodoItem.java

todo list μ—μ„œ μ²˜λ¦¬ν•  λΉ„μ¦ˆλ‹ˆμŠ€ λͺ¨λΈμ΄λ‹€. 

package com.todolist.tutorial.todo.model;

import lombok.*;

@Getter @Setter         //getter, setter λ©”μ†Œλ“œ
@NoArgsConstructor      //인자 μ—†λŠ” κΈ°λ³Έ μƒμ„±μž
@AllArgsConstructor     //λͺ¨λ“  인자 κ°€μ§€λŠ” μƒμ„±μž
@Builder                //λΉŒλ” νŒ¨ν„΄μœΌλ‘œ μƒμ„±ν•˜κ²Œ ν•΄μ€Œ.
public class TodoItem {
    private Long id;
    private String title;
    private boolean done;
}

loombook μ–΄λ…Έν…Œμ΄μ…˜ 덕뢄에 μ•„λž˜μ²˜λŸΌ class 내뢀에 κ΅¬ν˜„ν•˜μ§€ μ•Šμ€ λ©”μ†Œλ“œλ“€μ„ μ“Έ 수 있게 ν•΄μ€€λ‹€.

 

Request 와 Response λŠ” 각각 http μš”μ²­/응닡에 따라 μ£Όκ³ λ°›λŠ” 데이터닀. TodoItem 자체λ₯Ό μ‘λ‹΅ν•˜λ©΄ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ κ³΅κ°œν•˜λŠ” κ²ƒμ΄λ―€λ‘œ 지양해야 ν•œλ‹€. 또 Request 데이터가 TodoItem κ³Ό ν˜•νƒœκ°€ μΌμΉ˜ν•˜μ§€ μ•ŠλŠ” κ²½μš°λ„ μžˆμœΌλ―€λ‘œ ν•œλ²ˆ 더 κ°μ‹Έμ£ΌλŠ” 게 μ’‹λ‹€. μ΄λ ‡κ²Œ 데이터 κ°„ κ΅ν™˜μ„ μœ„ν•΄ λΉ„μ¦ˆλ‹ˆμŠ€ λ‘œμ§μ„ ν¬ν•¨μ‹œν‚€μ§€ μ•ŠλŠ” 객체λ₯Ό DTO(Data Transfer Object) 라고 ν•œλ‹€.

 

/model/TodoItemRequest.java

이 ν”„λ‘œμ νŠΈμ—μ„œλŠ” Request μ—μ„œ λ”±νžˆ μ²˜λ¦¬ν•  λ‚΄μš©μ΄ μ—†μœΌλ―€λ‘œ TodoItem λ₯Ό 상속해주면 λœλ‹€.

package com.todolist.tutorial.todo.model;

public class TodoItemRequest extends TodoItem {
}

 

/model/ApiResponse.java

TodoItem Response 만 λ§Œλ“€μ–΄λ„ λ˜μ§€λ§Œ, λ‚˜μ€‘μ— user 등이 μΆ”κ°€λœλ‹€λ©΄ 각각에 λŒ€ν•œ Response 객체λ₯Ό λ§Œλ“€μ–΄μ€˜μ•Ό ν•œλ‹€. κ·Έλ•Œλ§ˆλ‹€ 맀번 ν•„λ“œμ— error λ₯Ό λ„£μ–΄μ£ΌλŠ” 건 λΉ„νš¨μœ¨μ μ΄λ―€λ‘œ 곡톡 속성을 상속받을 수 μžˆλŠ” λΆ€λͺ¨ν΄λž˜μŠ€ 틀을 생성해쀀닀.

package com.todolist.tutorial.todo.model;

import lombok.*;

@Getter @Setter
@NoArgsConstructor
public class ApiResponse<T> {
    private T data;
    private String errors;
}

 

/model/TodoItemResponse.java

단일 todo item 을 응닡할 λ•Œ ν•œλ²ˆ 더 κ°μŒ€ 수 μžˆλŠ” TodoItemResponse 객체닀. λ³΄μ•ˆμ— 더 μ‹ κ²½μ“΄λ‹€λ©΄ νŒŒλΌλ―Έν„°μ— TodoItem 을 κ·ΈλŒ€λ‘œ 넣기보닀 멀버 λ³€μˆ˜λ“€μ„ 직접 ν•˜λ‚˜ν•˜λ‚˜ 넣기도 ν•˜μ§€λ§Œ νŠœν† λ¦¬μ–Όμ΄λ‹ˆ ν†΅μ§Έλ‘œ λ„£μ—ˆλ‹€. 

package com.todolist.tutorial.todo.model;

import lombok.Builder;

public class TodoItemResponse extends ApiResponse<TodoItem> {
    @Builder
    public TodoItemResponse(final TodoItem todoItem, final String errors) {
        this.setData(todoItem);
        this.setErrors(errors);
    }
}

 

/model/TodoItemListResponse.java

μ—¬λŸ¬ 개의 todo item 을 응닡할 λ•Œ κ°μ‹ΈλŠ” response 객체닀.

package com.todolist.tutorial.todo.model;

import lombok.Builder;

import java.util.List;

public class TodoItemListResponse extends ApiResponse<List<TodoItem>> {
    @Builder
    public TodoItemListResponse(final List<TodoItem> todoItems, final String errors) {
        this.setData(todoItems);
        this.setErrors(errors);
    }
}

 

/model/TodoItemAdapter.java

TodoItem <-> TodoItemResponse, TodoItemList -> TodoItemListResponse 둜 λ°”κΏ”μ£ΌλŠ” μ–΄λŽν„°λ₯Ό μƒμ„±ν•œλ‹€.

package com.todolist.tutorial.todo.model;

import java.util.List;

public class TodoItemAdapter {
    //todoITemRequest -> todoItem
    public static TodoItem todoItem(final TodoItemRequest todoItemRequest) {
        if(todoItemRequest == null) return null;

        return TodoItem.builder().title(todoItemRequest.getTitle()).done(todoItemRequest.isDone()).build();
    }

    //todoItem+error message -> todoItemResponse
    public static TodoItemResponse todoItemResponse(final TodoItem todoItem, final String errors) {
        return TodoItemResponse.builder().todoItem(todoItem).errors(errors).build();
    }

    //todoItemList+error message -> todoItemListResponse
    public static TodoItemListResponse todoItemListResponse(final List<TodoItem> todoItems, final String errors) {
        return TodoItemListResponse.builder().todoItems(todoItems).errors(errors).build();
    }
}
λ°˜μ‘ν˜•