diff --git a/Sources/GraphQLHummingbird/HTTP/GraphQLHandler+HTTP.swift b/Sources/GraphQLHummingbird/HTTP/GraphQLHandler+HTTP.swift index 1de86e3..0ce1c7b 100644 --- a/Sources/GraphQLHummingbird/HTTP/GraphQLHandler+HTTP.swift +++ b/Sources/GraphQLHummingbird/HTTP/GraphQLHandler+HTTP.swift @@ -6,13 +6,39 @@ import NIOCore extension GraphQLHandler { /// https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md#get - func handleGet(request: Request, context: Context) async throws -> Response { + func handleGet(request: Request, context: Context, jsonDecoder: JSONDecoder) async throws + -> Response + { guard config.allowGet else { throw HTTPError(.methodNotAllowed, message: "GET requests are disallowed") } // Decode query parameters as GraphQLRequest - let graphQLRequest = try request.uri.decodeQuery(as: GraphQLRequest.self, context: context) + let queryParameters = request.uri.queryParameters + guard let query = queryParameters.get("query") else { + throw HTTPError(.badRequest, message: "`query` parameter is required") + } + let variables: [String: Map] + if let queryVariables = queryParameters.get("variables") { + do { + variables = try jsonDecoder.decode( + [String: Map].self, + from: Data(queryVariables.utf8) + ) + } catch { + throw HTTPError( + .badRequest, + message: "`variable` parameter could not be decoded: \(error)" + ) + } + } else { + variables = [:] + } + let graphQLRequest = GraphQLRequest( + query: query, + operationName: queryParameters.get("operationName"), + variables: variables + ) let operationType: OperationType do { diff --git a/Sources/GraphQLHummingbird/Router+graphql.swift b/Sources/GraphQLHummingbird/Router+graphql.swift index 07e37e6..898d528 100644 --- a/Sources/GraphQLHummingbird/Router+graphql.swift +++ b/Sources/GraphQLHummingbird/Router+graphql.swift @@ -53,7 +53,11 @@ extension RouterMethods { } // Normal GET request handling - return try await handler.handleGet(request: request, context: context) + return try await handler.handleGet( + request: request, + context: context, + jsonDecoder: config.coders.jsonDecoder + ) } post(path) { request, context in diff --git a/Tests/GraphQLHummingbirdTests/HTTPTests.swift b/Tests/GraphQLHummingbirdTests/HTTPTests.swift index fc182c2..c2e8555 100644 --- a/Tests/GraphQLHummingbirdTests/HTTPTests.swift +++ b/Tests/GraphQLHummingbirdTests/HTTPTests.swift @@ -272,6 +272,29 @@ struct HTTPTests { } } + @Test func getRequestParsesEmtpyVariables() async throws { + let router = Router() + router.graphql(schema: helloWorldSchema) { _ in + EmptyContext() + } + let app = Application(router: router) + + try await app.test(.router) { client in + try await client.execute( + uri: "/graphql?query=%7Bhello%7D&variables=%7B%7D", + method: .get, + headers: jsonGraphQLHeaders + ) { response in + var body = response.body + #expect(response.status == .ok) + + let result = try defaultJSONDecoder.decode(GraphQLResult.self, from: response.body) + #expect(result.data?["hello"] == "World") + #expect(result.errors.isEmpty) + } + } + } + @Test func disallowGetRequest() async throws { let router = Router() router.graphql(