-
Notifications
You must be signed in to change notification settings - Fork 749
Expand file tree
/
Copy pathGraphQLResponse.swift
More file actions
105 lines (87 loc) · 3.62 KB
/
GraphQLResponse.swift
File metadata and controls
105 lines (87 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import Foundation
/// Represents a GraphQL response received from a server.
public final class GraphQLResponse<Data: GraphQLSelectionSet> {
public let body: JSONObject
private var rootKey: String
private var variables: GraphQLMap?
public init<Operation: GraphQLOperation>(operation: Operation, body: JSONObject) where Operation.Data == Data {
self.body = body
rootKey = rootCacheKey(for: operation)
variables = operation.variables
}
func setupOperation<Operation: GraphQLOperation> (_ operation: Operation) {
self.rootKey = rootCacheKey(for: operation)
self.variables = operation.variables
}
/// Parses a response into a `GraphQLResult` and a `RecordSet`.
/// The result can be sent to a completion block for a request.
/// The `RecordSet` can be merged into a local cache.
/// - Parameter cacheKeyForObject: See `CacheKeyForObject`
/// - Returns: A `GraphQLResult` and a `RecordSet`.
public func parseResult(cacheKeyForObject: CacheKeyForObject? = nil) throws -> (GraphQLResult<Data>, RecordSet?) {
let errors: [GraphQLError]?
if let errorsEntry = body["errors"] as? [JSONObject] {
errors = errorsEntry.map(GraphQLError.init)
} else {
errors = nil
}
let extensions = body["extensions"] as? JSONObject
if let dataEntry = body["data"] as? JSONObject {
let executor = GraphQLExecutor { object, info in
return object[info.responseKeyForField]
}
executor.cacheKeyForObject = cacheKeyForObject
let mapper = GraphQLSelectionSetMapper<Data>()
let normalizer = GraphQLResultNormalizer()
let dependencyTracker = GraphQLDependencyTracker()
let (data, records, dependentKeys) = try executor.execute(selections: Data.selections,
on: dataEntry,
withKey: rootKey,
variables: variables,
accumulator: zip(mapper, normalizer, dependencyTracker))
return (
GraphQLResult(data: data,
extensions: extensions,
errors: errors,
source: .server,
dependentKeys: dependentKeys),
records
)
} else {
return (
GraphQLResult(data: nil,
extensions: extensions,
errors: errors,
source: .server,
dependentKeys: nil),
nil
)
}
}
public func parseErrorsOnlyFast() -> [GraphQLError]? {
guard let errorsEntry = self.body["errors"] as? [JSONObject] else {
return nil
}
return errorsEntry.map(GraphQLError.init)
}
public func parseResultFast() throws -> GraphQLResult<Data> {
let errors = self.parseErrorsOnlyFast()
let extensions = body["extensions"] as? JSONObject
if let dataEntry = body["data"] as? JSONObject {
let data = try decode(selectionSet: Data.self,
from: dataEntry,
variables: variables)
return GraphQLResult(data: data,
extensions: extensions,
errors: errors,
source: .server,
dependentKeys: nil)
} else {
return GraphQLResult(data: nil,
extensions: extensions,
errors: errors,
source: .server,
dependentKeys: nil)
}
}
}