Stephen Ball 블로그 중에 REST API 클라이언트 개발에 도움이 될만한 글이라 생각되어 번역해보았습니다.

REST API 클라이언트 구현 마스터-디테일 관계 구현에 도움이 될것입니다.

 

·         링크https://delphiaball.co.uk/2019/12/04/master-detail-data-in-rad-server-using-temsdatasetresource/

 

글은 ‘REST 서버와 클라이언트 개발하기 번째 편입니다TEMSDataSetResource 컴포너트 사용하여  RAD 서버의 마스터-디테일 데이터를 구현하는 방법에 대해서 다루도록 하겠습니다.

 

앞선 글에서REST서버를 만들고 YAML 이용하여 API 전체 도튜멘테이션 제공했습니다. 당시 우리는 데이터  3개를 사용했습니다. 앞선 글과 비디오를 보지 못했다면, 1편부터 시작하기를 권장합니다세번째 편에서는 델파이로 멀티 플랫폼 클라이언트를 작성하여 여기에서 만든 API 사용해보기로 하겠습니다.

 

RAD 서버의 마스터-디테일 데이터

 

TEMSDataSetResource 컴포넌트 RAD 서버에서 데이터셋(DB 테이블)에 대한 JSON 처리 작업을 자동화하여  REST API 전체 도큐멘트를 신속하게 개발할 수있는 매우 강력한 컴포넌트입니다.  TEMSDataSetResource 기존의 마스터-디테일 관계 구성과 함께 사용하면 코드없이 REST 통해  자동으로 문서화 있습니다.

 

글에서는 코드없이 마스터-디테일 데이터를 구현하는 방법과  내부 호출로 보다 자세한 디테일 정보 다루기 위해 고유 REST 엔드 포인트를 다루는 방법에 대해서도 설명합니다.

 

이전 글에서는 백엔드 서비스 API 빌드 도큐멘테이션을  있는 방법으로 RAD 서버의 새로운 WebFiles 기능 (10.3.2부터) 사용하여 Swagger UI 시작하는 방법 대한 자료를 업데이트했습니다. 해당 게시물에서 작성된 샘플 애플리케이션을 기반으로 작성하겠습니다.

 

 

Youtube에서 바로보기:https://youtu.be/gKs-ZSdG94I

 

 

마스터-디테일 데이터 기본 연결

 

RAD Studio / Delphi / C ++ Builder에서 마스터-디테일의 기본 연결 방법은 델파이 1부터 변경되지 않았습니다.

 

·         마스터와 디테일의 개의 데이터 셋이 있습니다.

 

·        TDataSource 마스터 데이터 셋에 연결되어 있습니다.

 

·        디테일의  TDataSource 지정하여 현재 레코드를 읽을 위치를 식별합니다.

 

·        디테일에서 Mater Field(s) 설정합니다.

 

설정은 마스터를 검색할 디테일에서 마스터의 키와 일치하는 레코드들을 필터링합니다.

 

