Mark MassetのREST APIコードによると、4つのリソースアーキタイプがあります。
- ドキュメントはリソースの表現です。
- コレクション -サーバー上のデータセット。
- ストレージはクライアント上のデータセットです。
- コントローラーは実行されるアクションです。
ドキュメント、コレクション、およびリポジトリはリソースを表します。 一方、コントローラーはリソースの変更を担当します。 HTTPの動詞を使用して、リソースに対するアクションを示すことができますが、通常のCRUD操作では、これは必ずしも意味をなさない場合があります。 例として次のリソースをご覧ください。
- /メッセージ
- /メッセージ/ 4
メッセージコレクション(最初のリソース)と個別のメッセージ(2番目のリソース)がある場合、すべてのメッセージを消去したことを報告するにはどうすればよいですか? または、このメッセージをアーカイブに移動する方法は? CRUDはこれらの要件を完全に満たしていません。 ただし、コントローラーはこのタイプの操作には最適です。
- /メッセージ/ すべてクリア
- /メッセージ/ 4 / アーカイブ
ここでは、clear-allおよびarchiveコントローラーを使用して、それぞれCollectionを変更し、Documentをアーカイブします。
リソースにコントローラーを使用し始めてから、URLスキームにたどり着きました。 Angularの$リソースを使用するとこれを行うことができますが、データバインディングを構成するにはいくつかの「スマート」機能を使用する必要があります。
メッセージを操作するという上記の概念に基づいて、Angularのコンテキストでは、次のテンプレートを使用してリソースを定義する必要があります。
- /メッセージ/:id /:コントローラー
問題は、現時点では、最初のURLパラメーターの周りにいくつかのあいまいさが存在することです。 「:id」はコレクションベースのコントローラーへの参照ですか? それともドキュメントIDリンクですか?
この不確実性を排除するために、AngularではテンプレートURLの同じ部分にいくつかのパラメーターを定義できます。
- /メッセージ/:listController:id /:docController
URLパターンの2番目の部分には2つのパラメーターが含まれていることに注意してください。
- :listController
- :id
とりあえず、そのうちの1つだけを使用しますが、AngularはRESTfulリソースを適切に構築します。 これを実証するために、メッセージリソースを定義して上記のように使用するデモを作成しました。
<!doctype html> <html ng-app="Demo"> <head> <meta charset="utf-8" /> <title> RESTful AngularJS</title> <!-- . . , AngularJS ngResource. --> <script type="text/javascript" src="../angular-1.0.2/angular.js"></script> <script type="text/javascript" src="../angular-1.0.2/angular-resource.js"></script> <script type="text/javascript"> // ngResource // . var app = angular.module( "Demo", [ "ngResource" ] ); // , app . app.run( function( $resource ) { // , // , get() query(), // HTTP. RESTful // // , CRUD. var messages = $resource( "./api.cfm/messages/:listController:id/:docController", { id: "@id", listController: "@listController", docController: "@docController" }, { clear: { method: "POST", params: { listController: "clear-all" } }, archive: { method: "POST", params: { docController: "archive" } } } ); // , // . // GET ID. messages.query(); // POST . messages.clear(); // GET ID. messages.get( { id: 4 } ); // POST . messages.archive( { id: 8 } ); } ); </script> </head> <body> <!-- . --> </body> </html>
私のAngularリソースは2つの異なるコントローラーによって表示されることに注意してください。
- :ListController-メッセージのコレクションに作用します。
- :DocController-特定のメッセージに作用します。
上記のリソースメソッドが使用された場合、最終的に、次のアドレスで4つの要求が行われました。
- GET ... / api.cfm /メッセージ
- POST ... / api.cfm /メッセージ/ clear-all
- GET ... / api.cfm / messages / 4
- POST ... / api.cfm / messages / 8 /アーカイブ
ご覧のとおり、AngularはRESTに従ってURLを正しく識別しました。 バズ!
興味があれば、テストAPIファイルを次に示します。
<!--- , . ---> <cfset resourcePath = cgi.path_info /> <!--- : , ColdFusion 10 , POST. , . ---> <cfif ( cgi.request_method neq "GET" )> <cfset requestBody = getHTTPRequestData().content /> </cfif> <!--- , , . ---> <cfif reFind( "^/messages$", resourcePath )> <cfset response = "GET without ID." /> <cfelseif reFind( "^/messages/clear-all$", resourcePath )> <cfset response = "POST with clear-all Controller." /> <cfelseif reFind( "^/messages/\d+$", resourcePath )> <cfset response = "GET with ID." /> <cfelseif reFind( "^/messages/\d+/archive+$", resourcePath )> <cfset response = "POST with archive controller" /> <cfelse> <cfset response = "Hmm, couldn't match resource." /> </cfif> <!--- JSON. , . ---> <cfset serializedResponse = serializeJSON( response ) /> <!--- . ---> <cfheader name="X-Debug-Path" value="#cgi.path_info#" /> <!--- . ---> <cfcontent type="application/json" variable="#charsetDecode( serializedResponse, 'utf-8' )#" />
何らかの理由で、リクエスト本文にアクセスできるようになるまで(getHttpRequestData()関数経由で)POST 10リクエストでColdFusion 10がクラッシュしました。 これは、リクエスト本文にJSON(JavaScript Object Notation)データが含まれている場合にのみ発生しました。 空だった場合、要求はハングしません。 リクエストの処理を完全に理解しておらず、これが理にかなっているかはわかりませんが、ColdFusion 9はこれを実行しないことに注意してください。
オリジナル