patternMinor
Determining the HTTP status code to return for a request
Viewed 0 times
determiningthereturnrequeststatushttpforcode
Problem
I have a piece of code that I would like to refactor but can't figure how to do it. This is a method from a Play controller where I have to verify many precondition and respond different status for each case :
The first attempt looks like below. How do you implement such a suite of verifications?
My best attempt is now to have one method who create a triplet of
- resource should exist or 404
- revision should match the
If-Matchvalue or 412
- payload should be valid or 422
The first attempt looks like below. How do you implement such a suite of verifications?
service.find(key).map { resource =>
request.headers.get("If-Match").map { expected =>
if ( resource.revision == expected ) {
val payload = request.body.validate[Model]
payload match {
case JsSuccess(model, _) =>
Ok()
case JsError(errors) =>
UnprocessableEntity()
}
} else {
PreconditionFailed()
}
}
} getOrElse {
NotFound()
}My best attempt is now to have one method who create a triplet of
Option[Resource], String, JsResult[Model] and use pattern matching for each case :condition match {
case (None, _, _) =>
NotFound()
case (Some(resource), expected, _) if ( resource.revision!=expected ) =>
PreconditionFailed()
case (_, _, JsError(errors)) =>
UnprocessableEntity()
case (Some(resource), _, JsSuccess(model, _)) =>
Ok()
}Solution
You should learn more about partial functions. Everything you need to know is written in the documentation.
It is a structure that allows you to do a basic check on something and if it succeed, it does something. It is composed of two methods :
It applies the
The great thing about partial functions is that you can chain them easily with the
But there is another way to write it :
Here is a great article about it.
It is a structure that allows you to do a basic check on something and if it succeed, it does something. It is composed of two methods :
apply(v1: A): B
isDefinedAt(x: A): Boolean
It applies the
apply method on your input parameter only if the isDefinedAt method returned true when called with your input parameter.The great thing about partial functions is that you can chain them easily with the
andThen, compose and applyOrElse operators. Also, they can be written very easily by using the case syntax : val divideByTwo: PartialFunction[Int, Int] = { case d: Int if d%2 == 0 => d/2 }But there is another way to write it :
val divideByTwo = new PartialFunction[Int, Int] {
def apply(d: Int) = d / 2
def isDefinedAt(d: Int) = (d%2 == 0)
}Here is a great article about it.
Code Snippets
val divideByTwo: PartialFunction[Int, Int] = { case d: Int if d%2 == 0 => d/2 }val divideByTwo = new PartialFunction[Int, Int] {
def apply(d: Int) = d / 2
def isDefinedAt(d: Int) = (d%2 == 0)
}Context
StackExchange Code Review Q#122459, answer score: 3
Revisions (0)
No revisions yet.