문제정의
- Spring Cloud Service에서 서버간 데이터를 주고 받을 때 데이터의 일관된 형식을 지키지 않게 되면 서로 주고 받지 못하는 문제 발생
해결과정
- 코드
- 받아오는 필드들의 구조와 이름을 정확하게 일치시키는 작업이 필요했습니다. user 서버에서 delivery 서버로 요청을 보내는 경우를 예로 들자면
- 이 부분은 delivery-server의 controller 부분입니다.
required false인 부분은 없어도 상관없으나, 기본적으로 required는 true로 설정되어있기 때문에 명시되어있지 않은 부분은 요청 때 반드시 넣어주어야 하겠죠?@GetMapping public ResponseEntity<?> getManagers( @RequestParam(value = "search", required = false) String search, // 배송 담당자 타입 @RequestParam(value = "type", required = false) String type, // 배송 담당자 타입 @RequestParam(value = "delivery_manager_id", required = false) Long deliveryManagerId, // 허브 ID @RequestParam(value = "hub_id", required = false) UUID hubId, // 허브 ID @RequestParam(value = "order_id", required = false) UUID orderId, // 허브 ID @RequestParam(value = "sequence_min", required = false) Integer sequenceMin, // 최소 순번 @RequestParam(value = "sequence_max", required = false) Integer sequenceMax, // 최대 순번 @RequestParam(value = "created_from", required = false) String createdFrom, // 생성 시작일 @RequestParam(value = "created_to", required = false) String createdTo, // 생성 종료일 @RequestHeader("X-User_Id") String userId, @RequestHeader("X-Username") String username, @RequestHeader("X-Role") String role, Pageable pageable) throws AccessDeniedException { Page<DeliveryManagerDto> managers = deliveryManagerService.getManagers(search, type, deliveryManagerId, hubId, orderId, sequenceMin, sequenceMax, createdFrom, createdTo, userId, role, pageable); return ResponseEntity.status(HttpStatus.OK).body( CommonResponse.success(HttpStatus.OK.value(), "검색 조회가 완료되었습니다.", managers) ); } @DeleteMapping("/{deliveryManagerId}") public ResponseEntity<?> deleteManager(@PathVariable Long deliveryManagerId, @RequestHeader("X-User_Id") String userId, @RequestHeader("X-Username") String username, @RequestHeader("X-Role") String role) throws AccessDeniedException { deliveryManagerService.deleteManager(deliveryManagerId, userId, username, role); return ResponseEntity.status(HttpStatus.CREATED).body( CommonResponse.success(HttpStatus.CREATED.value(), "배송 담당자 정보 삭제가 완료되었습니다.", null) ); }
- 아래 부분은 delivery manager를 검색 시 가져오는 json 구조입니다.
{ "status": 200, "message": "검색 조회가 완료되었습니다.", "data": { "content": [ { "deliveryMangerId": 4, "slackId": "deliverySlack0", "type": "HUB_DELIVERY_MANAGER", "sequence": 2, "createdBy": "master0", "createdAt": "2024-12-16T18:42:00.697351", "updatedAt": "2024-12-16T19:18:30.733477" } ], "pageable": { "pageNumber": 0, "pageSize": 20, "sort": [], "offset": 0, "paged": true, "unpaged": false }, "last": true, "totalPages": 1, "totalElements": 1, "size": 20, "number": 0, "sort": [], "first": true, "numberOfElements": 1, "empty": false } }
- 아래 부분은 user-server의 DeliveryService 인터페이스를 상속받아 사용하는 DeliveryClient 클래스는 다음과 같습니다.
@FeignClient(name = "delivery-service")
public interface DeliveryClient extends DeliveryService {
@GetMapping("/api/deliveries/delivery-managers")
ResponseEntity<ApiResponseDto<GetUUIDDto>> getDeliveryManagerByUserId(@RequestParam(name = "delivery_manager_id") Long userId,
@RequestHeader(value = "X-User_Id", required = true) @NotBlank String headerUserId,
@RequestHeader(value = "X-Username", required = true) @NotBlank String username,
@RequestHeader(value = "X-Role", required = true) @NotBlank String role);
@DeleteMapping("/api/deliveries/delivery-managers/{delivery_manager_id}")
ResponseEntity<ApiResponseDto<?>> softDeleteDeliveryManager(@PathVariable(name = "delivery_manager_id") Long deliveryManagerId,
@RequestHeader(value = "X-User_Id", required = true) @NotBlank String headerUserId,
@RequestHeader(value = "X-Username", required = true) @NotBlank String username,
@RequestHeader(value = "X-Role", required = true) @NotBlank String role
);
}
저는 여기서 필요한 필드값만을 사용하기 위해 다음 dto를 예시로 만들어 사용하였습니다.
@Getter
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class GetUUIDDto {
private List<UUIDListDto> content;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class UUIDListDto {
private Long deliveryManagerId;
}
}
응답 데이터의 “data” 안의 “content”안의 “deliveryMangerId”만을 사용하기 위해 GetUUIDDto 를 만들어 List 타입으로 content를 받게 하고 inner class를 만들어 deliveryManagerId를 가져올 수 있게 하였습니다.
결과
- 위처럼 실행 후 실제 서버를 실행 후 삭제 요청을 보내니 정상적으로 user와 delivery manager 쪽에서 삭제되는 걸 확인할 수 있었습니다.
깨달은 내용
- 개인적으로 느낀 건 서버간 통신을 할 때도 client의 개념을 적용시켜야 한다는 것이었습니다. 서버라고 한다면 무조건 요청을 받고 데이터를 넘겨주어야 하는 것으로 알고 있었지만 서버간에도 client 역할이 있고 server의 역할이 있다는 것을 느꼈어요. 왜 FeignClient라고 이름을 지었는지 좀 알게 된 것 같습니다. 데이터를 넘겨줄 때 FeignClient를 통해서 우리가 postman을 통해 요청을 보내는 것처럼 만들어주고, 받아올 수 있는 것을 알게 되고 나니 너무 좁게만 생각하고 있었던 것 같네요. 제가 틀릴 수도 있다는 것을 알고 시야를 넓게 가지게 되는 경험이 됐습니다!
'개발 > 팀 프로젝트' 카테고리의 다른 글
Json 구조의 이해... (0) | 2025.01.03 |
---|---|
Postgresql 연결 오류 (0) | 2024.12.09 |
Github를 이용한 팀 프로젝트 (0) | 2024.11.12 |
명세서 작업 (1) | 2024.11.11 |