( 자세히 알고 싶으시다면  비디오에서 2:20부터 시청하십시오.

 

REST를 통한 마스터-디테일 데이터 

 

REST API 마스터-디테일 데이터를 표시하려면 3-4 단계가 필요합니다.

 

1. TEMSDataSetResource 연결 – 데이터 셋을 REST API로 접근 할 수 있는 리소스로 변환합니다.

 

TEMSDataSetResource.png

TEMSDataSetResource는 허용 액션(Allowed Action)중에  List  Get 허용하며, 데이터 셋과 연결되어 있습니다.

 

2. 리소스에 액세스하기 위해 호출 엔드 포인트 정의이것은 ResourceSuffix 속성을 통해 수행됩니다.

아래 예는 위의 비디오에서 리소스 exams의   가지 엔드 포인트를 보여줍니다.

 

[ResourceName('exams')]

TExamResource1 = class(TDataModule)[ResourceSuffix('./')]

[ResourceSuffix('List', './')]

[ResourceSuffix('Get', './{EXAM_ID}')]

[ResourceSuffix('Put', './{EXAM_ID}')]

[ResourceSuffix('Delete', './{EXAM_ID}')]

dsrEXAM: TEMSDataSetResource;

 

[ResourceSuffix('./{EXAM_ID}/questions')]

[ResourceSuffix('List', './')]

[ResourceSuffix('Get', './{QUESTION_ID}')]

[ResourceSuffix('Put', './{QUESTION_ID}')]

[ResourceSuffix('Delete', './{QUESTION_ID}')

dsrQuestions: TEMSDataSetResource;

 

[ResourceSuffix('./{EXAM_ID}/questions/{QUESTION_ID}/answers')]

[ResourceSuffix('List', './')]

[ResourceSuffix('Get', './{ANSWER_ID}')]

[ResourceSuffix('Put', './{ANSWER_ID}')]

[ResourceSuffix('Delete', './{ANSWER_ID}')]

dsrAnswers: TEMSDataSetResource;

 

번째 ResourceSuffix 호출 엔드 포인트를 보여줍니다. 그런 다음 뒤에 나오는  다른 이름의 매개 변수는 특정 항목을 요청하기 위해해당 호출에 추가 내용을 표시합니다. : exam1 question2 있다고 가정하면 다음과 같은 엔드 포인트가 제공됩니다.

 

/exams/   exams 목록
/exams/1/ Exam 1
/exams/1/questions/ Exam 1 대한 질문목록
/exams/1/questions/2/ Question ID 2 ( Exam 1 부분)
/exams/1/questions/2/answers/ Question 2 대한 답변

 

3. 엔드 포인트가 정의되면 필드를 엔드 포인트에 연결하여 타임시 매개 변수로 사용 합니다.

 

TEMSDataSetResource_KeyFields.png

 

4. 선택적으로, 속성을 통해  – ResourceSuffix 나열된   매개 변수에 대한 속성을 추가하여-신속하게 출력되는 문서 정의하십시오.

 

사용자 정의 REST 엔드  포인트를 이용한 마스터-디테일

 

TEMSDataSetResource컴포넌트는 훌륭하지만 원래 API 호출에대해 List(목록)과 Get(상세)의 항목은 동일하게 제공됩니다.: 번의 API 호출을 하지 않고 고객(마스터)의 활성화된 주문내용(디테일)을 받습니다.

 

예를 들어, 하나의 시험에 90 개의 질문이 있는  시험 문제가 있다고 가정하겠습니다. 각 질문에는 2-4 개의 답변이 있습니다. 90 개의 질문이 있으므로  초기 호출에 지정된 데이터셋의 데이터를 JSON으로 제공(List, Get)하고, 요청한 JSON 데이터를 데이터셋에 적용(Post, Put, Delete)할 수 있는 90 개의 API가 호출됩니다.

 

이렇게 하기 위해 사용자 정의 Get 메소드를 작성할 수 있습니다. 이전과 유사한 절차를 따릅니다.

 

[힌트] File > New > Other 메뉴에서 새 리소스를 만든 다음 RAD 서버 메뉴에서 RAD 서버 패키지를 선택하는 것이 가장 간단합니다. 위저드에서 생성 할 샘플 엔드 포인트를 선택하십시오. 그런 다음 수정할 수 있습니다.

 

REST API 엔드 포인트 정의

[ResourceSuffix('./{EXAM_ID}/questionsfull/')]

 

[EndPointRequestSummary('Exams', 'Exam Questions and Answers',

'Retrieves list of Questions for an exam, with the multiple-choice answers.',

'application/json', '')]

 

[EndPointRequestParameter(TAPIDocParameter.TParameterIn.Path,

'EXAM_ID', 'EXAM_ID from the /exams/ end point', true,

TAPIDoc.TPrimitiveType.spInteger,

TAPIDoc.TPrimitiveFormat.None, TAPIDoc.TPrimitiveType.spInteger, '', '')]

 

[EndPointResponseDetails(200, 'Ok',

TAPIDoc.TPrimitiveType.spObject,

TAPIDoc.TPrimitiveFormat.None, '', '')]

 

procedure Get(const AContext: TEndpointContext; const ARequest:

        TEndpointRequest; const AResponse: TEndpointResponse)

 

위의 예는 엔드 포인트 / exams / 1 / questionsfull /을 보여줍니다. 데이터 모듈의 리소스 이름 ('exams')이 다시 루트로 사용되며 ResourceSuffix가 엔드 포인트를 정의합니다.

 

REST 데이터 패킷을 수동으로 빌드

 

데이터를 내보내려면 다음 단계를 수행해야 합니다.

 

  1.  전달되는 매개 변수 가져 오기

  2.  데이터 셋 매개 변수를 설정하고 데이터 셋를 오픈합니다 (잘못된 매개 변수로 인한 모든 오류처리)

  3.  응답 JSON을 작성합니다.

 

 전달되는 매개 변수 가져 오기 

 

LItem := ARequest.Params.Values['EXAM_ID'];

 

매개 변수 이름으로 구하면 문자열 값을 반환합니다.

 

쿼리의 매개 변수를 설정하고 쿼리를 오픈합니다.

 

QryQuestions.Close;

 

try

   qryQuestions.ParamByName('EXAM_ID').AsString := LItem;

   qryQuestions.Open();

   qryAnswers.Open();

except // This raises the default not found error

   AContext.Response.RaiseNotFound('','Invalid EXAM_ID');

   Exit;

end;

 

사용자가 매개변수로 어떤 데이터를 넘길 지 모르기 때문에 매개 변수를 잘못 사용하였는지 체크하는 것이 중요합니다.

 

응답(Response) JSON 빌드 

 

이제 출력을 만들 차례입니다. AResponse.Body의 일부인 JSONWriter을 사용하여 간단하게 작성합니다. 예를 들면

 

AResponse.Body.JSONWriter.WriteStartArray;

AResponse.Body.JSONWriter.WriteStartObject;

AResponse.Body.JSONWriter.WritePropertyName('foo');

AResponse.Body.JSONWriter.WriteValue('bar');

AResponse.Body.JSONWriter.WriteEndObject;

AResponse.Body.JSONWriter.WriteEndArray;

 

비디오에서 출력을 만들기 위해 쿼리 데이터 셋에서 필드들을 루핑 처리하면서  ANSWERS라는 이름으로 배열로 추가하고 현재 디테일 정보를 반복처리합니다. 비디오 16시 15 분부터 보시기 바랍니다.

 

qryQuestions.First;

 

while not qryQuestions.Eof do begin

   // Build Question 

   AResponse.Body.JSONWriter.WriteStartObject; 

   ConvertRecordToJSONObject(qryQuestions); 

   // Answers for the question 

   AResponse.Body.JSONWriter. 

   WritePropertyName('ANSWERS'); 

   AResponse.Body.JSONWriter.WriteStartArray; 

 

   qryAnswers.First; 

   while not qryAnswers.Eof do begin 

       AResponse.Body.JSONWriter.WriteStartObject;   

       ConvertRecordToJSONObject(qryAnswers,   'QUESTION_ID');      

       AResponse.Body.JSONWriter.WriteEndObject;   

       qryAnswers.Next;   

   end; 

 

AResponse.Body.JSONWriter.WriteEndArray; 

AResponse.Body.JSONWriter.WriteEndObject; 

qryQuestions.Next; 

end;

AResponse.Body.JSONWriter.WriteEndArray;.

 

위 코드는 인라인 프로 시저를 사용합니다 ( var 뒤에 Get 프로시저 시작하기 전에 선언됩니다).

데이터 셋을 루프 처리하면서 필드 이름과 값을 현재 JSON 개체에 넣습니다.

 

procedure TExamResource1.Get(

  const AContext: TEndpointContext;

  const ARequest: TEndpointRequest; 

  const AResponse: TEndpointResponse);

var

  LItem: string;

procedure ConvertRecordToJSONObject(DataSet : TDataSet; MasterField : string = '');

var

  FieldIdx : Integer;

begin

  for FieldIdx := 0 to DataSet.FieldCount -1 do

  begin

  // Skip master field

  if (MasterField > '') and 

     (Uppercase(MasterField) = Uppercase(DataSet.Fields[FieldIdx].FieldName)) then

    Continue;

 

  // Add name value pairs

  AResponse.Body.JSONWriter.WritePropertyName(DataSet.Fields[FieldIdx].FieldName);

  AResponse.Body.JSONWriter.WriteValue(DataSet.Fields[FieldIdx].AsString);

  end;

end;

 

begin 

<main method code from above>

end;

 

/ exams / 1 / questionsfull /의  응답의 결과 출력은  아래와 같이 마스터-디테일을 포함합니다.

 

MasterDetail-Response-for-QuestionsFull.png

 

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 14387
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13023
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 15532
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 21064
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 22297
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 17933
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 38228
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 173741
1183 [고객사례-사물인터넷, 앱, 델파이] 로봇청소기 제어 앱 '니토 툴리오' 관리자 2020.03.24 369
1182 RAD Studio 10.3.3 안드로이드 앱에서 센서 컴포넌트 사용시 링크 오류 해결방법 김원경 2020.03.18 343
1181 [델파이 안드로이드 64비트 오류 수정] TInAppPurchase 컴포넌트 수정 file 김원경 2020.03.18 335
1180 [기술백서] 다양한 팀 '협업' 방법론과 개발 방식 관리자 2020.03.18 643
1179 RAD Studio IDE에 툴 추가하기 file 김원경 2020.03.17 329
1178 RAD 서버 : 웹 속성을 폴더에 매핑하기 file 김원경 2020.03.17 1534
1177 델파이 개발자 관점에서 본 윈도우 개발 file 김원경 2020.03.13 700
1176 C++ 언어와 C++빌더의 23년! 관리자 2020.03.13 569
1175 MS 비주얼 스튜디오 C++을 C++빌더와 함께 활용하기 관리자 2020.03.12 527
1174 Swagger / YAML 및 RESTful API의 자체 문서화 김원경 2020.03.11 1588
1173 [고객사례-유틸리티, 델파이] Navuu 관리자 2020.03.09 330
1172 [고객사례-유틸리티, 델파이] SupRemo - 개인방송, 화상회의 솔루션 관리자 2020.03.09 817
1171 RAD 서버에 Swagger UI 임베이딩 김원경 2020.03.09 527
1170 검사(Audits)와 측정(Metrics) 기능을 이용 소스코드 표준과 규약 준수를 측정하고 개선할 수 있습니다. 험프리 2020.03.06 281
» TEMSDataSetResource 컴포넌트를 사용하여 RAD 서버의 마스터-디테일 데이터 구현하기 file 김원경 2020.03.06 403
1168 RESTful 마스터-디테일 데이터를 사용하는 클라이언트 애플리케이션을 TRESTResponseDataSetAdapter를 사용하여 개발하기 file 험프리 2020.03.03 507
1167 [10.4 프리뷰] 베타 서비스 시작 & 새 기능 미리 보기 관리자 2020.03.03 1605
1166 델파이 25주년 기념 무료 크로스 플랫폼 샘플 앱 25개 선정(델파이/C++ 샘플 150여종) 험프리 2020.03.02 659
1165 윈도우 10에서의 High DPI 김원경 2020.03.02 1248
1164 이 달의 기술자료 - 2020년 03월 file 험프리 2020.02.28 271