RESTful на Play! фреймворк

Мы планируем проект, в основном обслуживающий контент для мобильных приложений, но требующий наличия веб-сайта.

Мой вопрос в том, имеет ли смысл использовать Джерси или Restlet для разработки API REST для наших мобильных приложений, а затем использовать Play! для обслуживания веб-сайта.

Или имеет смысл использовать Play! сделать все это? Если да, то как сделать REST с Play! фреймворк?

Ответ 1

В соответствии с запросом - простой подход, подобный 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. Для использования разных типов контента вам нужно создать несколько шаблонов. Один для каждого желаемого типа контента. Например:

user.xml:

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

user.json:

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

user.html:

<html>...</html>

Этот подход дает браузеру всегда представление HTML, поскольку все браузеры отправляют тип содержимого text/html в заголовок Accept. Все остальные клиенты (возможно, некоторые JavaScript-запросы AJAX) могут определять свой собственный желаемый тип контента. Используя метод jQuerys ajax(), вы можете сделать следующее:

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

Который должен предоставить вам информацию о пользователе с идентификатором 1 в формате JSON. В настоящее время Play поддерживает HTML, JSON и XML, но вы можете легко использовать другой тип, следуя официальной документации или использовать модуль согласования контента.

Если вы используете Eclipse для разработки, я предлагаю использовать клиентский плагин REST, который позволяет тестировать маршруты и соответствующий им тип контента.

Ответ 2

Это по-прежнему популярный вопрос, но самые высокие голосовые ответы не соответствуют текущей версии игры. Здесь рабочий пример REST с игрой 2.2.1:

Conf/маршруты:

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
}

Ответ 3

Используйте Play! чтобы сделать все это. Написание сервисов REST в Play очень просто.

Во-первых, файл маршрутов упрощает запись маршрутов, соответствующих методу REST.

Затем вы пишете свои действия в контроллере для каждого метода API, который вы хотите создать.

В зависимости от того, как вы хотите вернуть результат (XML, JSON и т.д.), вы можете использовать несколько методов. Например, используя метод renderJSON, вы можете легко визуализировать результаты. Если вы хотите визуализировать XML, вы можете сделать это так же, как если бы вы создали HTML-документ в своем представлении.

Вот пример.

route file

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>

Ответ 4

Интеграция с реализацией JAX-RS - возможный альтернативный подход к использованию встроенной HTTP-маршрутизации Play. Пример RESTEasy см. В RESTEasy Play! модуль.

Этот подход имеет смысл, если вы уже инвестировали в JAX-RS, или если вам нужны некоторые расширенные функции REST, которые предоставляет JAX-RS, например, согласование контента. В противном случае было бы проще просто использовать Play напрямую для обслуживания JSON или XML в ответ на HTTP-запросы.

Ответ 5

вы должны взглянуть на

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

это модуль для игры, который автоматически создает интерфейс отдыха, так же как модуль crud автоматически создает область администратора...

Ответ 6

Кажется, что этот подход нарушен в 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/huwtC3YZDlU