joh*_*ohn 7 scala playframework sangria
我有以下输入对象:
val BusinessInputType = InputObjectType[BusinessInput]("BusinessInput", List(
InputField("userId", StringType),
InputField("name", StringType),
InputField("address", OptionInputType(StringType)),
InputField("phonenumber", OptionInputType(StringType)),
InputField("email", OptionInputType(StringType)),
InputField("hours", ListInputType(BusinessHoursInputType))
))
val BusinessHoursInputType = InputObjectType[BusinessHoursInput]("hours", List(
InputField("weekDay", IntType),
InputField("startTime", StringType),
InputField("endTime", StringType)
))
Run Code Online (Sandbox Code Playgroud)
以下是定制编组定义的模型:
case class BusinessInput(userId: String, name: String, address: Option[String], phonenumber: Option[String], email: Option[String], hours: Seq[BusinessHoursInput])
object BusinessInput {
implicit val manual = new FromInput[BusinessInput] {
val marshaller = CoercedScalaResultMarshaller.default
def fromResult(node: marshaller.Node) = {
val ad = node.asInstanceOf[Map[String, Any]]
System.out.println(ad)
BusinessInput(
userId = ad("userId").asInstanceOf[String],
name = ad("name").asInstanceOf[String],
address = ad.get("address").flatMap(_.asInstanceOf[Option[String]]),
phonenumber = ad.get("phonenumber").flatMap(_.asInstanceOf[Option[String]]),
email = ad.get("email").flatMap(_.asInstanceOf[Option[String]]),
hours = ad("hours").asInstanceOf[Seq[BusinessHoursInput]]
)
}
}
}
case class BusinessHoursInput(weekDay: Int, startTime: Time, endTime: Time)
object BusinessHoursInput {
implicit val manual = new FromInput[BusinessHoursInput] {
val marshaller = CoercedScalaResultMarshaller.default
def fromResult(node: marshaller.Node) = {
val ad = node.asInstanceOf[Map[String, Any]]
System.out.println("HEY")
BusinessHoursInput(
weekDay = ad("weekDay").asInstanceOf[Int],
startTime = Time.valueOf(ad("startTime").asInstanceOf[String]),
endTime = Time.valueOf(ad("endTime").asInstanceOf[String])
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我有一个InputObject具有自定义编组的嵌套时,我没有看到在编组BusinessHoursInput之前调用的BusinessInput编组.我注意到了这一点,因为"嘿"的打印声明从未在"广告"的打印声明之前执行BusinessInput.当我尝试BusinessInput在DB中插入hours字段时,这会导致后来出现问题,因为它无法将其转换为BusinessHoursInput对象.在Sangria中,是否无法在父对象编组之前自定义Marshal嵌套对象?
您可能正在使用BusinessInput作为参数类型。实际的隐式查找发生在Argument定义时,并且仅针对BusinessInput类型。
由于FromInput是基于类型类的反序列化,因此您需要显式定义嵌套对象的反序列化器之间的依赖关系。例如,您可以这样重写反序列化器:
案例类BusinessInput(用户ID:字符串,名称:字符串,地址:Option [String],电话号码:Option [String],电子邮件:Option [String],小时数:Seq [BusinessHoursInput])
object BusinessInput {
implicit def manual(implicit hoursFromInput: FromInput[BusinessHoursInput]) = new FromInput[BusinessInput] {
val marshaller = CoercedScalaResultMarshaller.default
def fromResult(node: marshaller.Node) = {
val ad = node.asInstanceOf[Map[String, Any]]
BusinessInput(
userId = ad("userId").asInstanceOf[String],
name = ad("name").asInstanceOf[String],
address = ad.get("address").flatMap(_.asInstanceOf[Option[String]]),
phonenumber = ad.get("phonenumber").flatMap(_.asInstanceOf[Option[String]]),
email = ad.get("email").flatMap(_.asInstanceOf[Option[String]]),
hours = hoursFromInput.fromResult(ad("hours").asInstanceOf[Seq[hoursFromInput.marshaller.Node]])
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
在此版本中,我利用现有功能从原始输入中FromInput[BusinessHoursInput]反序列化BusinessHoursInput。
另外,您也可以FromInput通过利用现有的基于JSON的反序列化器来避免完全定义手动反序列化器。例如,在大多数情况下,circe的自动推导工作得很好。您只需要这两个导入(在您定义参数的文件中):
import sangria.marshalling.circe._
import io.circe.generic.auto._
Run Code Online (Sandbox Code Playgroud)
这些导入将适当的FromInput实例放入范围内。这些实例利用了circe自己的反序列化机制。