我使用Play 2.2.x和Slick 2.0(带有MYSQL后端)来编写REST API。我有一个User
模型,它有一堆字段,如age
、name
、gender
等。我想创建一个路由PATCH /users/:id
,它在主体中接收部分用户对象(即完整用户模型的字段的子集)并更新用户信息。我很困惑如何才能做到这一点:
- 如何在Play 2.2.x中使用
PATCH
动词 - 将部分用户对象解析为更新查询以在Slick 2.0中执行的通用方法是什么?我希望执行单个SQL语句,例如
update users set age=?, dob=? where id=?
免责声明:我还没有使用Slick,所以我只是根据他们关于纯SQL查询的文档来做这件事
回答您的第一个问题:
PATCH
只是routes
文件中的另一个HTTP谓词,因此对于您的示例:
PATCH /users/:id controllers.UserController.patchById(id)
你的UserController
可能是这样的:
val possibleUserFields = Seq("firstName", "middleName", "lastName", "age")
def patchById(id:String) = Action(parse.json) { request =>
def addClause(fieldName:String) = {
(request.body fieldName).asOpt[String].map { fieldValue =>
s"$fieldName=$fieldValue"
}
}
val clauses = possibleUserFields.flatMap ( addClause )
val updateStatement = "update users set " + clauses.mkString(",") + s" where id = $id"
// TODO: Actually make the Slick call, possibly using the 'sqlu' interpolator (see docs)
Ok(s"$updateStatement")
}
它的作用:
定义
PATCH
JSON 中可能存在的JSON字段名称列表定义一个将传入正文解析为JSON 的操作
遍历所有可能的字段名,测试它们是否存在于传入的JSON 中
如果是,则将形式为
fieldname=<newValue>
的子句添加到列表中构建SQL更新语句,根据需要用逗号分隔每个子句
我不知道这对你来说是否足够通用,可能有一种方法可以从Slick中获得字段名(即Slick列名),但正如我所说,我甚至不是Slick用户,更不用说专家了:-)