I have the following code: ```object HelloWorldQue...
# http4k
a
I have the following code:
Copy code
object HelloWorldQueryHandler {
  fun hello(yourname: String) = "Hello $yourname"
}

class GraphQLHandler: GraphQLHandler {
  private val graphql = newGraphQL(
    toSchema(
      SchemaGeneratorConfig(supportedPackages = listOf("no.example.capgemini")),
      listOf(TopLevelObject(HelloWorldQueryHandler))
    )
  ).build()

  override fun invoke(request: GraphQLRequest): GraphQLResponse =
    GraphQLResponse.from(
      graphql.execute {
        Builder()
          .query(request.query)
          .variables(request.variables)
      }
    )
}

fun main() {
  val app = routes("/graphql" bind graphQL(GraphQLHandler()))
  app.asServer(Netty()).start()
}
Now, this works when I use the GraphQL playground, but not when I use the Graphiql client. For the Graphiql client, this just returns an empty response. Am I missing something? Why is there a difference?
d
suggest that you put a debugging filter on the handler
handler.debug()
and sniff what the difference in request is
a
@dave: where exactly do you mean? I don’t quite understand where the
handler
object is 😮
d
Copy code
app.debug().asServer(Netty()).start()
a
Copy code
***** REQUEST: POST: /graphql *****
POST /graphql HTTP/1.1
Host: localhost:8000
Connection: keep-alive
accept: */*
Origin: null
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) GraphQLPlayground/1.8.10 Chrome/61.0.3163.100 Electron/2.0.11 Safari/537.36
content-type: application/json
Accept-Encoding: gzip, deflate
Accept-Language: en-GB
content-length: 84

<<stream>>
***** RESPONSE 200 to POST: /graphql *****
HTTP/1.1 200 OK
content-type: application/json; charset=utf-8

{"data":{"hello":"Hello arnab"},"errors":null}
***** REQUEST: POST: /graphql *****
POST /graphql HTTP/1.1
Content-Type: application/json
User-Agent: graphiql-app
Host: localhost:8000
Connection: close
content-length: 65

<<stream>>
***** RESPONSE 400 to POST: /graphql *****
HTTP/1.1 400 Bad Request
What in the world…?
d
put
debug(debugStreams=true)
instead. you'll get the content of the request
a
So this:
{"query":"{\n  hello(yourname:\"Arnab\")\n}","variables":null}
gives 400, but this does not
{"operationName":null,"variables":{},"query":"{\n  hello(yourname: \"arnab\")\n}\n"}
I am really not sure what’s going on here. The first one is from Graphiql and the other from GraphQL playground.
In my eyes both are identical except playground sends an empty dict for variables and null for operation name
Apparently sending an empty dict in GraphiQL is the thing 😮 This is really strange
d
I think the problem is that at the moment the vraiables can't be null
Copy code
data class GraphQLRequest(val query: String = "",
                          val operationName: String? = null,
                          val variables: Map<String, Any> = emptyMap()) {
    companion object {
        val requestLens = Body.auto<GraphQLRequest>().toLens()
    }
}
interestingly - the graphql java lib will blow up if it is null:
Copy code
this.variables = assertNotNull(variables, () -> "variables map can't be null");
we can easily fix it, but I'm not sure what the actual spec says about if the fields are nullable
a
Well, I took a look at the specs, and as far as I can see here, variables are not required in a query. Nullability. I cannot say anything about however: https://spec.graphql.org/June2018/#sec-Validation What I can say however, is that apollo graphql for instance, has nullable variables: https://github.com/apollographql/apollo-client/blob/cbcf951256b22553bdb065dfa0d32c0a4ca804d3/src/react/hooks/useQuery.ts
d
no problem - we can fix it to not blow up in the absence of variables
a
Where is this code from?
Copy code
this.variables = assertNotNull(variables, () -> "variables map can't be null");
(the snippet you posted above)
d
that's from graphql-java library
a
This is interesting. I’ll take a look as to how ktor solves this for instance.
d
well it's just a matter of making the field nullable and passing in an empty map instead. it's already fixed
a
Oh ok, is the release already out?
d
not yet
it's out now 🙂