State changes, rest APIs and end points based permissions.
Published on Apr 20, 2013You are ready to write your new HTTP API (notice I’m not saying REST) and everything goes well until you get the following requirement.
Customer status can be one of “Active, Passive, Enabled or Deleted”.
So far no problem.
Editing customers is available to all back-end roles, but status changes is only available to some roles.
This scenario is the one that most new comers find problematic. Specially if you want to model your permissions at the end point. For example using some kind of middleware.
Customers end points.
You may have the following end-points for the Customer object.
GET https://server.com/customers (all customers)
GET https://server.com/customers/:id (customer by id)
POST https://server.com/customers (create a new customer)
PUT https://server.com/customers (update the given customer)
DELETE https://server.com/customers/:id (delete the customer)
A few things to notice here. The PUT and POST route may or may not have the id at the end.
The implementation of the DELETE operation can be a logical delete while preserving the data in your data store, but that is not really relevant
In this scenario any update to customers is done via PUT.
We want to grant access to this operation to multiple roles, but we only want a subset of those roles to be able to change the status of the customer.
So we can’t really use this end point to change status without changing how we implement security.
Model Status on it’s own.
At this point of the analysis I like to stop and think what is the status of the customer. It may have started as a String property in the customer object, but it’s usually more than that.
I like to take a page of the DDD book and model the status as a value object.
I start by creating an empty Status object that contains only one String property.
I follow this with the creation of just one end point.
PUT https://server.com/customers/:id/status (updates the status for the customer with the payload)
Conclusion and home work.
Modeling the API in this manner will also allow us to add links to the customer object that represent some operations.
I think that implementing security at the end points and only at the end points help you with how you model the API and the underlaying model. A nice side effect is that your code will be more modular and easy to maintain.