Scala Slick: сериализация результата запроса в таблицу переменных

Я хотел бы предоставить метод select контроллеру, который принимает имя таблицы в качестве параметра и возвращает результат запроса SELECT как JSON. До сих пор я сделал это:

def specialSelect(tableName: String) = Action.async {
  val tq: TableQuery[_] = tableObjectFactory(tableName)
  val res: Future[Seq[_]] = db.run(tq.result)
  res.map { p:Seq[_] => Ok(p.toJson) }
}

где tableObjectFactoryпринимает мое имя таблицы и возвращает a TableQueryопределенного типа:

def tableObjectFactory(tableName: String): TableQuery[_] = {
  tableName match {
    case "users" => TableQuery[Users]
    case "projects" => TableQuery[Projects]
  }
}

Если не удается, потому что нет сериализатора JSON , определенного для универсального Seq[_]a (на самом деле _должен быть aProduct with Serializable, не уверен, что это помогает).

Имя таблицы не известно заранее (например, в URL "/special_select/<tableName>"), и у меня есть 120 таких таблиц, поэтому я не могу просто реализовать его для каждой таблицы.

Существует ли способ сериализации любого Seq[_], зная, что _всегда результат строки Слика (например, класс caseUsersRow), независимо от таблицы?

Я читал о Generic DAOs и ActiveSlick, но я не уверен, следует ли идти так далеко.

1 ответ

  1. Gson работал, спасибо @pamu. Добавить

    libraryDependencies += "com.google.code.gson" % "gson" % "2.8.0"
    

    настроить.sbt, то это преобразует любые Seq[_]строки или в JsArray, который может быть задан в качестве ответа http:

    import com.google.gson.Gson
    import play.api.libs.json._
    
    val gson: Gson = new Gson()
    
    def slickToJson(res: Seq[_]): JsArray = {
      JsArray(res.map(gson.toJson).map(Json.parse))
    }
    
    // in controller Action.async:
    db.run(...).map(p => Ok(slickToJson(p)))
    

    Строки сериализуются в String с помощью Gson, затем анализируются обратно в JsObjects с помощью Play api, а затем помещаются в JsArray. Я не мог найти лучшего.