Я пытаюсь реализовать контроллер в Play2, который предоставляет простой api для REST-стиля для моих db-таблиц. Я использую squeryl для доступа к базе данных и spray-json для преобразования объектов в/из JSONКак реализовать общий REST api для таблиц в Play2 с squeryl и spray-json
Моей идеи иметь один общий контроллер, чтобы сделать всю работу, поэтому я создал следующие маршруты в conf/routes
:
GET /:tableName controllers.Crud.getAll(tableName)
GET /:tableName/:primaryKey controllers.Crud.getSingle(tableName, primaryKey)
.. и следующий контроллер:
object Crud extends Controller {
def getAll(tableName: String) = Action {..}
def getSingle(tableName: String, primaryKey: Long) = Action {..}
}
(Да, отсутствует создание/обновление/удаление, но давайте читать работать первым)
Я сопоставляюсь таблицы к случаю классов расширенной squeryl-х Schema
:
object MyDB extends Schema {
val accountsTable = table[Account]("accounts")
val customersTable = table[Customer]("customers")
}
И я сказал распылительному о JSON моего случая классах, так что он знает, как преобразовать их.
object MyJsonProtocol extends DefaultJsonProtocol {
implicit val accountFormat = jsonFormat8(Account)
implicit val customerFormat = jsonFormat4(Customer)
}
До сих пор так хорошо, что на самом деле это работает очень хорошо, если я непосредственно использую таблицы-экземпляры. Проблема возникает, когда я пытаюсь создать код таким образом, чтобы в конечном итоге я получил один контроллер для доступа ко всем таблицам: я застрял с некоторым фрагментом кода, который не компилируется, и я не уверен, что следующий шаг.
Это похоже на проблему с распылителем-json, которая возникает, когда я пытаюсь преобразовать список объектов в json в мою функцию getAll
.
Вот моя общая попытка:
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)
}
Ошибка компиляции:
[error] /Users/code/api/app/controllers/Crud.scala:29:
Cannot find JsonWriter or JsonFormat type class for List[_$2]
[error] ).toList.toJson
[error] ^
[error] one error found
Я предполагаю, что проблема может быть, что JSON-библиотека должна знать, во время компиляции, которые тип модели Я бросаю на него, но я не уверен (обратите внимание на List[_$2]
в этой ошибке компиляции). Я попытался следующие изменения в код, который компилировать и результат операции:
- Удалите общий табличный (
MyDB.tables.find(.....).get
) и вместо того, чтобы использовать конкретный экземпляр таблицы, например,MyDB.accountsTable
. Доказывает, что сериализация JSON для работы. Однако это не является общим, для него требуется уникальный контроллер и конфигурация маршрута для таблицы в db. - Конвертировать список объектов из запроса db в строку перед вызовом toJson. I.e:
toList.toJson
->toList.toString.toJson
. Доказывает, что общий поиск таблиц работы Но не правильный ответ JSON, так как это строка-сериализовать список объектов ..
Мысли кого-нибудь?