이 글에서는 델파이를 이용해 REST API 서버와 연동하는 클라이언트 기술을 실습합니다.

REST 클라이언트 라이브러리 기반으로 실습합니다.

REST API 엔드포인트 연동

 

이 글에서는 REST API 서버의 REST API를 분석하고, 클라이언트에 표시 및 입력데이터를 서버에 저장하는 내용을 실습 위주로 진행합니다.

이 글에서는 데이터 처리하는 내용에 집중합니다. 이 글을 참고해 여러분이 만든 멋진 화면과 REST API를 연동하는 기술을 습득하시기 바랍니다.

 

이 글에 앞서 다음 내용의 이해가 필요합니다. 미리 선행 학습하시기 바랍니다.

 

이 글에서는 다음 내용을 다룹니다.

 

REST API 분석

이 글에서는 아래 링크에서 제작한 도서정보 REST API 서버를 대상으로 분석 및 연동합니다.

 

 

도서정보 REST API 서버에서 제공하는 엔드포인트는 아래와 같습니다. {item}에는 도서정보 아이디로 치환해야 합니다.

 엔드포인트

 역할

  데이터 포맷

 GET http://localhost:8080/books/

 도서정보 목록 조회

 응답: application/json

 GET http://localhost:8080/books/{item}/

 도서정보 상세 조회

 응답: application/json

 GET http://localhost:8080/books/{Item}/photo/

 도서정보 사진 조회

 응답: image/jpg

 POST http://localhost:8080/books/

 도서정보 생성

 요청 : application/json(Body)

 PUT http://localhost:8080/books/{item}/

 도서정보 수정

 요청 : application/json(Body)

 DELETE http://localhost:8080/books/{item}/

 도서정보 삭제  

 

REST API 분석은 REST Debugger(실행: Tools > REST Debugger 메뉴)를 이용합니다.

REST Debugger 상세정보 - http://docwiki.embarcadero.com/RADStudio/en/REST_Debugger_Tool (자동변역)

 

[실습] REST API 연동

실습에서는 도서대여 REST API 서버와 연동하는 클라이언트 프로그램을 제작합니다.

 

실습을 위해 도서대여 패키지를 포함한 EMS 서버를 실행합니다.

사전 준비사항

프로젝트 생성

클라이언트 프로그램은 델파이 멀티-디바이스 애플리케이션(Multi-Device Application)으로 진행합니다.

 

멀티-디바이스 애플리케이션 프로젝트를 생성(File > New > Multi-Device Application)합니다. 

프로젝트에 델파이 데이터 모듈을 추가(File > New > Other > Delphi Projects > Delphi Files > Data Module)합니다.

 

프로젝트를 저장합니다.(저는 아래와 같은 이름으로 저장했지만 다른 이름으로 저장해도 됩니다.)

 

데이터 모듈 이름을 "dmDataAccess"로 변경합니다. 폼 유닛(MobileForm)에서 데이터 모듈 유닛(DataAccessModule)을 사용할 수 있도록 uses 절에 추가합니다.

 

화면 구성(폼 디자인)

아래 그림을 참고해 화면을 구성합니다.

 

다음을 참고해 컴포넌트 이름을 지정합니다.

  • 버튼(TButton)
    • btnLoadData : 데이터 로드
    • btnNewData :  신규
    • btnDeleteData : 삭제
    • btnSaveData : 저장
  • 에디트(TEdit)
    • edtTtile : 제목
    • edtAuthor : 저자
    • edtISBN : ISBN
    • edtPrice : 가격
    • edtLink : 관련링크
  • 메모(TMemo)
    • mmoDescription : 설명

Get

Get 엔드포인트를 통해 도서정보 목록을 조회합니다.

REST API 분석

REST Debugger에서 아래와 같이 입력합니다.

  • Request 탭
    • Method : Get
    • URL : http://localhost:8080
    • Content-type : application/json
  • Parameters 탭
    • Resource : books

[Send Request] 버튼을 누릅니다.

 

위 이미지와 같이 200 : OK 메시지가 Response 영역에 표시되야 합니다.(200이 아닌 응답 상태 코드를 수신한 경우 EMS 서버 실행여부 또는 URL 등을 확인하시기 바랍니다.)

 

Response 영역의 Headers 탭과 Body탭을 통해 데이터 수신을 확인합니다.

JSON 데이터를 확인해, JSON 배열([])로 구성된 속성을 확인해 JSON Root Element에 입력 후 [Apply] 버튼을 클릭(또는 엔터)합니다.

 

Tabular Data 탭에 배열의 데이터가 테이블 형식으로 표시됩니다.

 

[Copy Components] 버튼을 눌러 분석한 데이터를 클립보드로 복사합니다.(이 컴포넌트는 개발에 직접 사용합니다.)

 

