我的案例类为Inventory
:
case class Inventory(
organizationId: UUID,
inventoryId: UUID,
name: String,
schema: String
)
输入类型:
private val NewInventoryInputType =
deriveInputObjectType[Inventory](
InputObjectTypeName("NewInventory"),
ExcludeInputFields("organizationId", "inventoryId")
)
争论:
val NewInventory = Argument("inventory", NewInventoryInputType)
最后一个字段:
val MutationType = ObjectType("Mutation", fields[GraphQLContext, Unit](
Field("createInventory", OptionType(UuidType),
Some("Creates a new inventory."),
NewInventory :: Nil,
resolve = c => {
val inventoryId = UUID.randomUUID
val inventory = c arg NewInventory
println(s"Inventory($inventory)")
inventoryId
}
)
))
我想要做的是能够使用如下查询创建Inventory
:
{
"query": "mutation ($inventory: NewInventory!) { createInventory(inventory: $inventory) }",
"variables": {
"inventory": {
"name":"i1",
"schema":"s"
}
}
}
缺少的部分是在Sangria尝试使用其拥有的变量实例化organizationId
域对象之前为inventoryId
和Inventory
创建UUID的位置。
目前,我收到此错误:
Argument 'inventory' has invalid value: At path '/inventoryId': error.path.missing (line 1, column 67):
mutation ($inventory: NewInventory!) { createInventory(inventory: $inventory) }
^
(当然,我可以创建一个没有ID字段的NewInventory
案例类,并手动实例化Inventory
,但我想避免为每个实体创建和维护两个类类型。)
答案 0 :(得分:0)
在为案例类定义输入对象时,需要定义两件事:
InputObjectType
- 它在GraphQL架构中声明了一个输入类型,并通过内省API公开了它的元信息。在您的示例中,您是借助deriveInputObjectType[Inventory]
宏来定义它。FromInput[Inventory]
type class的隐式实例 - 它提供了有关如何从某些输入(如JSON)反序列化此输入对象的信息。正如您在其他地方提到的那样,您已经使用一些JSON库(Json.format[Inventory]
)由于您要从输入对象的定义中排除2个字段,因此您还需要确保反序列化器知道它并且它应该能够处理缺少这2个字段的场景。在你的case类中,这两个字段是非可选的,这意味着JSON库(我假设你正在使用play-json
)总是希望这两个字段存在。这就是您看到此错误的原因:Argument 'inventory' has invalid value: At path '/inventoryId'
。该错误实际上来自play-json
,因为在GraphQL Schema中,您允许此字段不存在但JSON解串器不知道它
FromInput[Inventory]
type class提供了非常灵活的机制。我建议你查看它的文档,然后定义你自己的实现/包装器来处理这些缺失的字段。另一种方法是在CQRS的方向上更多,并定义2个独立的模式:一个用于查询,另一个用于突变输入(也可以在scala代码中表示为2个单独的案例类)。当然,您也可以将两个可选字段定义为Option[UUID]
。