データアクセス機能を用意する
Web APIを作る
それでは、具体的な作業に取り掛かりましょう。最初に用意するのは、データアクセス機能です。C/Sアプリケーションでは、クライアントアプリケーションが直接リモートのRDBMSに接続していました。
Ext JSによるWebアプリケーションはWebブラウザ上で動作するわけですから、ここから直接RDBMSに接続するわけにはいきません。Ext JSからは、任意のWeb APIにアクセスすることができるので、クエリーの結果をJSONデータで返すWeb APIと、特定のレコードを更新するWeb APIを実装しておきます。
Ext JS側での処理は後述しますが、データパッケージと呼ばれる機能を使うため、Web APIを扱うためのコーディングは実質不要です。
実装方法は自由
Web APIの実装は本記事の中心的な話題ではないので、あまり詳細は説明しません。Ext JSからすれば、REST/JSONのようなオープンなプロトコル/データ形式であれば、APIの実装方法は問いません。従って、以前から使用している言語を用いたり、サーバーサイドアプリケーションの構築に最適な言語を選択したりするなど、自由です。
今回は、元のデータアクセスがC/Sアプリケーションであったということもあるので、C/Sアプリケーションを実装していたDelphiをそのまま使うことにします。
Delphiにも、現在ではWeb APIを実装するためのテクノロジーが用意されており、コンポーネントを用いた効率的な開発で、主要なRDBMS、クラウドサービス、既存のシステムなどと連携するWeb APIを簡単に構築することができます。
Delphiで実装したWeb API
以下は、Delphiで実装したWeb APIの開発画面です。パネルのようなところにいくつかのアイコンが並んでいますが、これが、データアクセスやJSONデータ処理を行うためのコンポーネントです。UIはないのですが、ロジックもビジュアル操作で構築できるのです。
Web APIは以下のようなコードによって実装されています。DelphiにはREST API実装やJSONデータの受け渡しに特化したコンポーネントTEMSDataSetResourceが用意されており、データベースのCRUD操作を行うAPIを、コーディングなしに実装できます。TEMSDataSetResourceよりも細かい制御が必要な場合は、応答するprocedure内のコードで実装できます。
type [ResourceName('WebAPI')] // API のリソース名定義 TWebAPIResource1 = class(TDataModule) // TEMSDataSetResource は操作とサフィックスを定義するだけでAPIとして動作する [ResourceSuffix('get' , 'customers/{id}')] [ResourceSuffix('put' , 'customers/{id}')] EMSDataSetResource1: TEMSDataSetResource; published // データの一覧取得を TEMSDataSetResource よりも細かく制御する場合の定義 [ResourceSuffix('customers/')] procedure Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); end; implementation procedure TWebAPIResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var CustomerJSONResponse: TJSONObject; begin // ここで検索の実行やJSONデータの生成などを実装する AResponse.Body.SetValue(CustomerJSONResponse,True); end;
このAPIには http://localhost:8080/WebAPI/customers/ としてアクセスでき、データの取得はGETメソッドに対して、次のJSONデータを返します。またデータの更新をPUTで受け付けます。
{ “result”: [ { "CUSTOMER_ID": 1, "NAME": "神野 天音", "NAMEPHONETIC": "かみの あまね", "EMAIL_ADDRESS": "kamino_amane@example.com", "BIRTHDAY": "1995-02-14T00:00:00.000+09:00", "PREFECTURE": "東京都", "PHONE_NUMBER": "03-4540-4148", "MOBILEPHONE": "03-4540-4148" }, … … … ], “total”: 50000 }
“total”は、このデータセット全体のレコード数を示しています。