Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions Sources/GraphQLHummingbird/HTTP/GraphQLHandler+HTTP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 5 additions & 1 deletion Sources/GraphQLHummingbird/Router+graphql.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
23 changes: 23 additions & 0 deletions Tests/GraphQLHummingbirdTests/HTTPTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Loading