How to implement a generic REST api for tables in Play2 with squeryl and spray-json
我正在尝试在Play2中实现一个控制器,该控制器为我的数据库表公开了一个简单的REST风格的api。我正在使用squeryl进行数据库访问,并使用spray-json将对象与json
相互转换。
我的想法是只有一个通用控制器来完成所有工作,因此我在
1 2 | GET /:tableName controllers.Crud.getAll(tableName) GET /:tableName/:primaryKey controllers.Crud.getSingle(tableName, primaryKey) |
..和以下控制器:
1 2 3 4 |
(是,缺少创建/更新/删除,但让我们先阅读以开始工作)
我已经通过扩展的squeryl \\的
将表映射到案例类
1 2 3 4 |
我已经将我的案例类告诉了Spray-json,因此它知道如何转换它们。
1 2 3 4 |
到目前为止,只要我直接使用table-instances,它实际上就可以很好地工作。当我试图使代码通用化时,问题就浮出水面,以至于我最终只能使用一个控制器来访问所有表:我被一些无法编译的代码所卡住,我不确定该怎么办\\的下一步。
spray-json似乎是类型问题,当我尝试在我的
这是我的一般尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def getAll(tableName: String) = Action { val json = inTransaction { // lookup table based on url val table = MyDB.tables.find( t => t.name == tableName).get // execute select all and convert to json from(table)(t => select(t) ).toList.toJson // causes compile error } // convert json to string and set correct content type Ok(json.compactPrint).as(JSON) } |
编译错误:
1 2 3 4 5 |
我猜测问题可能是json库需要在编译时知道我要向其抛出哪种模型类型,但是我不确定(请注意其中的
有没有人?
您的猜测是正确的。 MyDb.tables是一个Seq [Table [_]],换句话说,它可以容纳任何类型的表。编译器无法使用find方法找出您找到的表的类型,并且看起来JSON转换需要该类型。有多种方法可以解决此问题,但是您需要对模型类进行某种类型的访问。