Play Framework, REST, Routes, and Controllers

Viewed 1136

I've read some interesting tutorials about RESTful API design and the concepts behind it is quite clear... but let's put it into practice with Play now.

Suppose we want to implement a RESTful API that provides functionality for dealing with users. Let's start with the model. Here is the Address class:

case class Address(
  id: Int,
  street: String,
  zip: String,
  city: String,
  country: String
)

... here the User class:

case class User(
  id: Int,
  email: String,
  firstName: String,
  lastName: String,
  addresses: Array[Int]
  // addresses: Array[Address] would this option be better?
)

... and finally the routes:

# Creates a new user
POST   /users                     controllers.users.create

# Gets the user identified by the specified id
GET    /users/:userId             controllers.users.find(userId)

# Modifies the user identified by the specified id
PUT    /users/:userId             controllers.users.update(userId)

# Deletes the user identified by the specified id
DELETE /users/:userId             controllers.users.delete(userId)

The first question is: how do I retrieve an user by email keeping my API complaint with the REST rules? The following wouldn't work because it conflicts with GET users/:userId:

# Gets the user identified by the specified email address
GET    /users/:email              controllers.users.findByEmail(email)

The two options I've in mind so far are:

GET    /users                     controllers.users.list(Option[email])

or

GET    /users/:email/xxx          controllers.users.findByEmail(email)

where xxx should be a kind of virtual resource. Any suggestion for that?

My second and last question is: how should I manage user addresses? Should I get an User, add the new Address to User.addresses, and then update the User with PUT?

PUT    /users/:userId             controllers.users.update(userId)

... or should I create a specific controller for managing user addresses like this?

POST   /users/:userId/addresses/  controllers.addresses.create(userId)

Personally I prefer the second option... but maybe there are better ones.

3 Answers
Related