2010-12-07 13 views
116

主にモバイルアプリにコンテンツを配信するプロジェクトを計画していますが、ウェブサイトが必要です。RESTful on Play!フレームワーク

私の質問は、JerseyまたはRestletを使用してモバイルアプリのREST APIを開発してからPlay!ウェブサイトを提供する。

Playを使用すると意味がありますか?それをすべてするには?もしそうなら、PlayでRESTを行う方法!フレームワーク?

+0

uができれば、私は感謝ここで助けてくださいhttp://stackoverflow.com/questions/32699420/url-parameters-are-not-being-passed-by-curl-post –

答えて

25

再生を使用してください!すべてそれをする。 PlayでのRESTサービスの作成は非常に簡単です。

最初に、routesファイルを使用すると、RESTアプローチに準拠したルートを簡単に記述できます。

次に、作成する各APIメソッドのアクションをコントローラーに書き込みます。

どのように結果(XML、JSONなど)を返すかによって、使用できる方法がいくつかあります。たとえば、renderJSONメソッドを使用すると、結果を非常に簡単にレンダリングできます。 XMLをレンダリングする場合は、ビューでHTML文書を作成するのと同じ方法で行うことができます。

ここはきちんとした例です。

ルートはJAX-RS実装との統合

GET  /user/{id}   Application.getUser(format:'xml') 
GET  /user/{id}/json  Application.getUserJSON 
POST /user/    Application.createUser 
PUT  /user/{id}   Application.updateUser 
DELETE /user/{id}   Application.deleteUser 

アプリケーションファイル

public static void createUser(User newUser) { 
    newUser.save(); 
    renderText("success"); 
} 

public static void updateUser(Long id, User user) { 
    User dbUser = User.findById(id); 
    dbUser.updateDetails(user); // some model logic you would write to do a safe merge 
    dbUser.save(); 
    renderText("success"); 
} 

public static void deleteUser(Long id) { 
    // first check authority 
    User.findById(id).delete(); 
    renderText("success"); 
} 

public static void getUser(Long id) { 
    User user = User.findById(id) 
    renderJSON(user); 
} 

public static void getUserJSON(Long id) { 
    User user = User.findById(id) 
    renderJSON(user); 
} 

getUser.xmlファイル

<user> 
    <name>${user.name}</name> 
    <dob>${user.dob}</dob> 
    .... etc etc 
</user> 
+0

Acceptヘッダーに基づいて正しいgetUserメソッドを選ぶことは可能ですか? –

+0

それは完全ではありませんが、ヘッダーがJSON要求であることをプレイが知っている場合、getuser.jsonファイルをレンダリングしようとします。ヘッダーがxmlの場合、getuser.xmlが試されます。しかし、理解するのがはるかに簡単で、RESTはuser/User/{id}/typeにもっと好きです。 – Codemwnci

+28

URIに表現型を明示的に指定するのはもっとREST風ではないと思います。 Acceptヘッダーを直接使用することをお勧めします。また、参照するリソースが変わらないようにURIを変更しないでください。 上記の例は、getUserJSON、getUserXMLなどを定義する代わりに、現在の実装と全く同じgetUser(Long id)メソッドを1つだけ持つように書き直すことができます。getUser.jsonとgetUser.xmlテンプレートを定義します。私はそれをuser.json/userに改名しますが。xml too – seb

5

ファイルが再生の内蔵を使用しての可能な代替的なアプローチでありますHTTPルーティングでRESTEasyの例については、RESTEasy Play! moduleを参照してください。

このアプローチは、すでにJAX-RSに投資している場合、またはコンテンツネゴシエーションなどのJAX-RSが提供する高度な機能RESTの一部が必要な場合に役立ちます。そうでない場合は、HTTPリクエストに応じてJSONまたはXMLを提供するために直接Playを使用する方が簡単です。

112

要求ごとに、単純なRESTのようなアプローチです。これは、Codemwncisのソリューションとほぼ同じように動作しますが、コンテンツネゴシエーションにAcceptヘッダーを使用します。最初に経路ファイル:

GET  /user/{id}   Application.user 
POST /user/    Application.createUser 
PUT  /user/{id}   Application.updateUser 
DELETE /user/{id}   Application.deleteUser 

ここでコンテンツタイプは指定しません。そうすることでIMHOが必要なのは、特定のリソースに対して「特別な」URIが必要な場合だけです。 /users/feed/へのルートを宣言すると、常にAtom/RSSに戻るようになります。

アプリケーションコントローラは、次のようになります。あなたが見ることができるように

public static void createUser(User newUser) { 
    newUser.save(); 
    user(newUser.id); 
} 

public static void updateUser(Long id, User user) { 
    User dbUser = User.findById(id); 
    dbUser.updateDetails(user); // some model logic you would write to do a safe merge 
    dbUser.save(); 
    user(id); 
} 

