Javascript GraphQL(Apollo)如何在参数中传递数据结构?

Javascript GraphQL(Apollo)如何在参数中传递数据结构?,javascript,graphql,apollo,Javascript,Graphql,Apollo,我想用很多输入参数进行查询: apollo_client.mutate({mutation: gql `mutation mutation($title: String!, $caption: String!, $id: Int!){ mutatePmaHome(pmaData: {id:$id, title: $title, caption: $caption}) { pma{ title caption } }

我想用很多输入参数进行查询:

 apollo_client.mutate({mutation: gql
  `mutation mutation($title: String!, $caption: String!, $id: Int!){
    mutatePmaHome(pmaData: {id:$id, title: $title, caption: $caption}) {
      pma{
        title
        caption
      }
    }
  }`,
  variables: {
    title: this.state.title,
    caption: this.state.caption,
    id: this.state.id
  },
}).then(console.log);
这就是传递简单数据结构(Int,String)时查询的外观 但我的问题是:如何在变异查询中传递单词或对象。我不知道怎么打

graphQL中的文档说我必须创建一个输入对象。但这里我和apollo在js上,所以我如何在查询中传递一个词汇表以避免键入所有数据(这里是3,但可以是10到20)。我想要一个输入类型字段更简洁的方法,但我找不到一个例子


谢谢

在我看来,你可以采取两种方法

更安全的方法是创建一个包含键和值的类型。然后,您的字典将是键和值的列表。然后,您需要使用
let entry=dictionary.find((entry)=>entry.key==key),而不是以
let value=dictionary[key]
的形式访问属性;设value=entry&&entry.value

// Before
{
  red: 1,
  blue: 2,
  green: 3,
}

// After
[
  {key: 'red', value: 1},
  {key: 'blue', value: 2},
  {key: 'green', value: 3},
]
Typedefs:

type IntegerProperty {
    key: ID!
    value: Int
}

type IntegerDictionary {
    values: [IntegerProperty!]!
}

一种更快但不太安全的方法是使用类似或的东西。这些允许您在GraphQL查询中包含任意JSON;但是,您将失去GraphQL对数据格式的保证。

Swift 5.1、Apollo 0.21.0

字典中的键和值需要遵守Apollo JSONECODABLE协议:

public protocol JSONEncodable: GraphQLInputValue {
  var jsonValue: JSONValue { get }
}
您需要在字典中循环,并使用.jsonValue(JSONECODABLE协议)返回每个对象

[String:Any?]vs[String:String]

如果将[String:String]字典传递给Apollo,它将自动工作,因为String符合JSONECODABLE协议。键和值都是字符串类型

JSON通常在Swift中表示为[String:Any?],这意味着键必须是String,但值可以由任何对象(数组、Bool、Double、Null、String、Dictionary)表示

因为阿波罗不知道任何物体是什么,它会导致一个西格布特。这是因为该值可能是您编写的不兼容JSON的自定义类

必须将Any对象强制转换为符合JSONECODABLE协议的类

由于默认情况下[String:Any?]无法定义Any对象,因此通用JSON库通过创建一个新类来表示JSON数据来实现这一点

下面的示例将JSONEncodable协议扩展到GenericJSON类,以确保该值符合Apollo突变所需的JSONEncodable协议

建立遵守JSONECODABLE协议的词典

  • 将通用JSON库添加到pod文件:
  • pod'GenericJSON'
    

  • 导入GenericJSON库,并在一些ApolloExtensions.swift文件中为您的自定义JSON GraphQL scalar创建别名。此别名将映射到GenericJSON库:
  • 在ApolloExtensions.swift文件中,为GenericJSON添加一个JSONECODABLE扩展名:
  • import GenericJSON
    
    // CUSTOM JSON SCALAR
    
    public typealias MyJsonScalar = JSON
    
    extension JSON: JSONEncodable {
    
        public var jsonValue: JSONValue {
    
            if self.objectValue != nil {
    
                return jsonObject as JSONObject
    
            }
    
            if self.arrayValue != nil {
    
                var array : Array<JSONEncodable> = []
    
                for obj in self.arrayValue! {
    
                    if obj.arrayValue != nil {
    
                        array.append(obj.jsonValue as! Array<JSONEncodable>)
    
                    } else if obj.objectValue != nil {
    
                        array.append(obj.jsonValue as! JSONObject)
    
                    } else {
    
                        array.append(obj.jsonValue as! JSONEncodable)
    
                    }
    
                }
    
                return array as Array<JSONEncodable>
    
            }
    
            if self.stringValue != nil {
    
                return self.stringValue! as String
    
            }
    
            if self.doubleValue != nil {
    
                return self.doubleValue! as Double
    
            }
    
            if self.boolValue != nil {
    
                return self.boolValue! as Bool
    
            }
    
            if self.isNull {
    
                return "" as String
    
            }
    
            return "" as String
    
        }
    
        public var jsonObject: JSONObject {
    
            var jsonObject : JSONObject = JSONObject(minimumCapacity: self.objectValue!.count)
    
            for (key, value) in self.objectValue! {
    
                if value.arrayValue != nil {
    
                    jsonObject[key] = value.jsonValue as! Array<JSONEncodable>
    
                } else if value.objectValue != nil {
    
                    jsonObject[key] = value.jsonValue as! JSONObject
    
                } else {
    
                    jsonObject[key] = value.jsonValue as! JSONEncodable
    
                }
    
            }
    
            return jsonObject
    
        }
    
    }
    
    func createJSONDictionary() {
    
        let myDictionary : [String: Any?] = ["foo" : "foo", "bar" : 2]
    
        do {
    
            let jsonData : Data = try JSONSerialization.data(withJSONObject: myDictionary, options: [])
    
            if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String : Any?] {
    
                let json: JSON = try JSON(jsonObject)
    
                self.myGraphQLMutation(json: json)
    
            } else {
    
                // casting error
    
            }
    
        } catch {
    
            // json error
    
        }
    
    }
    
    func myGraphQLMutation(json: JSON) {
    
        // apollo
    
        let apollo : ApolloClient = ApolloHelper.shared.client
    
        // myMutation
    
        let myMutation = MyMutation(json: json)
    
        // perform
    
        apollo.perform(mutation: myMutation, queue: DispatchQueue.global()) { result in
    
            switch result {
    
                case .success(let graphQLResult):
    
                    // Deal with GraphQLResult and its data and/or errors properties here
    
                    break
    
                case .failure(let error):
    
                    // deal with network errors here
    
                    return
    
            }
    
        }
    
    }