자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
Delphi (자문 자답) JSON 안의 특정 필드 값만 바꾸는 방법은 TJsonPair를 사용하면 간단합니다. (POST, PUT 방식으로 특정 필드만 교체할 때, 특히 유용)
2020.06.15 11:29
혹시, 필요한 분이 있을까봐 남겨둡니다. (자문 자답)
Unleashed라는 도매 및 창고관리 SaaS 클라우드 소프트웨어의 API를 이용하는 애플리케이션을 델파이로 개발하고 있습니다.
해당 REST API를 이용하여 Product 데이터 1개의 수많은 필드 중 2개 필드의 값만 변경하고, 다른 것은 그대로 유지해야 했습니다.
그런데, Unleashed 에서 제공하는 API는 변경 시에도 PUT이나 PATCH 방식이 아니라 오직 POST만 제공합니다.
그리고, POST로 해당 Product 데이터를 제공할 때, 값을 넣지 않은 필드는 모두 디펄트값으로 변경된다고 합니다.
즉, 나는 2개 필드만 바꾸고 싶은데, 결국 바꾸고 싶은 2개 필드 이외에도 해당 Product의 모든 필드에 해당 현재 값을 모두 채워서 POST 방식으로 요청해야 하는 상황이 되었습니다.
HTTP 스펙 상 CRUD 메소드로, POST(생성, Create), GET(조회, Read), PUT(수정, Update- 통채로 Replace), PATCH(수정, Update-해당 부분만 Modify) 또는 DELECT(삭제, Delete) 방식(Method)를 정하고 있다는 면에서 볼 때, Unleashed의 API는 (뭔가 이유가 있었을텐데) 쉽게 이해하기는 힘듭니다. 하지만, API사용자 입장에서는 최대한 API 제공자의 서비스를 이해하고 맞추는 수밖에 없습니다. 아마 API 제공자도 이미 오픈한 API를 바꾸기도 쉽지 않겠죠)
그래서, API 서버에서 Product을 JSON으로 가져오고, 그 JSON 안에서 원하는 2개 필드의 값만 바꾸어서 다시 API 서버로 통채로 던져서 수정하는 방법을 사용했습니다.
JSON 안의 특정 필드 값만 바꾸는 방법은 TJsonPair를 사용하면 간단합니다.
사실 Stack Overflow의 아래에 설명된 대로 하였습니다.
단, Stack Overflow에서 알려준 코드에서 JSON페어.JsonValue.Free; 코드가 없어야 작동합니다.(Delphi 10.3.3 버전 기준)
https://stackoverflow.com/questions/33426576/
[작성된 실전 코드 중 해당 부분 발췌 (Delphi 10.3.3 버전 기준)]
uses
..., System.JSON;
procedure TfrmMainForm.PriceBatchUpdate;
var
JOProductU: TJSONObject;
JOPair: TJSONPair;
begin
//상품코드를 이용하여 상품 데이터를 TJsonObject로 받아온다.
JOProductU := TProductMgmt.GetProductUByProductCodeJSON(ProductCode);
//TJsonPair로 원하는 필드를 가진 TJsonPair를 잡는다 (기본판매가: DefaultSellPrice 필드)
//가장 바깥에 있는 필드라면, 이렇게 바로 잡아낸다.
JOPair := JOProductU.Get('DefaultSellPrice');
PriceDefaultSellUOld := JOPair.JsonValue.Value; //기본판매가 값을 기록해둔다.(로그용)
JOPair.JsonValue := TJSONNumber.Create(10); //기본판매가 값을 10으로 바꾼다.
//TJsonPair로 원하는 필드를 가진 TJsonPair를 잡는다 (T1판매가: SellPriceTier 필드 안에 있는 Value라는 필드)
//이런 식으로 얼마든지 안쪽 깊이 들어 있는 필드도 잡을 수 있다.
JOPair := JOProductU.GetValue<TJSONObject>('SellPriceTier1').Get('Value');
PriceSell1UOld := JOPair.JsonValue.Value; //T1판매가 값을 기록해둔다.(로그용)
JOPair.JsonValue := TJSONNumber.Create(15); //T1판매가 값을 15으로 바꾼다.
...
//TJsonObject인 JOProductU에서 원하는 값을 위 방법으로 이미 교체했으므로, 그대로 서버에 보낸다. 끝.
dmUnleashedAccess.UpdateProduct(ProductIDU,JOProductU);
end;
(델파이 초보입니다. 더 좋은 코드나 제안이 있으면, 댓글로 가르침을 주세요. 미리 환영합니다)
댓글 2
Delphi (자문 자답) JSON 안의 특정 필드 값만 바꾸는 방법은 TJsonPair를 사용하면 간단합니다. (POST, PUT 방식으로 특정 필드만 교체할 때, 특히 유용)
2020.06.15 11:29
혹시, 필요한 분이 있을까봐 남겨둡니다. (자문 자답)
Unleashed라는 도매 및 창고관리 SaaS 클라우드 소프트웨어의 API를 이용하는 애플리케이션을 델파이로 개발하고 있습니다.
해당 REST API를 이용하여 Product 데이터 1개의 수많은 필드 중 2개 필드의 값만 변경하고, 다른 것은 그대로 유지해야 했습니다.
그런데, Unleashed 에서 제공하는 API는 변경 시에도 PUT이나 PATCH 방식이 아니라 오직 POST만 제공합니다.
그리고, POST로 해당 Product 데이터를 제공할 때, 값을 넣지 않은 필드는 모두 디펄트값으로 변경된다고 합니다.
즉, 나는 2개 필드만 바꾸고 싶은데, 결국 바꾸고 싶은 2개 필드 이외에도 해당 Product의 모든 필드에 해당 현재 값을 모두 채워서 POST 방식으로 요청해야 하는 상황이 되었습니다.
HTTP 스펙 상 CRUD 메소드로, POST(생성, Create), GET(조회, Read), PUT(수정, Update- 통채로 Replace), PATCH(수정, Update-해당 부분만 Modify) 또는 DELECT(삭제, Delete) 방식(Method)를 정하고 있다는 면에서 볼 때, Unleashed의 API는 (뭔가 이유가 있었을텐데) 쉽게 이해하기는 힘듭니다. 하지만, API사용자 입장에서는 최대한 API 제공자의 서비스를 이해하고 맞추는 수밖에 없습니다. 아마 API 제공자도 이미 오픈한 API를 바꾸기도 쉽지 않겠죠)
그래서, API 서버에서 Product을 JSON으로 가져오고, 그 JSON 안에서 원하는 2개 필드의 값만 바꾸어서 다시 API 서버로 통채로 던져서 수정하는 방법을 사용했습니다.
JSON 안의 특정 필드 값만 바꾸는 방법은 TJsonPair를 사용하면 간단합니다.
사실 Stack Overflow의 아래에 설명된 대로 하였습니다.
단, Stack Overflow에서 알려준 코드에서 JSON페어.JsonValue.Free; 코드가 없어야 작동합니다.(Delphi 10.3.3 버전 기준)
https://stackoverflow.com/questions/33426576/
[작성된 실전 코드 중 해당 부분 발췌 (Delphi 10.3.3 버전 기준)]
uses
..., System.JSON;
procedure TfrmMainForm.PriceBatchUpdate;
var
JOProductU: TJSONObject;
JOPair: TJSONPair;
begin
//상품코드를 이용하여 상품 데이터를 TJsonObject로 받아온다.
JOProductU := TProductMgmt.GetProductUByProductCodeJSON(ProductCode);
//TJsonPair로 원하는 필드를 가진 TJsonPair를 잡는다 (기본판매가: DefaultSellPrice 필드)
//가장 바깥에 있는 필드라면, 이렇게 바로 잡아낸다.
JOPair := JOProductU.Get('DefaultSellPrice');
PriceDefaultSellUOld := JOPair.JsonValue.Value; //기본판매가 값을 기록해둔다.(로그용)
JOPair.JsonValue := TJSONNumber.Create(10); //기본판매가 값을 10으로 바꾼다.
//TJsonPair로 원하는 필드를 가진 TJsonPair를 잡는다 (T1판매가: SellPriceTier 필드 안에 있는 Value라는 필드)
//이런 식으로 얼마든지 안쪽 깊이 들어 있는 필드도 잡을 수 있다.
JOPair := JOProductU.GetValue<TJSONObject>('SellPriceTier1').Get('Value');
PriceSell1UOld := JOPair.JsonValue.Value; //T1판매가 값을 기록해둔다.(로그용)
JOPair.JsonValue := TJSONNumber.Create(15); //T1판매가 값을 15으로 바꾼다.
...
//TJsonObject인 JOProductU에서 원하는 값을 위 방법으로 이미 교체했으므로, 그대로 서버에 보낸다. 끝.
dmUnleashedAccess.UpdateProduct(ProductIDU,JOProductU);
end;
(델파이 초보입니다. 더 좋은 코드나 제안이 있으면, 댓글로 가르침을 주세요. 미리 환영합니다)
외부 솔루션 연동 할때 enterprise connector 사용하면 딱인데.... 찾아보니 unleashed는 지원을 안하네요
지원만 되었다면 API가 변경이 되던 말던 신경안써도 될텐데 말이죠.
https://www.embarcadero.com/products/enterprise-connectors/enterprise-connectors