首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Sangria创建资源时,将id排除在GraphQL迁移之外

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

Stack Overflow用户
提问于 2017-02-11 19:58:10
回答 1查看 299关注 0票数 3

我被困在试图定义什么在我看来是一个非常基本的突变。我是所有Scala,GraphQL,Akka的新手,而不是一个母语为母语的人,所以请原谅我,如果下面的任何事情是胡说八道!对于冗长的帖子,我很抱歉,我试着用最少的例子来保持简短,但我觉得完整的上下文很重要。

上下文

下面的代码定义了一个Transaction案例类,一个用于所有事务的假DB,以及一个用于查询和创建事务的模式:

代码语言:javascript
复制
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模式如下:

代码语言:javascript
复制
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!
}

然后,我可以创建一个事务并使用以下查询查询它:

代码语言:javascript
复制
mutation {
  createTransaction(transaction: {
    id: 1
    description: "Electricity bill"
    amount: 100
  }) {
    id
  }
}

query {
  transaction(id: 1) {
    id
    description
    amount
  }
}

问题

然而,id不应该是突变的一部分。理想情况下,我会得到:

代码语言:javascript
复制
input TransactionInput {
  description: String!
  amount: BigDecimal!
}

type Mutation {
  createTransaction(input: TransactionInput): Transaction
  updateTransaction(id: Int!, input: TransactionInput): Transaction # For later
}

documentation中,这是使用以下内容来完成的:

代码语言:javascript
复制
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: --我在想这样的事情:

代码语言:javascript
复制
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被赋予了一个映射到TransactionTransactionArg

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

尝试3:我尝试使用以下方法更新派生InputObjectType以排除id

代码语言:javascript
复制
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中实现这一点。我读了很多次文档,并广泛地查看了谷歌,因为这似乎是一个简单的问题,但没有发现任何类似的东西。谢谢!

EN

回答 1

Stack Overflow用户

发布于 2017-02-15 09:33:41

createTransactionupdateTransaction似乎都返回定义为:

代码语言:javascript
复制
type Transaction {
  id: Int!
  description: String!
  amount: BigDecimal!
}

id: Int!声明id是必需的(这就是!的意思),所以我首先将它重新定义为:id: Int (没有感叹号)。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42180567

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档