REST API 연동 구현

데이터 모듈에 붙여넣기(Ctrl + V) 후 아래 그림을 참고해 이름을 변경합니다.

 

각 컴포넌트의 역할과 주요 속성

  • TRESTClient - 서버 정보 설정
    • BaseURL : 서버 기본 URL
  • TRESTRequest - 요청할 정보 설정 및 요청 작업 수행
    • Client : TRESTClient 지정
    • Method : 요청 시 HTTP 메소드 종류
    • Resource : REST API 리소스 지정(URI에서 BaseURL 제외한 영역), 파라메터는 중괄호({})로 지정
    • Params : Resource에 포함된 파라메터 값 정
    • Response : 응답 객체(TRESTResponse) 지정
  • TRESTResponse - 요청의 응답 정보 보관
    • Content : 응답받은 데이터(string)
    • RootElement : 응답 데이터 중 필요한 항목 지정
  • TRESTResponseDataSetAdapter - 응답 데이터를 데이터셋으로 변환
    • Response : 변환 대상 응답데이터
    • Dataset : 변환한 데이터를 기록할 데이터 셋(TDataSet을 상속받은 메모리 테이블, TFDMemTable 또는 TClientDataSet 등)
    • RootElement : 응답 데이터 중 변환할 항목 지정
  • TFDMemTable - 메모리 테이블

reqList 컴포넌트 팝업메뉴에서 Execute 메뉴를 눌러 연결을 확인하고 데이터를 가져옵니다.

이 작업은 REST API 서버의 데이터를 받아 메모리테이블(TFDMemTable)에 데이터를 로드합니다. 이 데이터를 기반으로 메모리 테이블의 필드 정보를 표시하고, UI 컨트롤에 데이터를 표시합니다. 델파이에서 프로젝트를 새로 열었다면, 위 작업을 다시 시도해 데이터를 메모리 테이블에 로드해야 합니다.

 

폼의 [데이터 로드] 버튼 클릭 이벤트에 아래 코드를 구현합니다.

dmDataAccess.reqList.Execute;

 

도서목록 데이터를 그리드에 표시하기 위해 라이브 바인딩 디자이너 표시(View > Tool Windows > LiveBindings Designer) 후 아래 그림을 참고해 데이터와 UI컨트롤을 바인딩 합니다.

 

프로젝트를 실행하고, [데이터 로드] 버튼을 눌러 그리드에 정보가 표시되는 것을 확인합니다.

 

GetItem

GetItem 엔드포인트를 통해 도서정보 목록을 조회합니다.

REST API 분석

REST Debugger에서 아래와 같이 입력합니다.

  • Request 탭
    • Method : Get
    • URL : http://localhost:8080
    • Content-type : application/json
  • Parameters 탭
    • Resource : books/{item}/
    • Request parameters : item 항목에 도서정보 아이디 값 입력

[Send Request] 버튼을 누릅니다.

 

응답 데이터 확인 후 JSON Root Element에 "book" 입력 후 [Apply] 버튼을 누르고, Tabular Data 탭에서 데이터 표시를 확인합니다.

 

[Copy Components] 버튼을 누릅니다.

 

REST API 연동 구현

데이터 모듈에 붙여넣기 후 아래와 같이 이름을 변경합니다.

 

 TRESTClient는 재사용합니다. RESTClient2 컴포넌트를 제거합니다. reqDetail.Client 항목을 RESTClient1으로 지정합니다.

 

reqDetail 컴포넌트 팝업메뉴에서 Execute 메뉴를 눌러 데이터를 가져옵니다.

 

폼에서 라이브 바인딩 디자이너를 표시하고, 아래 그림을 참고해 바인딩합니다.

 

private 영역에 아래 변수와 메소드 추가 후 자동 완성(Shift + Ctrl + C)으로 구현부를 생성합니다.

private

  FSelectedSeq: Integer;

  procedure RequestDetail(ASeq: Integer);

  procedure LoadPhoto(ASeq: Integer);

  procedure ClearControls;

 

 

그리드의 OnSelChanged 이벤트(그리드 셀 변경)를 추가후 아래 코드를 구현합니다.

procedure TForm1.Grid1SelChanged(Sender: TObject);

var

  Seq: Integer;

begin

  if dmDataAccess.memBookList.RecordCount = 0 then

    Exit;

 

  Seq := dmDataAccess.memBookList.FieldByName('BOOK_SEQ').AsInteger;

  RequestDetail(Seq);

end;

 

procedure TForm1.ClearControls;

begin

  dmDataAccess.memBookDetail.EmptyDataSet;

  ImageControl1.Bitmap.Assign(nil);

end;

 

procedure TForm1.RequestDetail(ASeq: Integer);

