gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 08:57:30 26 4
gpt4 key购买 nike

我一直在试图定义在我看来是非常基本的突变。我是所有 Scala、GraphQL、Akka HTTP 的新手,而且不是母语人士,所以如果下面有任何废话,请原谅我!抱歉这篇文章很长,我确实尝试用最少的例子来保持简短,但我觉得完整的上下文很重要。

上下文

我有以下定义 Transaction 的代码案例类,所有交易的假数据库,以及查询和创建交易的模式:

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
}

graphql-js documentation ,这是使用以下方式完成的:

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映射到 Transaction .

尝试 2: 我也尝试切换到 jsonFormat2因为删除了 id , 但这会触发 type mismatch在编译时因为 Transaction有 3 个属性。

尝试 3: 我尝试更新派生的 InputObjectType排除 id使用:

val TransactionInputType = deriveInputObjectType[Transaction](
InputObjectTypeName("TransactionInput"),
ExcludeInputFields("id")
)

这可以编译,但是当尝试运行上面给出的突变时,结果为:

  • Argument 'transaction' has invalid value: Object is missing required member 'id'省略 id 时来自 createTransaction(transaction: {...})领域。
  • Argument 'transaction' expected type 'TransactionInput!' but got: {id: 42, description: \"Electricity bill\", amount: 100}. Reason: Unknown field 'id' is not defined in the input type 'TransactionInput'.添加回来时。

我错过了什么? graphql-js 似乎很简单对我来说,但我找不到如何使用 Sangria 在 Scala 中做到这一点。我多次阅读文档并在谷歌上广泛查看,因为这似乎是一个简单的问题,但没有发现任何类似的东西。谢谢!

最佳答案

似乎 createTransactionupdateTransaction 都返回一个类型 Transaction 定义为:

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

id: Int! 指出 id 是必需的(这就是 ! 的意思)所以我首先将它重新定义为:id: Int(无感叹号)

关于scala - 使用 Sangria 创建资源时,将 id 排除在 GraphQL 迁移之外,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42180567/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com