web-dev-qa-db-ja.com

PlayでRESTful!フレームワーク

主にモバイルアプリにコンテンツを提供するプロジェクトを計画していますが、Webサイトが必要です。

私の質問は、モバイルアプリ用のREST APIを開発し、Play!を使用してWebサイトを提供するのに、JerseyまたはRestletを使用することが理にかなっているかどうかです。

または、Playを使用するだけの方が理にかなっていますか?それをすべて行うには?もしそうなら、どうすればREST Play!フレームワークで?

117
Gary

要求ごとに、単純なRESTのようなアプローチ。 Codemwncisのソリューションとほぼ同じように機能しますが、コンテンツネゴシエーションにAcceptヘッダーを使用します。まず、ルートファイル:

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

ここではコンテンツタイプを指定しません。これは、特定のリソースに「特別な」URIが必要な場合にのみ必要です。常にAtom/RSSで返される/users/feed/へのルートを宣言するようなものです。

アプリケーションコントローラーは次のようになります。

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つ。例えば:

user.xml:

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

user.json:

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

user.html:

<html>...</html>

すべてのブラウザがAccept/Headerでtext/htmlコンテンツタイプを送信するため、このアプローチは常にブラウザにHTMLビューを提供します。他のすべてのクライアント(おそらくJavaScriptベースのAJAX要求)は、独自のコンテンツタイプを定義できます。jQuerysajax()メソッドを使用すると、次のことができます。

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

これにより、ID 1のユーザーに関する詳細がJSON形式で表示されます。現在、PlayはHTML、JSON、およびXMLをネイティブでサポートしていますが、 公式ドキュメント に従うか、または コンテンツネゴシエーションモジュール を使用することで、異なるタイプを簡単に使用できます。

開発にEclipseを使用している場合は、ルートと対応するコンテンツタイプをテストできる RESTクライアントプラグイン を使用することをお勧めします。

112
seb

これは今でも一般的な質問ですが、投票数の多い回答は最新バージョンのPlayでは最新ではありません。動作するRESTプレイ2.2.1の例:

conf/routes:

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)

app/controllers/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
}
68
Alden

Play!を使用してくださいすべてを行うために。 PlayでRESTサービスを書くのはとても簡単です。

最初に、routesファイルはRESTアプローチに準拠するルートを書くことを簡単にします。

次に、作成するAPIメソッドごとに、コントローラーでアクションを記述します。

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

これがきちんとした例です。

ルートファイル

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>
26
Codemwnci

JAX-RS実装と統合することは、Playの組み込みHTTPルーティングを使用するための可能な代替アプローチです。 RESTEasyの例については、 RESTEasy Play!モジュール を参照してください。

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

5
Peter Hilton

あなたは見ておくべきです

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

crudモジュールが管理領域を自動的に構築するように、残りのインターフェイスを自動的に構築するプレイ用モジュールです...

4
opensas

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

Jsonおよびxml POSTを使用して作成する特定のメソッドが必要です。ここで概説: https://groups.google.com/forum/#!topic/play-framework/huwtC3YZDl

2
tchristensen