簡體   English   中英

GraphQL (Apollo) 如何在參數中傳遞數據結構?

[英]GraphQL (Apollo) how to pass datastructure in parameter?

我想使用大量輸入參數進行查詢:

 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 value = dictionary[key] ,然后您需要使用let entry = dictionary.find((entry) => entry.key === key); let value = entry && entry.value let entry = dictionary.find((entry) => entry.key === key); let value = entry && entry.value

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

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

類型定義:

type IntegerProperty {
    key: ID!
    value: Int
}

type IntegerDictionary {
    values: [IntegerProperty!]!
}

一種更快但類型安全性較低的方法是使用類似graphql-type-jsongraphql-json-object-type 這些允許您在 GraphQL 查詢中包含任意 JSON; 但是,您將失去 GraphQL 對數據格式的保證。

斯威夫特 5.1,阿波羅 0.21.0

字典中的鍵和值需要遵守 Apollo JSONEncodable 協議:

public protocol JSONEncodable: GraphQLInputValue {
  var jsonValue: JSONValue { get }
}

您需要遍歷您的 Dictionary 並使用 .jsonValue(JSONEncodable 協議)返回每個對象。

[字符串:任何?] vs [字符串:字符串]

如果您將 [String : String] 的字典傳遞給 Apollo,它會自動工作,因為 String 符合 JSONEncodable 協議。 鍵和值都是字符串類型。

JSON 在 Swift 中通常表示為 [String : Any?],這意味着鍵必須是 String,但值可以是 Any 對象(Array、Bool、Double、Null、String、Dictionary)。

因為 Apollo 不知道 Any 對象是什么,所以會導致 SIGABRT。 這是因為該值可能是您編寫的與 JSON 不兼容的自定義類。

您必須將 Any 對象強制轉換為符合 JSONEncodable 協議的類。

由於 [String : Any?] 默認情況下無法定義 Any 對象,因此通用 JSON 庫通過創建一個新類來表示 JSON 數據來實現這一點。

下面的示例將 JSONEncodable 協議擴展到 GenericJSON 類,以確保該值符合 Apollo 進行突變所需的 JSONEncodable 協議。

構建符合 JSONEncodable 協議的字典

  1. 將通用 JSON 庫添加到您的 pod 文件中:

https://github.com/zoul/generic-json-swift

pod 'GenericJSON'

  1. 導入GenericJSON庫並在某些ApolloExtensions.swift文件中為您的自定義 JSON GraphQL 標量創建別名。 此別名將映射到 GenericJSON 庫:
import GenericJSON

// CUSTOM JSON SCALAR

public typealias MyJsonScalar = JSON
  1. ApolloExtensions.swift文件中,為 GenericJSON JSON 添加一個 JSONEncodable 擴展:
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

    }

}
  1. 從您的字典中創建一個 JSON 對象並將其傳遞到您的 GraphQL 變更中:
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

        }

    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM