험프리 12월 15일, 2021에 포스트됨 공유하기 12월 15일, 2021에 포스트됨 이 글에서 데이터셋의 데이터를 바로 REST API로 서비스 할 수 있는 TEMSDataSetResource 컴포넌트를 소개합니다. TEMSDataSetResource 컴포넌트 사용 시 데이터셋의 데이터를 JSON 데이터로 변환하는 코드를 대폭 줄일 수 있고, 부가 기능(목록 페이징, 정렬)을 덤으로 활용할 수 있습니다. 목차 TEMSDataSetResource 컴포넌트는? 데이터셋 JSON 처리 자동화 프로젝트 생성 데이터 연결 TEMSDataSetResource 컴포넌트 설정 데이터 수정(PUT) 요청 형식 데이터 생성(POST) 요청 형식 데이터 삭제(DELETE) 요청 형식 부가기능 활용 페이징 처리 데이터 정렬 비지니스 로직에서 활용 목록과 상세 조회 시 다른 항목 제공하기 TEMSDataSetResource 컴포넌트는? TEMSDataSetResource 컴포넌트는 데이터셋에 JSON 처리 기능이 포함된 리소스를 제공하는 컴포넌트이다. TEMSDataSetResource 컴포넌트의 주요 기능은 다음과 같다. 데이터셋 JSON 처리 자동화 데이터셋의 데이터를 JSON으로 제공(List, Get) 요청한 JSON 데이터를 데이터셋에 적용(Post, Put, Delete) 허용할 액션 지정(AllowAction: List, Get, Post, Put, Delete) 제공할 항목 지정(ValueFields) 목록 요청 시 페이징 처리(PageParamName, PageSize) 및 정렬 지정(SoringParamPrefix) 각 기능을 직접 구현하며 설명한다. 데이터셋 JSON 처리 자동화 도서대여 프로그램 만들기에서 사용한 데이터베이스를 기준으로 안내한다. (실습을 따라하려면, 다음 링크에서 데이터베이스 파일을 다운로드 후 진행해야 한다.) https://github.com/devgear/BOOKRENTAL/tree/master/DB 프로젝트 생성 RAD 서버 패키지 프로젝트를 생성한다. 델파이 : File > New > Other | Delphi > RAD Server > RAD Server Package 리소스 이름은 "books"로 지정한다. 엔드포인트 선택 화면에서 Sample EndPoints를 모두 선택해제한다.(컴포넌트에 요청 처리를 위임할 것이다.) 데이터 연결 도서대여 프로그램 데이터베이스와 연결하고, 도서정보 테이블을 조회하도록 설정한다. 데이터 모듈에 TFDConnection과 TFDQuery 컴포넌트를 추가한다. TFDConnection 컴포넌트를 더블클릭 해 연결 설정 후 Test 버튼을 클릭해 연결을 확인한다. Driver ID : IB Database : 앞에서 다운로드한 데이터베이스 파일 선택 User_Name : sysdba Password : masterkey CharacterSet : UTF8(한글 사용을 위함) TFDQuery 컴포넌트를 더블클릭 후 SQL 명령어 추가 후 실행 및 확인 후 OK 버튼을 누른다. TEMSDataSetResource 컴포넌트 설정 데이터 모듈에 TEMSDataSetResource를 추가하고, 다음 속성을 설정한다. AllowedActions : 허용할 액션 설정 모두 True로 설정 DataSet : JSON을 처리할 데이터셋(TFDQuery 등) FDQuery1으로 설정 중간에 프로젝트를 실행해 보고, 어떻게 동작하는지 확인해 보자. 개발용 RAD 서버의 로그를 보면 다음 TEMSDataSetResource 컴포넌트가 엔드포인트를 제공하는 것(붉은박스)과 경로(파란박스)를 확인할 수 있다. List 엔드포인트를 테스트 해보자. 웹브라우저를 실행하고 "http://localhost:8080/books/EMSDataSetResource1/"을 실행한다. 두가지 정도 개선이 필요하다. 필요한 항목만 목록(List)으로 제공하고 싶다.(이미지와 설명 필드는 목록으로 제공하기에 데이터가 너무 많다. 아마 페이지 로딩에 시간이 걸렸을 것이다.) URI의 경로에 컴포넌트 이름(/books/EMSDataSetResource1/)이 들어가면 안될 것 같다. 필요한 항목만 목록에서 제공 첫번째, 필요한 항목만 목록으로 제공하려면, SQL 문장을 변경할 수도 있지만 ValueFIelds 속성을 설정해보자. ValueFields 속성을 더블클릭해 에디터를 표시하면 모든 필드목록이 표시된다. 포함할 필드를 우측으로 이동한다.(전체 이동 후 불필요한 항목을 제거해도 된다.) 프로젝트를 다시 실행해 웹브라우저로 결과를 확인하면, 다음과 같이 설정한 항목만 제공되는 것을 확인할 수 있다. (단, 상세 정보 요청 시에도 위에서 설정한 항목들만 제공된다. 해결방법은 뒤에서 다시 설명한다.) URI 경로 설정 두번째, URI의 경로를 설정해보자. TEMSDataSetResource 선언 코드 위에 다음과 같이 ResourceSuffix 애트리뷰트를 설정한다. type [ResourceName('books')] TBooksResource1 = class(TDataModule) FDConnection1: TFDConnection; FDQuery1: TFDQuery; [ResourceSuffix('list', '/')] [ResourceSuffix('get', '/{id}')] [ResourceSuffix('post', '/')] [ResourceSuffix('put', '/{id}')] [ResourceSuffix('delete', '/{id}')] EMSDataSetResource1: TEMSDataSetResource; published end; 첫번째 인수(Argument)는 메소드 종류, 두번째 인수는 리소스 접미사(경로)이다. 리소스 접미사의 경우 상대경로(../, ./)와 절대경로(/)를 모두 사용할 수 있으며, 절대경로 사용 시 리소스이름 뒤에 경로가 추가된다. 프로젝트를 실행 후 RAD 서버 로그를 살펴보면 설정한 내용이 적용됨을 확인할 수 있다. 데이터 수정(PUT) 요청 형식 데이터 수정은 응답받은 JSON 객채를 그대로 Custom Body에 담아 PUT 메소드로 전송하면 된다. 경로의 접미사로 ID(BOOK_SEQ)를 지정한 항목의 데이터를 수정한다. REST 디버거(Tools > REST Debugger)에서 다음과 같이 테스트 가능하다. 데이터 생성(POST) 요청 형식 데이터 생성도 수정과 동일하게 Custom Body로 전달한 데이터로 데이터 생성이 가능하다. 인용하기 (REST 원칙대로)POST 요청 시 다음 오류가 발생한다. 이 경우, 다음과 같이 키필드(book_seq)의 파라미터를 지정하면 오류가 발생하지 않는다. 데이터 삭제(DELETE) 요청 형식 데이터 삭제는 DELETE 메소드와 URI만으로 호출하면 데이터를 삭제할 수 있다. 부가기능 활용 페이징 처리 TEMSDataSetResource 컴포넌트는 부가적으로 목록(List)의 페이징 기능을 제공한다. 다음과 같은 요청으로 페이징 처리가 가능하다. /books?page={페이지 번호} PageParamName 속성의 위 파라메터의 이름을 지정할 수 있고, PageSize 속성은 페이지에 포함할 데이터 건수를 지정할 수 있다. PageSize를 2로 설정 후 테스트 하면 다음과 같이 2건의 데이터를 표시한다. 데이터 정렬 TEMSDataSetResource 컴포넌트는 목록(List)의 정렬 기능을 제공한다. 다음과 같이 사용 가능하다. /books?sf{정렬할 필드명}={A 또는 D, 정렬방식} 예를 들면 다음과 같다. /books?sfBOOK_SEQ=D - 일련번호 역순으로 정렬된 목록 제공 /books?sfBOOK_TITLTE=A - 도서제목으로 정렬된 목록 제공 비지니스 로직에서 활용 TEMSDataSetResource는 JSON 처리기능이 내장되어 편리하지만, 유효성 검사 등의 비지니스 로직 추가할 수 없다. 하지만, 엔드포인트 메소드 내에서 비지니스 로직을 구현과 TEMSDataSetResource 컴포넌트를 함께 사용할 수도 있다. TEMSDataSetResource는 List, Get, Put, Post, Delete 메소드를 제공하며, 코드상에서 호출해도 컴포넌트가 제공하는 기능을 그대로 사용할 수 있다. 다음과 같이 엔드포인트 메소드내에서 비지니스 로직과 함께 사용 가능하다. procedure TTestResource1.PutItem(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var Json: TJSONValue; Title: string; begin JSON := ARequest.Body.GetValue; Title :=JSON.GetValue<string>('BOOK_TITLE'); if Title = '' then AResponse.RaiseBadRequest; EMSDataSetResource1.Put(AContext, ARequest, AResponse); end; 목록과 상세 조회 시 다른 항목 제공하기 보통 GET 메소드로 목록과 상세 데이터 제공 시, 목록은 최소한의 항목을 상세는 최대한의 항목을 제공해야 할 수 있다. TEMSDataSetResource 컴포넌트는 ValueFields를 통해 항목을 지정할 수 있지만, 목록과 상세에서 모두 동일한 항목을 제공한다. 이 경우 엔드포인트 메소드에 다음과 같이 목록과 상세 데이터를 다르게 제공하도록 구현할 수 있다. procedure TBookRentalResource.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); const SQL_LIST ='SELECT BOOK_SEQ, BOOK_TITLE, BOOK_AUTHOR, BOOK_PRICE FROM BOOK'; begin FDQuery1.SQL.Text := SQL_LIST; EMSDataSetResource1.List(AContext, ARequest, AResponse); end; procedure TBookRentalResource.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 Item: string; begin Item := ARequest.Params.Values['id']; FDQuery1.SQL.Text := SQL_ITEM_INFO; FDQuery1.ParamByName('BOOK_SEQ').AsString := Item; EMSDataSetResource1.Get(AContext, ARequest, AResponse); end; TEMSDataSetResource 컴포넌트는 데이터셋의 데이터를 JSON으로 제공하는 코드를 대폭 줄여주며, 페이징, 정렬 등의 부가 기능을 덤으로 얻을 수 있다. 또한, 비지니스 로직을 직접 구현하는 경우에도, 필요한 메소드 호출만으로 컴포넌트의 기능을 모두 사용할 수도 있다. 참고자료 [docwiki] Using RAD Server Components(영문) 인용하기 이 댓글 링크 다른 사이트에 공유하기 더 많은 공유 선택 사항
Recommended Posts
이 토의에 참여하세요
지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.