Scala 在使用Sangria创建资源时,将id排除在GraphQL迁移之外

Scala 在使用Sangria创建资源时,将id排除在GraphQL迁移之外,scala,graphql,sangria,Scala,Graphql,Sangria,我一直在试图定义一种在我看来非常基本的变异。 我对Scala、GraphQL、Akka HTTP都是新手,不是母语人士,所以请原谅我下面的内容是胡说八道!很抱歉,这篇文章太长了,我确实尽量用最少的例子来保持简短,但我觉得完整的上下文很重要 上下文 我有以下代码,它定义了一个事务案例类,一个用于所有事务的假数据库,以及一个用于查询和创建事务的模式: case class Transaction(id: Int, description: String, amount: BigDecimal) o

我一直在试图定义一种在我看来非常基本的变异。 我对Scala、GraphQL、Akka HTTP都是新手,不是母语人士,所以请原谅我下面的内容是胡说八道!很抱歉,这篇文章太长了,我确实尽量用最少的例子来保持简短,但我觉得完整的上下文很重要

上下文 我有以下代码,它定义了一个
事务
案例类,一个用于所有事务的假数据库,以及一个用于查询和创建事务的模式:

case class Transaction(id: Int, description: String, amount: BigDecimal)

object TransactionDB {
  var transactions: List[Transaction] = Nil
}

class TransactionDB {
  def transaction(id: Int): Option[Transaction] =
    TransactionDB.transactions.find(_.id == id)
  def createTransaction(transaction: Transaction) = {
    TransactionDB.transactions = transaction :: TransactionDB.transactions
    transaction
  }
}

import sangria.macros.derive._
import sangria.marshalling.sprayJson._
import sangria.schema._
import spray.json._
import DefaultJsonProtocol._

object TransactionSchema {
  val Id = Argument("id", IntType)
  val TransactionType = deriveObjectType[Unit, Transaction]()
  val QueryType = ObjectType("Query", fields[TransactionDB, Unit](
    Field("transaction", OptionType(TransactionType),
      arguments = Id :: Nil,
      resolve = c ⇒ c.ctx.transaction(c.arg(Id))
    )
  ))

  implicit val transactionFormat = jsonFormat3(Transaction)
  val TransactionInputType = deriveInputObjectType[Transaction](
    InputObjectTypeName("TransactionInput")
  )

  val TransactionArg = Argument("transaction", TransactionInputType)
  val MutationType = ObjectType("Mutation", fields[TransactionDB, Unit](
    Field("createTransaction", TransactionType,
      arguments = TransactionArg :: Nil,
      resolve = c ⇒ c.ctx.createTransaction(c.arg(TransactionArg))
    )
  ))

  val schema = Schema(QueryType, Some(MutationType))
}
生成的GraphQL模式如下所示:

type Mutation {
  createTransaction(transaction: TransactionInput!): Transaction!
}

type Query {
  transaction(id: Int!): Transaction
}

type Transaction {
  id: Int!
  description: String!
  amount: BigDecimal!
}

input TransactionInput {
  id: Int!
  description: String!
  amount: BigDecimal!
}
然后,我可以创建一个事务并使用以下查询进行查询:

mutation {
  createTransaction(transaction: {
    id: 1
    description: "Electricity bill"
    amount: 100
  }) {
    id
  }
}

query {
  transaction(id: 1) {
    id
    description
    amount
  }
}
问题 然而,
id
不应该是突变的一部分。理想情况下,我会:

input TransactionInput {
  description: String!
  amount: BigDecimal!
}

type Mutation {
  createTransaction(input: TransactionInput): Transaction
  updateTransaction(id: Int!, input: TransactionInput): Transaction # For later
}
在中,这是通过以下方法实现的:

createTransaction({description, amount}) {
  const id = generateId();
  transactionRepo[id] = new Transaction(id, description, amount);
  return transaction[id];
},
updateTransaction(id, {description, amount}) { // Assuming id exists
  transactionRepo[id] = new Transaction(id, description, amount);
  return transactionRepo[id];
},
在Scala/Sangria中找到解决方案是我的难题

尝试的解决方案 尝试1:我想到了这样的事情:

def createTransaction(description: String, amount: BigDecimal) = {
  val r = scala.util.Random // Or leave this to the DB layer
  val transaction = Transaction(r.nextInt(10000), description, amount)
  TransactionDB.transactions = transaction :: TransactionDB.transactions
  transaction
}
但这不起作用,因为
createTransaction
被赋予映射到
事务的
TransactionArg

尝试2:由于删除了
id
,我也尝试切换到
jsonFormat2
,但这会在编译时触发
类型不匹配,因为
事务
有3个属性

尝试3:我尝试更新派生的
InputObjectType
以排除
id
,方法是:

val TransactionInputType = deriveInputObjectType[Transaction](
  InputObjectTypeName("TransactionInput"),
  ExcludeInputFields("id")
)
这会编译,但在尝试运行上述结果时:

  • 参数“transaction”的值无效:当从
    createTransaction(transaction:{…})
    字段中省略
    id
    时,对象缺少必需的成员“id”
  • 参数“transaction”应为类型“transactionput!”但得到:{id:42,描述:\'电费单',金额:100}。原因:输入类型“Transactionput”中未定义未知字段“id”。
    将其添加回时


我错过了什么?对我来说,
graphqljs
似乎很简单,但我找不到如何使用Sangria在Scala中实现这一点。我读了很多次文档,并在谷歌上进行了广泛的搜索,因为这似乎是一个简单的问题,但没有发现任何类似的问题。谢谢

似乎
createTransaction
updateTransaction
都返回一个类型
Transaction
,定义为:

type Transaction {
  id: Int!
  description: String!
  amount: BigDecimal!
}
id:Int
声明需要
id
(这就是
的意思),因此我首先将其重新定义为:
id:Int
(无感叹号)