begin

  FSelectedSeq := ASeq;

 

  ClearControls;

 

  dmDataAccess.reqDetail.Params.ParameterByName('item').Value := ASeq.ToString;

  BindSourceDB2.DataSource.Enabled := False;

  dmDataAccess.reqDetail.ExecuteAsync(procedure

  begin

    BindSourceDB2.DataSource.Enabled := True;

  end);

 

  LoadPhoto(ASeq);

end;

 

procedure TForm1.LoadPhoto(ASeq: Integer);

begin

end;

 

LoadPhoto 메소드는 아래에서 구현합니다.


GetItem - 이미지 수신

REST API 연동 구현

이미지 수신, 생성, 수정, 삭제에 공통으로 사용할 컴포넌트를 데이터 모듈에 추가합니다.

 

RESTRequest의 Client 항목을 RESTClient1으로 Reponse 항목을 RESTResponse로 지정합니다.

 

LoadPhoto 메소드에 아래와 같이 구현합니다.(TRESTRequestMethod는 REST.Types에 선언되어 있습니다. uses 절에 REST.Types를 추가하세요.)

procedure TForm1.LoadPhoto(ASeq: Integer);

var

  Stream: TMemoryStream;

begin

  dmDataAccess.RESTRequest.Method := TRESTRequestMethod.rmGET;

  dmDataAccess.RESTRequest.Resource := '/books/{item}/photo/';

  dmDataAccess.RESTRequest.Params.ParameterByName('item').Value := ASeq.ToString;

  dmDataAccess.RESTRequest.ExecuteAsync(procedure

    begin

      if dmDataAccess.RESTResponse.StatusCode = 404 then

        Exit;

      Stream := TMemoryStream.Create;

      try

        Stream.WriteData(dmDataAccess.RESTResponse.RawBytes, dmDataAccess.RESTResponse.ContentLength);

        ImageControl1.Bitmap.LoadFromStream(Stream);

      finally

        Stream.Free;

      end;

    end);

 

end;

프로젝트를 실행하고, 그리드를 변경해 상세 데이터 및 이미지 표현을 확인합니다.

Post / PutItem / DeleteItem

신규, 저장, 삭제 기능을 구현합니다.

REST API 연동 구현

데이터 모듈에서 데이터셋의 데이터를 JSON으로 반환하는 메소드를 작성합니다. 이 메소드는 Post, PutItem 엔드포인트 호출 시 사용합니다.

 

데이터 모듈의 uses 절에 "System.JSON, System.JSON.Writers"을 추가합니다.

 

아래 코드를 참고해, GetBookData 메소드를 정의하고, 구현합니다.

function TdmDataAccess.GetBookData: TJSONObject;

var

  Writer: TJsonObjectWriter;

begin

  Writer := TJsonObjectWriter.Create(False);

  try

    Writer.WriteStartObject;  // start resource

    Writer.WritePropertyName('book');

 

    Writer.WriteStartObject;  // start item

    Writer.WritePropertyName('BOOK_TITLE');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_TITLE').AsString);

 

    Writer.WritePropertyName('BOOK_ISBN');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_ISBN').AsString);

 

    Writer.WritePropertyName('BOOK_AUTHOR');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_AUTHOR').AsString);

 

    Writer.WritePropertyName('BOOK_PRICE');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_PRICE').AsString);

 

    Writer.WritePropertyName('BOOK_LINK');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_LINK').AsString);

 

    Writer.WritePropertyName('BOOK_DESCRIPTION');

    Writer.WriteValue(memBookDetail.FieldByName('BOOK_DESCRIPTION').AsString);

 

    Writer.WriteEndObject;  // end item

    Writer.WriteEndObject;  // end resource

 

    Result := Writer.JSON as TJSONObject;

  finally

    Writer.Free;

  end;

end;

 

[신규], [삭제], [저장] 버튼의 이벤트에 아래 코드를 작성합니다.

procedure TForm1.btnNewDataClick(Sender: TObject);

begin

  FSelectedSeq := -1;

  ClearControls;

end;

 

procedure TForm1.btnSaveDataClick(Sender: TObject);

var

  Data: TJSONObject;

begin

  if FSelectedSeq = -1 then

  begin

    dmDataAccess.RESTRequest.Method := TRESTRequestMethod.rmPOST;

    dmDataAccess.RESTRequest.Resource := '/books/';

  end

  else

  begin

    dmDataAccess.RESTRequest.Method := TRESTRequestMethod.rmPUT;

    dmDataAccess.RESTRequest.Resource := '/books/{item}/';

    dmDataAccess.RESTRequest.Params.ParameterByName('item').Value := FSelectedSeq.ToString;

  end;

  dmDataAccess.RESTRequest.ClearBody;

  Data := dmDataAccess.GetBookData;

  dmDataAccess.RESTRequest.Body.Add(Data);

  dmDataAccess.RESTRequest.Execute;

 

  ShowMessage('저장');

