ユーザ情報をJSONで受け取り、登録もしくは更新を行います。

Readsの定義

JsonControllerにユーザ情報を受け取るためのケースクラスと、JSONからそのケースクラスに変換するためのReadsを定義します。

object JsonController extends Controller {
  ...
  // ユーザ情報を受け取るためのケースクラス
  case class UserForm(id: Option[Long], name: String, companyId: Option[Int])
  // JSONをUserFormに変換するためのReadsを定義
  implicit val userFormReads = Json.reads[UserForm]
  ...

コントローラ

JsonControllercreateメソッドを以下のように実装します。

JSONリクエストを受け取る場合は

  • DBAction(parse.json) { ... }
  • DBAction.transaction(parse.json) { ... }

のようにアクションにparse.jsonを指定します。rs.body.validateメソッドでJSONをケースクラスに変換でき、変換に失敗した場合の処理をrecoverTotalメソッドで行うことができます。

def create = DBAction.transaction(parse.json) { implicit rs =>
  rs.body.validate[UserForm].map { form =>
    // OKの場合はユーザを登録
    val user = UsersRow(0, form.name, form.companyId)
    Users.insert(user)
    Ok(Json.obj("result" -> "success"))

  }.recoverTotal { e =>
    // NGの場合はバリデーションエラーを返す
    BadRequest(Json.obj("result" ->"failure", "error" -> JsError.toFlatJson(e)))
  }
}

同様にupdateメソッドを以下のように実装します。

def update = DBAction.transaction(parse.json) { implicit rs =>
  rs.body.validate[UserForm].map { form =>
    // OKの場合はユーザ情報を更新
    val user = UsersRow(form.id.get, form.name, form.companyId)
    Users.filter(t => t.id === user.id.bind).update(user)
    Ok(Json.obj("result" -> "success"))

  }.recoverTotal { e =>
    // NGの場合はバリデーションエラーを返す
    BadRequest(Json.obj("result" ->"failure", "error" -> JsError.toFlatJson(e)))
  }
}

POINT

  • parse.jsonはボディパーサと呼ばれるもので、リクエストボディの処理方法を決めるものです

実行

コマンドラインから以下のコマンドを実行してユーザ情報を登録・更新できることを確認しましょう。

登録:

curl -H "Content-type: application/json" -XPOST -d '{"name":"TestUser", "companyId":1}' http://localhost:9000/json/create

更新:

curl -H "Content-type: application/json" -XPOST -d '{"id":1, "name":"TestUser", "companyId":1}' http://localhost:9000/json/update

いずれの場合も成功すると以下のJSONが返却されます。

{"result":"success"}

エラー時のレスポンスを確認するために、以下のように不正なJSONを送信してみましょう(プロパティ名がnameではなくuserNameになっている)。

curl -H "Content-type: application/json" -XPOST -d '{"userName":"TestUser"}' http://localhost:9000/json/create

すると以下のようにエラー情報を含むJSONが返却されます。

{"result":"failure","error":{"obj.name":[{"msg":"error.path.missing","args":[]}]}}