RAD 스튜디오 10.2 버전 부터 EMS 패키지 대신 RAD 패키지로 이름이 변경되었습니다. 구현하는 방식은 동일합니다.

 

이 글에서는 델파이를 이용해 REST API 엔드포인트를 제공하는 서버 제작 기술을 학습합니다.

RAD 서버의 EMS 패키지 프로젝트로 진행합니다.

 

REST API 엔드포인트

rest_endpoint.png

리소스에 HTTP 메소드 요청 시 처리하도록 구현해 놓은 것을 REST API 엔드포인트라고합니다.

 

REST는 GET, POST, PUT, DELETE 4개의 HTTP 메소드 지원을 원칙으로하며, 그 중 지원할 HTTP 메소드를 지정 및 구현해 REST API를 제공합니다. 즉 리소스에 따라 필요한 HTTP 메소드에 한해 엔드포인트를 제공할 수 있습니다.

 

이 글에서는 RAD 서버를 이용해 리소스를 생성하고, 엔드포인트를 작성하는 실습을 진행합니다.

실습의 주제는 도서정보를 제공하는 REST API를 개발합니다.

 

실습에서 사용하는 데이터베이스는 도서대여 프로그램 만들기에서 사용한 데이터베이스를 사용합니다. 다음 링크의 참고 링크에서 다운로드 받으시기 바랍니다.

 

이 글에 앞서 다음 내용을 이해하고 있어야 합니다. 미리 선행 학습하시기 바랍니다.

 

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

 

EMS 패키지 프로젝트 시작하기

EMS 패키지 프로젝트를 이용해 REST API 리소스와 엔드포인트를 개발할 수 있습니다.

 

EMS 패키지를 생성하고, 실행하는 내용은 다음 링크를 통해 선행 학습하시기 바랍니다.

 

EMS 패키지 프로젝트 생성

"books" 이름으로 리소스 이름을 지정하고 파일유형으로 Data Module을 선택 합니다.

create_emspackage_resource.png

 

 

엔드포인트를 모두 선택 합니다.

create_emspackage_methods.png

 

 

프로젝트를 생성하면 아래와 같은 코드가 자동 생성됩니다.

 

emspackage_init_interface.png

 

[ResourceName('books')]

리소스 이름을 지정하는 특성 구문으로, 아래의 클래스(TBooksResource1)의 리소스 이름을 지정합니다.

