이번엔 주문/배송 상태 변경 기능을 추가해보도록 하겠다.
[API_ENDPOINT]/api/v1/developers/orders/${partnerOrderId}/status 으로 PATCH 를 요청한다.
| Parameter | Description |
|---|---|
| Authorization | 시작하기에서 생성한 Authorization 파라미터 값 |
| vendor | kakaoT 퀵∙도보 배송 API Sandbox에서 발급받은 Vendor 아이디 |
| Content-Type | application/json |
여태까지와 똑같은 헤더값이다
| Name | Type | Description | Required |
|---|---|---|---|
partnerOrderId | String | 연동사 주문 아이디 | 필수 |
이번에도 조회와 똑같이 partnerOrderId 를 path 파라미터로 사용한다.
curl -X 'PATCH' \
'https://open-api-logistics.kakaomobility.com/goa-sandbox-service/api/v1/developers/orders/${partnerOrderId}/status' \
-H 'accept: application/json' \
-H 'vendor: ${vendor_id}' \
-H 'Authorization: XXX' \
-H 'Content-Type: application/json' \
-d '{
"orderStatus": "CANCEL",
"cancelBy": "ADMIN"
}'
이번엔 orderStatus 와 cancelBy 가 Body를 구성한다.
| Name | Type | Description | Required |
|---|---|---|---|
orderStatus | Enum(String) | 변경하려는 주문의 상태다음 중 하나: ABORT: 배송 강제 종료MATCH_PICKER: 배송원 배정 완료CANCEL: 배송 취소PICKUP_COMPLETED: 배송원 픽업 완료DROPOFF_COMPLETED: 배송 완료 | 필수 |
cancelBy | Enum(String) | 주문 취소 주체다음 중 하나: PICKER: 배송원에 의한 주문 취소ADMIN: 관리자에 의한 주문 취소 | 선택 |
따로 JSON으로 응답하지 않고 요청에 대한 성공 여부를 HTTP 상태 코드로 전달받는다.
결론부터 말하자면 지금까지 했던 것처럼 MVC 기반에서 작동시키기엔 지금의 환경에서는 무리가 있다.
필자는 이 작업을 eGovFramework 3.10에서 진행하고 있으며 해당 환경은 버전이 낮아 HiddenHttpMethodFilter 와 같은 POST를 PATCH로 바꿔주는 방식을 사용하기 까다롭다.
정상적인 Response를 받는 것은 실패했지만 어떤 식으로 접근했는지 적어보려고 한다.
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
먼저 HiddenHttpMethodFilter 를 빈으로 가져와야한다.
HiddenHttpMethodFilter은 POST를 PATCH로 변환할 수 있는 필터다.
만약 Spring boot 환경이 아닌 Spring MVC 환경이라면 web.xml 파일에 설정해야 한다.
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
jsp에서는 를 통해 Controller에 PATCH 요청을 보낸다.
<body>
<div class="container">
<h3 class="title">주문 변경할 ID</h3>
<p id="vendor" hidden>${vender}</p>
<p id="authorization" hidden>${authorization}</p>
<form id="orderPatch" method="post">
<label for="partnerOrderId">파트너 ID</label>
**<input type="hidden" name="_method" value="PATCH">**
...
<button type="button" class="btn-submit" onclick="submitForm()">조회</button>
</form>
<script>
function submitForm() {
const form = document.getElementById("orderPatch");
const ID = document.getElementById("partnerOrderId").value;
if (ID) {
form.action = '/kakaoTest/patch/' + ID + '.do';
form.submit();
} else {
alert("Invaild ID");
}
}
</script>
</div>
</body>
form에서 hidden으로 보낸 PATCH 요청을 Controller에선 params = “_method=PATCH”를 추가해서 처리하도록 한다.
@RequestMapping(value = "/patch/{partnerOrderId}.do", method = RequestMethod.POST, params = "_method=PATCH")
public String patchOrder(@PathVariable String partnerOrderId, @ModelAttribute OrderVO orderVO, Model model) {
try {
final String API_ENDPOINT = apiConfig.getHostURL() + "/api/v1/developers/orders/" + partnerOrderId + "/status";
final String VENDOR_ID = apiConfig.getVendorID();
final String authorization = getAuthorization();
JSONObject json = new JSONObject();
// JSON 객체에 데이터 삽입
json.put("orderStatus", orderVO.getOrderStatus());
json.put("cancelBy", orderVO.getCancelBy());
// HTTP Header 설정
HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type", "application/json");
headers.set("Authorization", authorization);
headers.set("vendor", VENDOR_ID);
// HTTP 요청 생성
HttpEntity<String> requestEntity = new HttpEntity<>(json.toString(), headers);
// API 호출
ResponseEntity<String> response = null;
try {
response = restTemplate.postForEntity(API_ENDPOINT, requestEntity, String.class);
System.out.println("Response Status Code: " + response.getStatusCode());
System.out.println("Response Body: " + response.getBody());
} catch (Exception e) {
System.out.println("기타 예외 발생");
e.printStackTrace();
}
// 응답 처리
model.addAttribute("responseCode", response.getStatusCodeValue());
model.addAttribute("responseBody", response.getBody());
return "result";
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error: " + e.getMessage());
return "result";
}
}
다음과 같은 과정을 거친다면 어느정도 spring 환경이 최신 버전일 때 정상적으로 작동할 것으로 예상된다.
PATCH는 애초에 웹 어플리케이션에서 작동하기 보다 REST API에서 작동하는 요청이다 보니 웹에서는 여러가지로 호환이 안되는 문제를 깨달았다.
이 프로젝트는 잠정적으로 끝났지만 나머지 구현했던 부분들에 대해서도 작성할 예정이다.
https://logistics-developers.kakaomobility.com/document/patch-orders-status