In MVC usually the controller sets whatever needs to be sent back to the client/View, including HTTP status code, e.g.:
class Controller {
public function get(Request req, Response resp) {
if (this.model.get(req.getId()) {
resp.setStatusCode(Response::HTTP_OK)
} else {
resp.setStatusCode(Response::HTTP_NOT_FOUND)
}
}
}
There are a few problems in doing it this way:
- all controller methods become littered with if/else for setting different HTTP status code
- I've encountered a problem where someone has a Model::createOrGet(), which just return Model. The controller doesn't know if one has been created or fetch from store.
- setting HTTP status code code becomes duplicated between controllers.
Would it be better to make Model pass HTTP status code back to the controller, e.g.:
class Controller {
public function get(Request req, Response resp) {
cart := this.model.getOrCreate(req.getCustomerId()
resp.setStatusCode(this.model.getStatusCode())
if (cart) {
return cart
}
}
public function create(Request req, Response resp) {
cart := this.model.getOrCreate(req.getCustomerId()
resp.setStatusCode(this.model.getStatusCode())
if (cart) {
return cart
}
}
public function put(Customer c, array data) {
// this can result different success/error status codes
this.model.processPutDataForCustomer(c, data)
resp.setStatusCode(this.model.getStatusCode())
}
}
Basically this.model
sets the last status to the appropriate HTTP status code which can be one of the success, client error or server error codes and the controller can just get that status code.
Is this good or is there a better way for this common problem? Isn't it logical for web application to know HTTP status code deeper than the controller?
I'd really like to see example for multiple possible HTTP status code to be returned by the controller, something like a PUT request that can be one of "Bad Request", "Conflict", "Not Found", "Created" and "No Content".