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.