end;

 

procedure TForm1.btnDeleteDataClick(Sender: TObject);

begin

  dmDataAccess.RESTRequest.Method := TRESTRequestMethod.rmDELETE;

  dmDataAccess.RESTRequest.Resource := '/books/{item}/';

  dmDataAccess.RESTRequest.Params.ParameterByName('item').Value := FSelectedSeq.ToString;

  dmDataAccess.RESTRequest.Execute;

 

  ShowMessage('삭제');

end;

 

위 코드와 같이 단순한 요청, 응답의 경우 컴포넌트를 재사용 하는 것도 좋은 방법입니다.

 

완성된 프로젝트 파일

 RESTAPI_Client.zip


 

번호 제목 글쓴이 날짜 조회 수
공지 [DelphiCon 요약] 코드사이트 로깅 실전 활용 기법 (Real-world CodeSite Logging Techniques) 관리자 2021.01.19 15432
공지 [UX Summit 요약] 오른쪽 클릭은 옳다 (Right Click is Right) 관리자 2020.11.16 13961
공지 [10.4 시드니] What's NEW! 신기능 자세히 보기 관리자 2020.05.27 16498
공지 RAD스튜디오(델파이,C++빌더) - 고객 사례 목록 관리자 2018.10.23 22054
공지 [데브기어 컨설팅] 모바일 앱 & 업그레이드 마이그레이션 [1] 관리자 2017.02.06 23268
공지 [전체 목록] 이 달의 기술자료 & 기술레터 관리자 2017.02.06 18922
공지 RAD스튜디오(델파이, C++빌더) - 시작하기 [1] 관리자 2015.06.30 39253
공지 RAD스튜디오(델파이,C++빌더) - 모바일 앱 개발 사례 (2020년 11월 업데이트 됨) 험프리 2014.01.16 174698
1342 [DelphiCon 요약] 델파이로 웹 다루기 (Powering the Web with Delphi) file 관리자 2021.02.16 1117
1341 [고객 사례- POS, C++빌더] YG-POS - 소상공인을 위한 무료 소프트웨어 관리자 2021.02.08 649
1340 [고객 사례- 금융, 델파이] 주식, 화폐 등 금융 정보 분석 소프트웨어 - 게임스탑, 비트코인, 아마존, 구글 등 관리자 2021.02.04 627
1339 ‘장기 활용 가능성’이 가장 뛰어난 프레임워크는? (델파이 VS. WPF VS. ELECTRON) 관리자 2021.02.01 462
1338 [델파이 웹개발] 델파이로 풀스택 웹 개발하기 - uniGUI 활용 (Full Stack Web Development with uniGUI for Delphi) file 관리자 2021.02.01 4290
1337 버전별 업데이트된 주요 기능들 (C++빌더6 / 델파이7부터 최신 버전까지!) 관리자 2021.01.29 376
1336 이 달의 기술자료 - 2021년 02월 file 험프리 2021.01.26 510
1335 [샘플 프로젝트] 심박 측정기-델파이/C++빌더와 IOT 연동하기 관리자 2021.01.25 459
1334 C++ 유니코드 문자열 리터럴(Unicode String Literal) 활용 방법 관리자 2021.01.22 449
1333 C++빌더 마이그레이션, C++ 프로젝트를 간편하게 업데이트 하는 방법 관리자 2021.01.19 310
1332 [고객 사례- 델파이, 게임] 체스 오프닝 위저드 - 60,000여명의 체스 플레이어가 실제로 사용하는 앱 관리자 2021.01.18 713
1331 생산성을 끌어올려줄 겟잇(GetIt)의 최신 컴포넌트들 관리자 2021.01.18 513
1330 [DelphiCon 요약] High DPI 고해상도를 VCL에서 활용하기 (Leveraging High DPI in VCL Applications) 관리자 2021.01.13 767
1329 [DelphiCon 요약] Spring4D 소개 - 델파이 개발을 한수준 높이기 (Introduction to Spring4D - Taking Delphi Development to the Next Level) 관리자 2021.01.08 1146
1328 새해 목표: LEARN, TEACH, REPEAT. 관리자 2021.01.05 315
1327 [DelphiCon 요약] 델파이로 함수형 프로그래밍하기 (Functional Programming With Delphi) 관리자 2020.12.29 710
1326 [DelphiCon 요약] 델파이 고성능 구현 (High Performance Delphi) 관리자 2020.12.27 900
1325 [TOP 10] 2020년 하반기, 개발자가 사랑한 기술자료는? 관리자 2020.12.24 353
1324 이 달의 기술자료 - 2021년 01월 file 험프리 2020.12.24 412