이 이름은 URI에 사용되며, URI(http://localhost:8080/books/) 요청 시 리소스 이름이 지정된 클래스의 엔드포인트 프로시저를 실행합니다. 이 이름은 코드 상에서 수정할 수 있습니다.

 

[ResourceSuffix('{item}')]

리소스 뒤에 붙는 리소스접미사를 정의하는 특성(Attribute) 구문입니다.

URI(http://localhost:8080/books/100/)에서 리소스 이름 뒤의 영역을 지정합니다.

중괄호({..})로 정의된 항목은 파라메터로 지정되어, 코드로 읽어 올 수 있습니다.

 

예를들어 "http://localhost:8080/books/100/"으로 호출하는 경우, "100"이 접미사이며, 중괄호로 파라메터로 지정된 경우 다음 코드로 값을 가져올 수 있습니다.

ARequest.Params.Values['item'] // 100

 

리소스접미사는 여러 단계로 정의할 수 있습니다. 

[ResourceSuffix('{item}/photo/')]

procedure GetItemPhoto(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

[ResourceSuffix('{item}/{subitem}/')]

procedure GetItemSub(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

 

HTTP 메소드 프로시저

EMS 패키지에서는 Get, GetItem, Post, PutItem, DeleteItem 총 5개의 엔드포인트를 제공합니다.

 엔드포인트

 HTTP 메소드

 리소스 접미사

 Get

 GET

 

 GetItem

 GET

 {item}

 Post

 POST

 

 PutItem

 PUT

 {item}

 DeleteItem

 DELETE

 {item}

 

위 표와 같이, 엔드포인트는 HTTP 메소드, 리소스 접미사와 매핑됩니다. 

Get 을 예로 들면, GET으로 리소스에 요청하면 엔드포인트 Get 프로시저가 호출되고, {item}이 포함되어 GET으로 요청하면 GetItem 프로시저가 호출됩니다.

 

각 엔드포인트의 프로시저는 엔드포인트 이름으로 시작되도록 정의해야합니다. 만약, 같은 엔드포인트가 프로시저가 2개이상 구현된 경우 실행 시 오류가 발생합니다.

 

[실습] REST API 엔드포인트 개발하기

이 장에서는 엔드포인트 별로 기능을 구현하고 실습하는 방법을 안내합니다.

실습에서는 도서대여 프로그램의 데이터베이스를 사용 합니다. 데이터 포맷으로는 JSON을 사용합니다.

 

사전 준비사항

다음 디렉토리 구조로 진행합니다.

 

dir.png

 

도서대여 프로그램 데이터베이스 파일을 DB 디렉토리에 저장합니다.

 

위에서 생성한 EMS 패키지 프로젝트 Source 디렉토리에 저장합니다.

save_dir.png

 

프로젝트 옵션에서 Output 디렉토리를 지정합니다.

out_dir.png

 

 

BookResource 데이터 모듈에 아래와 같이 TFDConnection, TFDQuery 컴포넌트를 추가하고 이름을 변경합니다.

datamodule.png

 

conBookRental(TFDConnection)의 OnBeforeConnect 이벤트 핸들러 생성 후 아래 코드(데이터베이스 파일 경로를 지정)를 추가합니다. uses 절에 System.IOUtils를 추가합니다.

procedure TBooksResource1.conBookRentalBeforeConnect(Sender: TObject);

var

  Path: string;

begin

  Path := TPath.GetFullPath('..\DB\BOOKRENTAL.IB');

  if not TFile.Exists(Path) then

  begin

    raise Exception.Create('Not found database.');

  end;

 

  conBookRental.Params.Values['Database'] := Path;

end;

 

Get / GetItem

리소스에 GET 메소드로 요청하면 Get 또는 GetItem(접미사가 있을 경우)이 호출됩니다. GET 메소드는 조회 역할을 하면 각 엔드포인트는 다음 역할을 구현합니다.

  • Get - 리소스의 목록 정보 조회
  • GetItem - 리소스의 상세 정보 조회

 

Get - 리소스 목록

Get 엔드포인트는 리소스 목록을 조회하는 역할을 합니다. 실습에서는 도서정보 리소스를 구현하므로, 도서 정보 목록을 제공하도록 구현합니다.

 

GET http://localhost:8080/books/

{

  "books":

  {

    "total":6,

    "book":

    [

      {

        "BOOK_SEQ":15,

        "BOOK_TITLE":"델파이 Begin...End",

        "BOOK_AUTHOR":"김원경"

      },     

      {

        "BOOK_SEQ":16,

        "BOOK_TITLE":"한 번에 개발하는 안드로이드 iOS앱 with 델파이. 1편",

        "BOOK_AUTHOR":"김원경 , 김현수, 오상현"

      }

    ]

  }

}

 

Get 엔드포인트에 아래와 같이 구현합니다. JSON 데이터 작성은 TJsonObjectWriter를 이용했습니다. 다른 JSON 라이브러리를 사용해 작성해도 무관합니다.

procedure TBooksResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_LIST ='SELECT BOOK_SEQ, BOOK_TITLE, BOOK_AUTHOR, BOOK_PRICE FROM BOOK';

var

  Writer: TJsonObjectWriter;

begin

  qryBook.Close;

  qryBook.SQL.Text := SQL_LIST;

  qryBook.Open;

 

  Writer := TJsonObjectWriter.Create;

  try

    Writer.WriteStartObject; // start resource

    Writer.WritePropertyName('books');

 

    Writer.WriteStartObject; // start item

    Writer.WritePropertyName('total');

    Writer.WriteValue(qryBook.RecordCount);

 

    Writer.WritePropertyName('book');

    Writer.WriteStartArray;

 

    qryBook.First;

    while not qryBook.Eof do

    begin

      Writer.WriteStartObject;

      Writer.WritePropertyName('BOOK_SEQ');

      Writer.WriteValue(qryBook.FieldByName('BOOK_SEQ').AsInteger);

 

      Writer.WritePropertyName('BOOK_TITLE');

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

 

      Writer.WritePropertyName('BOOK_AUTHOR');

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

 

      Writer.WritePropertyName('BOOK_PRICE');

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

 

      Writer.WriteEndObject;

      qryBook.Next;

    end;

 

    Writer.WriteEndArray;

 

    Writer.WriteEndObject;  // end item

    Writer.WriteEndObject;  // end resource

 

    AResponse.Body.SetValue(Writer.JSON as TJSONValue, True);

  except

    Writer.Free;

    raise;

  end;

end;

 

구현을 마치면, 프로젝트를 실행하고 웹브라우저에서 "http://localhost:8080/books/"를 입력해 JSON 문자열이 화면에 표시되는 것을 확인합니다.

 

 

GetItem - 리소스 상세

GetItem 엔드포인트는 특정 도서의 상세 정보를 제공하도록 구현합니다.

 

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

{

  "book":

  {

    "BOOK_SEQ":15,

    "BOOK_TITLE":"델파이 Begin...End",

    "BOOK_ISBN":"9788996251613",

    "BOOK_AUTHOR":"김원경",

    "BOOK_PRICE":"28000",

    "BOOK_LINK":"http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788996251613&orderClick=LAG&Kc=SETLBkserp1_5",

    "BOOK_DESCRIPTION":"델파이의 시작부터 끝까지 파헤치다!

... (생략)"

  }

}

 

다음과 같이 구현합니다.

procedure TBooksResource1.GetItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_ITEM_INFO = 'SELECT ' +

                    'BOOK_SEQ, BOOK_TITLE, BOOK_ISBN, BOOK_AUTHOR, BOOK_PRICE, ' +

                    'BOOK_LINK, BOOK_DESCRIPTION ' +

                  'FROM BOOK WHERE BOOK_SEQ = :BOOK_SEQ';

 

var

  BOOK_SEQ: string;

  Writer: TJsonObjectWriter;

begin

  BOOK_SEQ := ARequest.Params.Values['item'];

  // Sample code

  qryBook.Close;

  qryBook.SQL.Text := SQL_ITEM_INFO;

  qryBook.ParamByName('BOOK_SEQ').AsString := BOOK_SEQ;

  qryBook.Open;

 

  if qryBook.RecordCount = 0 then

    AResponse.RaiseNotFound('Not found', '''' + BOOK_SEQ + ''' is not found');

 

  Writer := TJsonObjectWriter.Create;

  try

    Writer.WriteStartObject;  // start resource

    Writer.WritePropertyName('book');

 

    Writer.WriteStartObject;  // start item

    Writer.WritePropertyName('BOOK_SEQ');

    Writer.WriteValue(qryBook.FieldByName('BOOK_SEQ').AsInteger);

 

    Writer.WritePropertyName('BOOK_TITLE');

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

 

    Writer.WritePropertyName('BOOK_ISBN');

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

 

    Writer.WritePropertyName('BOOK_AUTHOR');

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

 

    Writer.WritePropertyName('BOOK_PRICE');

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

 

    Writer.WritePropertyName('BOOK_LINK');

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

 

    Writer.WritePropertyName('BOOK_DESCRIPTION');

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

 

    Writer.WriteEndObject;  // end item

    Writer.WriteEndObject;  // end resource

 

    AResponse.Body.SetValue(Writer.JSON as TJSONValue, True);

  except

    Writer.Free;

    raise;

  end;

end;

 

 

구현을 마치고, 프로젝트를 실행하고, 웹브라우저에 "http://localhost:8080/books/{item}/"({item}은 목록의 BOOK_SEQ로 치환합니다.) 입력해 결과를 확인합니다.

 

RESTDebugger - REST API 분석도구

GET 메소드의 경우 웹브라우저로 손쉽게 테스트 해볼 수 있습니다. 테스트 하기 어려운 POST, PUT, DELETE 메소들은 RESTDebugger를 이용해 테스트 할 수 있습니다.

 

RESTDebugger는 Tools > REST Debugger 메뉴를 사용해 실행합니다.

rest_debugger_01.png

Request 탭의 Method(HTTP 메소드), URL, Conentt-type, Custom body 등을 지정 후

 

rest_debugger_02.png

 

Parameters 탭에서 Resource, Request Parameters 항목을 지정 해 [Send Reuqest] 버튼을 눌러 요청합니다.

Resource 항목의 경우 {item}과 같이 중괄호로 지정한 항목이 자동으로 파라메터에 추가됩니다.

 

응답은 Headers와 Body 탭에 정보가 표시됩니다.

 

 

자세한 사용법은 다음 링크를 참고하시기 바랍니다.

 

Post / PutItem / DeleteItem

리소스를 생성, 수정, 삭제합니다. 생성과 수정에 필요한 정보는 요청 시 Custom Body영역에 JSON 포맷으로 전달하도록 구현합니다.

Post - 리소스 생성

Post 엔드포인트는 도서정보를 생성하도록 구현합니다. 도서에 대한 정보는 요청(Request)의 Custom Body에 담긴JSON 데이터를 이용합니다.

 

POST http://localhost:8080/books/

Custom Body

{

  "book":

  {

    "BOOK_TITLE":"테스트",

    "BOOK_ISBN":"1234567890123",

    "BOOK_AUTHOR":"홍길동",

    "BOOK_PRICE":"10000",

    "BOOK_LINK":"",

    "BOOK_DESCRIPTION":"12345."

  }

}

 

 

다음과 같이 구현합니다.

procedure TBooksResource1.Post(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_ITEM_INSERT = 'INSERT INTO BOOK(BOOK_TITLE, BOOK_ISBN, BOOK_AUTHOR, BOOK_PRICE, BOOK_LINK, BOOK_DESCRIPTION)' +

                    '  VALUES (:BOOK_TITLE, :BOOK_ISBN, :BOOK_AUTHOR, :BOOK_PRICE, :BOOK_LINK, :BOOK_DESCRIPTION)';

 

var

  Title, Author, Price, ISBN, Link, Desc: string;

  Json: TJSONValue;

begin

  JSON := ARequest.Body.GetValue;

 

  Title := JSON.GetValue<string>('book.BOOK_TITLE');

  ISBN := JSON.GetValue<string>('book.BOOK_ISBN');

  Author := JSON.GetValue<string>('book.BOOK_AUTHOR');

  Price := JSON.GetValue<string>('book.BOOK_PRICE');

  Link := JSON.GetValue<string>('book.BOOK_LINK');

  Desc := JSON.GetValue<string>('book.BOOK_DESCRIPTION');

  qryBook.Close;

  qryBook.SQL.Text := SQL_ITEM_INSERT;

  qryBook.ParamByName('BOOK_TITLE').AsString := Title;

  qryBook.ParamByName('BOOK_ISBN').AsString := ISBN;

  qryBook.ParamByName('BOOK_AUTHOR').AsString := Author;

  qryBook.ParamByName('BOOK_PRICE').AsString := Price;

  qryBook.ParamByName('BOOK_LINK').AsString := Link;

  qryBook.ParamByName('BOOK_DESCRIPTION').AsString := Desc;

  qryBook.ExecSQL;

end;

 

구현을 마치고, 프로젝트를 실행합니다. REST Debugger에서 아래와 같이 정보 입력해 테스트 합니다. 요청 후 도서 목록(http://localhost:8080/books/)에서 추가된 것을 확인합니다.

post_request.png

 

현재(2017.05) REST Debugger의 Custom Body가 유니코드를 지원하지 않는 버그가 있습니다.(한글을 입력 후 요청 시 캐릭터셋이 맞지 않는 오류가 EMS 패키지에서 발생합니다.)

 

조치방법

1번안 - REST Debugger 소스코드를 수정합니다.

  • C:\Program Files (x86)\Embarcadero\Studio\19.0\source\data\rest\restdebugger\RESTDebugger.dpr(10.2 도쿄 기준) 프로젝트 열기
  • uMain_frm.pas의 762번째 줄을 아래와 같이 수정
    •   memo_RequestBody.Lines.SaveToStream(FRESTParams.CustomBody, TEncoding.UTF8);
  • 컴파일(Project > Options > Delphi Compoiler > Output Directory를 접근 권한이 있는 곳으로 변경)

 

2번안 - 아래 RESTDebugger 실행파일을 다운로드 후 테스트 합니다.

 RESTDebugger.zip

 

PutItem - 리소스 수정

PutItem 엔드포인트는 특정한 도서정보를 수정하도록 구현합니다. 도서의 Id는 리소스 접미사를 이용해 파악합니다. 도서에 대한 정보는 요청(Request)의 Custom Body에 담긴JSON 데이터를 이용합니다.

 

PUT http://localhost:8080/books/{item}/ - {item}은 유효한 도서일련번호로 변경할 것

Custom Body

{

  "book":

  {

    "BOOK_TITLE":"테스트 수정",

    "BOOK_ISBN":"1234567890123",

    "BOOK_AUTHOR":"홍길동",

    "BOOK_PRICE":"10000",

    "BOOK_LINK":"",

    "BOOK_DESCRIPTION":"12345."

  }

}

 

다음과 같이 구현합니다.

procedure TBooksResource1.PutItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_ITEM_UPDATE = 'UPDATE BOOK SET ' +

                    '  BOOK_TITLE = :BOOK_TITLE,' +

                    '  BOOK_ISBN = :BOOK_ISBN, ' +

                    '  BOOK_AUTHOR = :BOOK_AUTHOR,' +

                    '  BOOK_PRICE = :BOOK_PRICE,' +

                    '  BOOK_LINK = :BOOK_LINK, ' +

                    '  BOOK_DESCRIPTION = :BOOK_DESCRIPTION ' +

                    ' WHERE ' +

                    '  BOOK_SEQ = :BOOK_SEQ';

 

var

  BOOK_SEQ: string;

  Title, Author, Price, ISBN, Link, Desc: string;

  Json: TJSONValue;

begin

  BOOK_SEQ := ARequest.Params.Values['item'];

  JSON := ARequest.Body.GetValue;

 

  Title := JSON.GetValue<string>('book.BOOK_TITLE');

  ISBN := JSON.GetValue<string>('book.BOOK_ISBN');

  Author := JSON.GetValue<string>('book.BOOK_AUTHOR');

  Price := JSON.GetValue<string>('book.BOOK_PRICE');

  Link := JSON.GetValue<string>('book.BOOK_LINK');

  Desc := JSON.GetValue<string>('book.BOOK_DESCRIPTION');

  qryBook.Close;

  qryBook.SQL.Text := SQL_ITEM_UPDATE;

  qryBook.ParamByName('BOOK_TITLE').AsString := Title;

  qryBook.ParamByName('BOOK_ISBN').AsString := ISBN;

  qryBook.ParamByName('BOOK_AUTHOR').AsString := Author;

  qryBook.ParamByName('BOOK_PRICE').AsString := Price;

  qryBook.ParamByName('BOOK_LINK').AsString := Link;

  qryBook.ParamByName('BOOK_DESCRIPTION').AsString := Desc;

  qryBook.ParamByName('BOOK_SEQ').AsString := BOOK_SEQ;

  qryBook.ExecSQL;

 

  if qryBook.RowsAffected = 0 then

    AResponse.RaiseNotFound('Not found', '''' + BOOK_SEQ + ''' is not found');

end;

 

구현을 마치고, 프로젝트를 실행합니다. REST Debugger에서 아래와 같이 정보 입력해 테스트 합니다. 요청 후 도서 목록(http://localhost:8080/books/)에서 수정된 것을 확인합니다.

put_request.png

DeleteItem - 리소스 삭제

DeleteItem 엔드포인트는 특정 도서정보를 삭제하도록 구현합니다. 도서의 Id는 리소스 접미사를 이용해 파악합니다. 

 

DELETE http://localhost:8080/books/{item}/ - {item}은 유효한 도서일련번호로 변경할 것

다음과 같이 구현합니다.

procedure TBooksResource1.DeleteItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_ITEM_DELETE ='DELETE FROM BOOK WHERE BOOK_SEQ = :BOOK_SEQ';

 

var

  BOOK_SEQ: string;

begin

  BOOK_SEQ := ARequest.Params.Values['item'];

 

  qryBook.Close;

  qryBook.SQL.Text := SQL_ITEM_DELETE;

  qryBook.ParamByName('BOOK_SEQ').AsString := BOOK_SEQ;

  qryBook.ExecSQL;

 

  if qryBook.RowsAffected = 0 then

    AResponse.RaiseNotFound('Not found', '''' + BOOK_SEQ + ''' is not found');

end;

 

구현을 마치고, 프로젝트를 실행합니다. REST Debugger에서 아래와 같이 정보 입력해 테스트 합니다. 요청 후 도서 목록(http://localhost:8080/books/)에서 삭제된 것을 확인합니다.

delete_request.png

 

GetItem - 이미지 제공

도서정보의 경우 이미지를 제공합니다. 이미지 제공은 상세 정보 하위 "photo" 리소스를 추가해 구현합니다.

 

GET http://localhost:8080/books/{item}/photo/ - {item}은 유효한 도서일련번호로 변경할 것

 

아래 코드를 참고해 하위 리소스 엔드포인트를 추가합니다.

[ResourceSuffix('{item}/photo/')]

procedure GetItemPhoto(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

 

다음과 같이 구현합니다. 

procedure TBooksResource1.GetItemPhoto(const AContext: TEndpointContext;

  const ARequest: TEndpointRequest; const AResponse: TEndpointResponse);

const

  SQL_ITEM_IMAGE ='SELECT BOOK_IMAGE FROM BOOK WHERE BOOK_SEQ = :BOOK_SEQ';

var

  BOOK_SEQ: string;

  Stream: TMemoryStream;

begin

  BOOK_SEQ := ARequest.Params.Values['item'];

 

  Stream := TMemoryStream.Create;

  try

    qryBook.Close;

    qryBook.SQL.Text := SQL_ITEM_IMAGE;

    qryBook.ParamByName('BOOK_SEQ').AsString := BOOK_SEQ;

    qryBook.Open;

 

    if qryBook.RecordCount = 0 then

      AResponse.RaiseNotFound('Not found', '''' + BOOK_SEQ + ''' is not found');

 

    TBlobField(qryBook.FieldByName('BOOK_IMAGE')).SaveToStream(Stream);

 

    if Stream.Size = 0 then

      AResponse.RaiseNotFound('Not found', '''' + BOOK_SEQ + ''' is not found');

 

    Stream.Position := 0;

    AResponse.Body.SetStream(Stream, 'image/jpeg', True);

  except

    Stream.Free;

    raise;

  end;

end;

 

위 코드는 DB에 저장된 이미지 데이터를 Stream으로 로드 해 그대로 응답합니다. 특히 Content-type을 'image/jpg'로 지정해 데이터가 이미지라는 것을 정의합니다.

 

구현을 마치면, 프로젝트를 실행하고 웹브라우저에서 "http://localhost:8080/books/{item}/photo/"를 입력해 화면에 이미지가 표시되는 것을 확인합니다.

web_jpg.png

 

추가 학습할 내용

REST API 클라이언트 개발하기(REST 클라이언트 이용)

위에서 작성한 REST API 서버와 연동하는 클라이언트를 개발합니다. REST API를 분석해 조회, 입력, 수정, 삭제, 이미지 수신 기능을 실습위주로 학습합니다.

 

참고/관련 자료


번호 제목 글쓴이 날짜 조회 수
공지 [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
534 [발표자료] 20191205 기술브리핑! 20분만에 파악하는 RAD스튜디오 10.3.3 file 관리자 2019.12.05 442
533 [행사] 첫번째 "델파이 마이그레이션 DAY" 회고 험프리 2019.12.05 289
532 기술자료 TOP 7 - 개발자들이 가장 많이 클릭한 기술자료는? (2019년 하반기) 관리자 2019.12.05 849
531 이 달의 기술자료 - 2019년 12월 험프리 2019.12.05 367
530 [오픈소스] 델파이 코드 커버리지 소개 file 험프리 2019.12.05 536
529 [팁] TIniFile과 TMemIniFile 사용 험프리 2019.12.04 1427
528 [10.3 리오][업데이트 3] 향상된 IDE 기능들 file 관리자 2019.12.03 457
527 [10.3 리오][업데이트 3] 엔터프라이즈 커넥터가 무상 제공됩니다 (엔터프라이즈, 아키텍트 사용 고객 한정) file 관리자 2019.11.22 642
526 [10.3 리오][업데이트 3] RAD서버 도커(Docker) 배포 기능을 활용하세요. file 관리자 2019.11.22 1004
525 [10.3 리오][업데이트 3] iOS 13, 맥OS 카탈리나 지원을 시작하세요. file 관리자 2019.11.22 394
524 [10.3 리오][업데이트 3] 델파이에서 안드로이드 64비트 앱 개발이 가능합니다. file 관리자 2019.11.22 1174
523 [10.3 리오][업데이트 3] What's NEW! 신기능 자세히 보기 file 관리자 2019.11.22 3967
522 [개발팁 시리즈] 델파이/C++빌더 VCL 애플리케이션을 개발한다면? 꼭 확인하세요! 관리자 2019.11.20 462
521 주요 OS 시장 점유율 - 윈도우와 안드로이드! file 관리자 2019.11.19 559
520 윈도우 버전 점유율 변화: 2009년부터 2019년 현재까지! file 관리자 2019.11.18 362
519 [고객사례-소셜네트워크, 델파이] KisKis 관리자 2019.10.25 1088
518 이 달의 기술자료 - 2019년 11월 file 험프리 2019.10.25 359
517 IBM 왓슨과 인공지능(AI) 활용하기 - 델파이/C++빌더 관리자 2019.10.25 651
516 [발표자료] 20191017 실전 사례로 살펴보는 소프트웨어 현대화 전략 file 관리자 2019.10.23 364
515 윈도우 10 지원과 좋은 UX 구현을 위해 기억해야 할 점 관리자 2019.10.22 613