public static void deleteUser(Long id) { 
    User.findById(id).delete(); 
    renderText("success"); 
} 

public static void user(Long id) { 
    User user = User.findById(id) 
    render(user); 
} 

は私だけgetUserJSON方法を取り除き、getUserメソッドの名前を変更しました。異なるコンテンツタイプを使用するには、いくつかのテンプレートを作成する必要があります。目的のコンテンツタイプごとに1つ。たとえば、

ユーザーです。XML:

<users> 
    <user> 
    <name>${user.name}</name> 
    . . . 
    </user> 
</users> 

user.json:

{ 
    "name": "${user.name}", 
    "id": "${user.id}", 
    . . . 
} 

user.html:すべてのブラウザでは、text/htmlのコンテンツ・タイプを送信するので

<html>...</html> 

このアプローチは、常にHTMLビューをブラウザを提供しますAcceptヘッダーに入力します。他のすべてのクライアント(JavaScriptベースのAJAXリクエストなど)は、独自のコンテンツタイプを定義できます。あなたが次のことを行うことができjQuerysアヤックス()メソッドを使用して:あなたはJSON形式のID 1を持つユーザーに関する詳細情報を取得する必要があります

$.ajax({ 
    url: @{Application.user(1)}, 
    dataType: json, 
    success: function(data) { 
    . . . 
    } 
}); 

。 Playは現在、HTML、JSON、XMLをネイティブにサポートしていますが、official documentationに従うか、content negotiation moduleを使用すると簡単に別のタイプを使用できます。

開発用にEclipseを使用している場合は、REST client pluginを使用して、ルートとその対応するコンテンツタイプをテストすることをお勧めします。

+2

ありがとうございます。遊び!ドキュメントは基本的な物の構造を説明するために私が見てきた最高のものですが、詳細な例が不足していることがあります。同じ例で2つのアプローチを実証すると、実際には問題が解決されます。 –

+0

私はあなたの例を試していますが、投稿されたJSONデータがUserクラスに変換されるところが不思議です。たとえば、createUser関数の中で、newUserがnullであることがわかります。 – Gary

+2

@Gary: "newUser"の代わりに "user"を使用したことはありますか?コントローラーとフォームパラメーターの名前は一致する必要があります。私は、https://github.com/sebhoss/play-user-sampleですべてのユーザーのHTML/XML/JSON出力を含む上記の方法を示す簡単なプロジェクトを作成しました – seb

4

あなたはそれがない

2

...

それが自動的にCRUDモジュールが自動的に管理エリアを構築すると同じように、残りのインターフェイスを構築プレイするためのモジュールです

http://www.lunatech-labs.com/open-source/resteasy-crud-play-module

を見ている必要がありますPlayバージョン1.2.3ではこのアプローチが壊れているようです。 @sebによって行われたソースをダウンロードして先にhttps://github.com/sebhoss/play-user-sampleで説明した場合、JSONオブジェクトでPOSTを使用して新しいユーザーオブジェクトを作成することはもはや不可能です。

jsonとxml POSTを使用して作成する特定の作成方法が必要です。概要:https://groups.google.com/forum/#!topic/play-framework/huwtC3YZDlU

67

これはまだよく聞かれる質問ですが、最高の投票回答は現在のバージョンの再生では最新ではありません。

のconf /ルート:ここでプレイ2.2.1での作業RESTの例です

GET  /users     controllers.UserController.getUsers 
GET  /users/:id    controllers.UserController.getUser(id: Long) 
POST /users     controllers.UserController.createUser 
PUT  /users/:id    controllers.UserController.updateUser(id: Long) 
DELETE /users/:id    controllers.UserController.deleteUser(id: Long) 

アプリ/コントローラ/ UserController.java:

public static Result getUsers() 
{ 
    List<User> users = Database.getUsers(); 
    return ok(Json.toJson(users)); 
} 

public static Result getUser(Long id) 
{ 
    User user = Database.getUser(id); 
    return user == null ? notFound() : ok(Json.toJson(user)); 
} 

public static Result createUser() 
{ 
    User newUser = Json.fromJson(request().body().asJson(), User.class); 
    User inserted = Database.addUser(newUser); 
    return created(Json.toJson(inserted)); 
} 

public static Result updateUser(Long id) 
{ 
    User user = Json.fromJson(request().body().asJson(), User.class); 
    User updated = Database.updateUser(id, user); 
    return ok(Json.toJson(updated)); 
} 

public static Result deleteUser(Long id) 
{ 
    Database.deleteUser(id); 
    return noContent(); // http://stackoverflow.com/a/2342589/1415732 
} 
+0

また、sebの回答の更新版も見たいですが、残念ながらあなたの答えは.xmlと.htmlのすべての魔法を削除しました。 :-( – flaschenpost

関連する問題