RESTful on Play! framework

前端 未结 6 500
攒了一身酷
攒了一身酷 2020-11-28 00:16

We are planning a project primarily serving content to mobile apps, but need to have a website.

My question is whether is makes sense to use Jersey or Restlet to dev

相关标签:
6条回答
  • 2020-11-28 00:54

    It does seem like this approach is broken in Play version 1.2.3. If you download the source done by @seb and mentioned earlier https://github.com/sebhoss/play-user-sample, the creation of a new user object using POST with a JSON object is no longer possible.

    You need to have specific methods for creation done using with json and xml POSTs. Outlined here: https://groups.google.com/forum/#!topic/play-framework/huwtC3YZDlU

    0 讨论(0)
  • 2020-11-28 00:59

    Use Play! to do it all. Writing REST services in Play is very very easy.

    Firstly, the routes file makes it straightforward to write routes that conform to the REST approach.

    Then, you write your actions, in the controller, for each API method you want to create.

    Depending on how you want to return the result (XML, JSON etc), there are a few methods you can use. For example, using the renderJSON method, allows the results to be rendered very easily. If you want to render XML, then you can just do so in the same way as you would build an HTML document in your View.

    Here is a neat example.

    routes 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
    

    Application file

    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 file

    <user>
       <name>${user.name}</name>
       <dob>${user.dob}</dob>
       .... etc etc
    </user>
    
    0 讨论(0)
  • 2020-11-28 01:00

    Integrating with a JAX-RS implementation is a possible alternative approach to using Play's built-in HTTP routing. For a RESTEasy example, see the RESTEasy Play! module.

    This approach makes sense if you are already invested in JAX-RS, or if you need some of the advanced features REST that JAX-RS provides such as content negotiation. If not, it would be simpler to just use Play directly to serve JSON or XML in response to HTTP requests.

    0 讨论(0)
  • 2020-11-28 01:06

    This is still a popular question, but the highest voted answers are not up to date with the current version of play. Here's a working REST example with play 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
    }
    
    0 讨论(0)
  • 2020-11-28 01:06

    you should have a look at

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

    it's a module for play that automatically build a rest interface, just like the crud module automatically builds an admin area...

    0 讨论(0)
  • 2020-11-28 01:10

    As per request, a simple REST-like approach. It works almost the same way Codemwncis' solution works but uses the Accept header for content negotiation. First the routes file:

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

    You don't specify any content type here. Doing so is IMHO only necessary when you want to have "special" URIs for certain resources. Like declaring a route to /users/feed/ to always return in Atom/RSS.

    The Application controller looks like this:

    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);
    }
    

    As you can see I only removed the getUserJSON method and renamed the getUser method. For different content types to work you now have to create several templates. One for each desired content type. For example:

    user.xml:

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

    user.json:

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

    user.html:

    <html>...</html>
    

    This approach gives browsers always the HTML view, since all browsers send a text/html content type in their Accept header. All other clients (possibly some JavaScript-based AJAX requests) can define their own desired content type. Using jQuerys ajax() method you could do the following:

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

    Which should get you the details about User with the ID 1 in JSON format. Play currently supports HTML, JSON and XML natively but you can easily use a different type by either following the official documentation or use the content negotiation module.

    If you are using Eclipse for development I suggest use the REST client plugin which lets you test your routes and their corresponding content type.

    0 讨论(0)
提交回复
热议问题