13 Webサービス
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith ,
Japanese Translation: T.Yamamoto, Japanese Grails Doc Translating Team
このドキュメントの内容はスナップショットバージョンを元に意訳されているため、一部現行バージョンでは未対応の機能もあります。
Version: 2.1.0.BUILD-SNAPSHOT
13 Webサービス
WebサービスはWebアプリケーションにWeb APIを提供するものであり、通常はSOAPまたはRESTで実装されています。13.1 REST
RESTは本来SOAPのようなプロトコルではなく、アーキテクチャスタイルです。RESTは非常に単純です。簡素なXMLやJSONを通信媒体に用いて、基本的なシステムとGET、PUT、POSTおよびDELETEといったHTTPメソッドを「表現する」URLパターンを組み合わせています。 それぞれのHTTPメソッドは異なるアクションにマップします。例えば、GETはデータ検索、PUTはデータ作成、POSTは更新などとマップします。このため、RESTはCRUDと非常によく適合します。URLパターン
GrailsでRESTを実装する1つ目のやり方として、以下のようにRESTfulなURLマッピングを提供する方法があります。static mappings = { "/product/$id?"(resource:"product") }
/product
というURIをProductController
に紐付けます。GET、PUT、POSTおよびDELETEといった各HTTPメソッドは、下表に示したようにコントローラ内の一意のアクションに紐付きます。メソッド | アクション |
---|---|
GET | show |
PUT | update |
POST | save |
DELETE | delete |
"/product/$id"(controller: "product") { action = [GET: "show", PUT: "update", DELETE: "delete", POST: "save"] }
resource
と違い、parseRequest
変数をURLマッピングに指定しないと、XMLやJSONのマーシャリングを自動的には行いません:"/product/$id"(controller: "product", parseRequest: true) { action = [GET: "show", PUT: "update", DELETE: "delete", POST: "save"] }
HTTPメソッド
前のセクションでは、特定のHTTPメソッドを特定のコントローラのアクションにマップするURLマッピングが、どれほど簡単に定義できるかを見ました。特定のHTTPメソッドを送信するRESTクライアントを作成するのも簡単です。(GroovyのHTTPBuilderモジュールの例):import groovyx.net.http.* import static groovyx.net.http.ContentType.JSONdef http = new HTTPBuilder("http://localhost:8080/amazon") http.request(Method.GET, JSON) { url.path = '/book/list' response.success = { resp, json -> for (book in json.books) { println book.title } } }
GET
またはPOST
以外のメソッドの要求を発行するためには、Grailsの援助が必要となります。フォーム(form)を定義する時に、DELETE
のような別のメソッドを指定できます。<g:form controller="book" method="DELETE"> .. </g:form>
_method
というhiddenパラメータを送信し、これをHTTPメソッドの要求として使用します。ブラウザ以外のクライアントでメソッドを変更するためには、X-HTTP-Method-Override
を使用して代替メソッド名を指定します。XMLマーシャリング - 読み取り
GrailsのXMLマーシャリングの機能をコントローラで使用して、GETメソッドの実装できます。import grails.converters.XMLclass ProductController { def show() { if (params.id && Product.exists(params.id)) { def p = Product.findByName(params.id) render p as XML } else { def all = Product.list() render all as XML } } .. }
Product
を返し、無い場合は全てを返します。この方法で、/product
にアクセスすると全リストが返り、/product/MacBook
等指定して存在した場合は、そのProduct
を返します。XMLマーシャリング - 更新
PUT
およびPOSTの
ような更新をサポートするには、Grailsのparamsオブジェクトを利用してXMLを読み取ることができます。次のようなXMLを受信したとします。<?xml version="1.0" encoding="ISO-8859-1"?> <product> <name>MacBook</name> <vendor id="12"> <name>Apple</name> </vender> </product>
def save() { def p = new Product(params.product) if (p.save()) { render p as XML } else { render p.errors } }
params
オブジェクトからproduct
キーを使用して取得し、Product
クラスのコンストラクタに渡すことで自動的にバインドします:def p = new Product(params.product)
コンテントネゴシエーションを使用することができます。異なったクライアント(REST、HTMLなど)に対する異なった応答が必要な場合は、
Product
オブジェクトが保存され、XMLとして描写されます。問題が起きた場合は、Grailsのバリデーション機能によってエラーメッセージが返信されます。<error> <message>The property 'title' of class 'Person' must be specified</message> </error>
JAX-RSでのREST
RESTful Webサービス用のJava APIをベースとしたRESTを、JAX-RSプラグイン構築することも可能です。 (JSR 311: JAX-RS)13.2 SOAP
GrailsにはSOAPのサポートを追加するプラグインがいくつかあります。コントラクトファーストのSOAP向けにはSpring WSプラグインがあり、GrailsサービスからSOAP APIを生成したいのであれば以下のようなプラグインがあります。- CXF プラグインは、CXF SOAPスタックを使用します。
- Axis2 プラグインは、Axis2 を使用します。
- Metro プラグインは、Metro フレームワークを使用します。(コントラクトファースト向けに使用することもできます。)
expose
プロパティを定義することによって、SOAPを統合することが可能です。下記はCXFプラグインの例です:class BookService { static expose = ['cxf'] Book[] getBooks() {
Book.list() as Book[]
}
}
http://127.0.0.1:8080/your_grails_app/services/book?wsdl
CXFプラグインについてもっと知りたい方は、ドキュメントを参照しましょう。
13.3 RSSとAtom
RSSやAtomについては、Grailsへの直接的な機能は提供されていません。renderメソッドのXML機能を使用して、RSSやATOMのフィードを構築することができます。他に、ROME ライブラリを使用してRSSとAtomビルダを提供したFeedsプラグイン もあります。その使用例を以下に示します。def feed() { render(feedType: "rss", feedVersion: "2.0") { title = "My test feed" link = "http://your.test.server/yourController/feed" for (article in Article.list()) { entry(article.title) { link = "http://your.test.server/article/${article.id}" article.content // return the content } } } }