티스토리 뷰

Spring

Spring - <JSON> data patch

0307kjb 2022. 1. 22. 00:29

@RequestBody를 통해 Json 데이터를 받아 rest api를 활용하여 crud 작업을 수행할 수 있다.

여기서는 patch과정을 통해 crud 작업을 수행한다.

 

@Entity
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MenuItem {

    @Id
    @GeneratedValue
    private long id;

    private long restaurantId;

    private String name;

    @JsonInclude(JsonInclude.Include.NON_DEFAULT)
    private boolean deleted;
}

롬복을 통해 빌더 패턴과 Getter, Setter를 표현한 엔티티이다. (JPA)

@JsonInclude에 관해서는 이따가 설명할 것.

 

// 컨트롤러 //

@RestController
public class MenuItemController {

    @Autowired
    private MenuItemService menuItemService;

    @PatchMapping("/restaurants/{restaurantId}/menuitems")
    public void bulkUpdate(@PathVariable("restaurantId") long restaurantId, @RequestBody List<MenuItem> menuItems) {
        menuItemService.bulkUpdate(restaurantId, menuItems);
    }
}


// 테스트 //

@ExtendWith(SpringExtension.class)
@WebMvcTest(MenuItemController.class)
class MenuItemControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private MenuItemService menuItemService;

    @Test
    public void bulkUpdate() throws Exception {

        List<MenuItem> menuItems = new ArrayList<>();

        mvc.perform(patch("/restaurants/1/menuitems").
                contentType(MediaType.APPLICATION_JSON).
                content("[]")).andExpect(status().isOk());

        verify(menuItemService).bulkUpdate(1L, menuItems);

    }
}

 

@RequestBody List<Object>를 통해 해당 엔티티의 필드 목록을 json 데이터로 가져온다.

테스트에서도 json 데이터를 가져오는 것을 입력값으로 하여 verify(검증)이 되는 것을 볼 수 있다.

 

// 서비스 //

@Service
public class MenuItemService {

    @Autowired
    private final MenuItemRepository menuItemRepository;

    public MenuItemService(MenuItemRepository menuItemRepository) {
        this.menuItemRepository = menuItemRepository;
    }

    public void bulkUpdate(long restaurantId, List<MenuItem> menuItems) {
        for(MenuItem menuItem : menuItems){
            update(restaurantId, menuItem);
        }
    }

    public void update(long restaurantId, MenuItem menuItem){
        if(menuItem.isDeleted()){
            menuItemRepository.deleteById(menuItem.getId());
            return;
        }
        menuItem.setRestaurantId(restaurantId);
        menuItemRepository.save(menuItem);
    }
}


// 테스트 //

class MenuItemServiceTests {

    private MenuItemService menuItemService;

    @Mock
    private MenuItemRepository menuItemRepository;

    @BeforeEach
    public void init(){
        MockitoAnnotations.openMocks(this);
        menuItemService = new MenuItemService(menuItemRepository);
    }

    @Test
    public void bulkUpdate(){
        List<MenuItem> menuItems = new ArrayList<>();

        menuItems.add(MenuItem.builder().name("Kimchi").build());
        menuItems.add(MenuItem.builder().id(1L).name("quackdugi").build());
        menuItems.add(MenuItem.builder().id(1L).deleted(true).build());

        menuItemService.bulkUpdate(1L, menuItems);
        verify(menuItemRepository, times(2)).save(any());
        verify(menuItemRepository, times(1)).deleteById(1L);

    }
}

 

json 데이터에 deleted가 있다면 삭제하는 메서드의 로직이다.

테스트의 경우에도 이를 확인 가능한데, save는 2번(추가와 수정)이 이루어지고 deleteById가 한 번 실행되는 것을 볼 수 있다.

 

 

 

실행결과)

 

http로 1번 레스토랑 항목 갖고오기.

 

menuitems.json
http PATCH 명령어를 통해 JSON 데이터 발송.

 

결과(menuitem이 추가된 것을 확인)

 

menuitems.json
http PATCH 명령어를 통해 JSON 데이터 다시 발송.

 

menuitems의 갱신과 삭제가 된 점을 확인 가능.

 

여기서 @JsonInclude를 해주지 않는다면 프론트단에서 원하지 않는 정보인 deleted가 보이기 때문에 true일 경우에만 보이도록 조치를 취한 것이다.

'Spring' 카테고리의 다른 글

연관 관계  (0) 2022.05.30
Java, Mybatis, Oracle 연동 코드  (0) 2022.05.29
Spring - Exception  (0) 2022.01.21
Spring - Validation  (0) 2022.01.21
JPA 활용.  (0) 2022.01.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함