|
1 | 1 | import Foundation
|
2 | 2 | import NIO
|
| 3 | +import RxSwift |
3 | 4 |
|
4 | 5 | public struct GraphQLResult : Equatable, Codable, CustomStringConvertible {
|
5 | 6 | public var data: Map?
|
@@ -151,3 +152,66 @@ public func graphql<Retrieval: PersistedQueryRetrieval>(
|
151 | 152 | )
|
152 | 153 | }
|
153 | 154 | }
|
| 155 | + |
| 156 | +/// This is the primary entry point function for fulfilling GraphQL subscription |
| 157 | +/// operations by parsing, validating, and executing a GraphQL subscription |
| 158 | +/// document along side a GraphQL schema. |
| 159 | +/// |
| 160 | +/// More sophisticated GraphQL servers, such as those which persist queries, |
| 161 | +/// may wish to separate the validation and execution phases to a static time |
| 162 | +/// tooling step, and a server runtime step. |
| 163 | +/// |
| 164 | +/// - parameter queryStrategy: The field execution strategy to use for query requests |
| 165 | +/// - parameter mutationStrategy: The field execution strategy to use for mutation requests |
| 166 | +/// - parameter subscriptionStrategy: The field execution strategy to use for subscription requests |
| 167 | +/// - parameter instrumentation: The instrumentation implementation to call during the parsing, validating, execution, and field resolution stages. |
| 168 | +/// - parameter schema: The GraphQL type system to use when validating and executing a query. |
| 169 | +/// - parameter request: A GraphQL language formatted string representing the requested operation. |
| 170 | +/// - parameter rootValue: The value provided as the first argument to resolver functions on the top level type (e.g. the query object type). |
| 171 | +/// - parameter contextValue: A context value provided to all resolver functions |
| 172 | +/// - parameter variableValues: A mapping of variable name to runtime value to use for all variables defined in the `request`. |
| 173 | +/// - parameter operationName: The name of the operation to use if `request` contains multiple possible operations. Can be omitted if `request` contains only one operation. |
| 174 | +/// |
| 175 | +/// - throws: throws GraphQLError if an error occurs while parsing the `request`. |
| 176 | +/// |
| 177 | +/// - returns: returns a SubscriptionResult containing the subscription observable inside the key `observable` and any validation or execution errors inside the key `errors`. The |
| 178 | +/// value of `observable` might be `null` if, for example, the query is invalid. It's not possible to have both `observable` and `errors`. The observable payloads are |
| 179 | +/// GraphQLResults which contain the result of the query inside the key `data` and any validation or execution errors inside the key `errors`. The value of `data` might be `null`. |
| 180 | +/// It's possible to have both `data` and `errors` if an error occurs only in a specific field. If that happens the value of that field will be `null` and there |
| 181 | +/// will be an error inside `errors` specifying the reason for the failure and the path of the failed field. |
| 182 | +public func graphqlSubscribe( |
| 183 | + queryStrategy: QueryFieldExecutionStrategy = SerialFieldExecutionStrategy(), |
| 184 | + mutationStrategy: MutationFieldExecutionStrategy = SerialFieldExecutionStrategy(), |
| 185 | + subscriptionStrategy: SubscriptionFieldExecutionStrategy = SerialFieldExecutionStrategy(), |
| 186 | + instrumentation: Instrumentation = NoOpInstrumentation, |
| 187 | + schema: GraphQLSchema, |
| 188 | + request: String, |
| 189 | + rootValue: Any = Void(), |
| 190 | + context: Any = Void(), |
| 191 | + eventLoopGroup: EventLoopGroup, |
| 192 | + variableValues: [String: Map] = [:], |
| 193 | + operationName: String? = nil |
| 194 | +) throws -> Future<SubscriptionResult> { |
| 195 | + |
| 196 | + let source = Source(body: request, name: "GraphQL Subscription request") |
| 197 | + let documentAST = try parse(instrumentation: instrumentation, source: source) |
| 198 | + let validationErrors = validate(instrumentation: instrumentation, schema: schema, ast: documentAST) |
| 199 | + |
| 200 | + guard validationErrors.isEmpty else { |
| 201 | + return eventLoopGroup.next().makeSucceededFuture(SubscriptionResult(errors: validationErrors)) |
| 202 | + } |
| 203 | + |
| 204 | + return subscribe( |
| 205 | + queryStrategy: queryStrategy, |
| 206 | + mutationStrategy: mutationStrategy, |
| 207 | + subscriptionStrategy: subscriptionStrategy, |
| 208 | + instrumentation: instrumentation, |
| 209 | + schema: schema, |
| 210 | + documentAST: documentAST, |
| 211 | + rootValue: rootValue, |
| 212 | + context: context, |
| 213 | + eventLoopGroup: eventLoopGroup, |
| 214 | + variableValues: variableValues, |
| 215 | + operationName: operationName |
| 216 | + ) |
| 217 | +} |
0 commit comments