2010-12-07 3 views
116

Мы планируем проект, предназначенный главным образом для контента для мобильных приложений, но для этого нужен веб-сайт.RESTful on Play! framework

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

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

+0

я был бы признателен, если и может помогите мне здесь http://stackoverflow.com/questions/32699420/url-parameters-are-not-being-passed-by-curl-post – 2015-09-23 13:08:40

ответ

25

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

Во-первых, файл маршрутов упрощает запись маршрутов, соответствующих методу 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> 
+0

Можно ли выбрать правильный метод getUser на основе заголовка Accept? – 2010-12-07 21:19:11

+0

это, но не полностью надежный. Если воспроизведение знает, что заголовок является запросом JSON, он попытается отобразить файл getuser.json. Если заголовок представляет собой xml, тогда он попытается getuser.xml. Тем не менее, гораздо проще понять, и больше REST нравится, пользователю/User/{id}/type – Codemwnci 2010-12-07 21:27:43

+28

Я не думаю, что это больше REST-типа, чтобы явно указать тип представления в URI. Лучше использовать заголовок Accept напрямую и не изменять URI, поскольку ресурс, который вы хотите видеть, остается тем же. Приведенный выше пример может быть переписан, чтобы иметь только один метод getUser (Long id), который делает то же самое, что и его текущая реализация, но вместо определения getUserJSON, getUserXML и т. Д. Вы скорее определяете шаблон getUser.json и getUser.xml , Хотя я бы переименовал его в user.json/user.xml тоже – seb 2010-12-08 09:44:18

5

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

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

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

пользователь.XML:

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

user.json:

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

user.html:

<html>...</html> 

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

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

Что вы должны получить подробную информацию о пользователе с ID 1 в формате JSON. Play в настоящее время поддерживает HTML, JSON и XML изначально, но вы можете легко использовать другой тип либо после official documentation, либо использовать content negotiation module.

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

2

Это делает похоже, что этот подход нарушен в 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

67

Это по-прежнему популярный вопрос, но самые высокие голосовые ответы не соответствуют текущей версии игры. Вот рабочий пример 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 
}