概要
REST API等で定義した文字列の値を、
scalaで case objcet
を使ってenum(っぽいやつ)を定義した値に string型
から変換したいことがあると思います。
今回、いい感じに string型
から定義したenum(っぽいやつ)に変換する処理を実装したので記事にしておこうと思います。
そもそもscalaにenumはないけども
scalaにはそもそもenumがないので、この記事のようなやり方を使って実現してます。
作ったコード
abstract sealed class OrderParameter {
def getOrderQuery(hb: HogeObject) = {
this match {
case MODIFIED_AT => hb.modifiedAt.desc
case SORT_NUMBER => hb.sortNumber.asc
case PUBLISH_AT => hb.publishedAt.desc
}
}
}
object OrderParameter {
def fromString(value: String): Option[OrderParameter] = {
Vector(MODIFIED_AT, SORT_NUMBER, PUBLISH_AT).find(_.toString == value)
}
}
case object MODIFIED_AT extends OrderParameter
case object SORT_NUMBER extends OrderParameter
case object PUBLISH_AT extends OrderParameter
実際に作ったクラスはこちらになります、このクラスを呼び出し元で次のように使ってあげることでいい感じにstringから変換できます。
呼び出し元
def func(order: String): Action[AnyContent] = Action.async {
OrderParameter.fromString(order) match {
case None => Future {
BadRequest(Json.toJson(ErrorResponse(
400, "パラメータが不正です"
)))
}
case Some(orderParameter) => {
for {
content <- hogeObjectDao.findAll(orderParameter) # hb.modifiedAt.desc を使ってsortByをかけれる処理を作る
} yield {
content match {
case Some(res) => {
Ok(Json.obj("results" -> res))
}
case None => NotFound(Json.toJson(ErrorResponse(
404, "Not Found"
)))
}
}
}
}
apiで呼び出された時とかに order
というパラメータを OrderParameter
のobjectと同じ名前でStringで指定してあげれば、変換できない場合はエラー、変換できた場合はOrderParameter
としてプログラム内で使えるようになります。
まとめ
せっかく型がしっかりしている言語を使っているので、RESTAPIとかで受け付けるパラメータも型っぽく振る舞えるようにしたいですよね。
こうすることで、指定できるパラメータを制限できるので安全な実装になるかと思います。