Graphene Django "Must provide query string"
Asked Answered
U

7

10

I have setup a Graphene server using Django. When I run my queries through GraphiQL (the web client), everything works fine. However, when I run from anywhere else, I get the error: "Must provide query string."

I did some troubleshooting. GraphiQL sends POST data to the GraphQL server with Content-Type: application/json. Here is the body of the request that I copied from Chrome network tab for GraphiQL:

{"query":"query PartnersQuery {\n  partners{\n    name\n    url\n    logo\n  }\n}","variables":"null","operationName":"PartnersQuery"}

When I copy it to Postman with Content-Type: application/json, I get the following response:

{
  "errors": [
    {
      "message": "Must provide query string."
    }
  ]
}

What can be the cause of this problem? I have not done anything crazy with the schema. Just followed the tutorials from graphene's docs. What else can cause an issue like this?

Umbilicate answered 25/5, 2017 at 16:15 Comment(0)
D
2

Checkout sample apps and see how they do things,

e.g. https://github.com/mjtamlyn/graphene-tutorial they do the following:

from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView

url(r'^explore', GraphQLView.as_view(graphiql=True)),
url(r'^graphql', csrf_exempt(GraphQLView.as_view())),
Dantzler answered 5/6, 2017 at 12:24 Comment(0)
S
4

This error is raised when parse_body is unable to parse the incoming data. I'd start there by looking at the data passed into this method and ensuring it's of the correct type.

For example, the multipart/form-data section naively returns request.POST, which may need to be overwritten to handle, for example, the request that apollo-upload-client sends for file upload handling. In our case we created a view to both require a login and to support the apollo-upload-client use case and it works fine.

Same answered 7/6, 2017 at 18:7 Comment(2)
Hi @adam-donahue can you show your implementation of your custom parse_body function and how to overwrite this method. So pretty much you pointed me to the problem I was investigating all day long. For authentication I am attaching a custom TokenAuthentication class using the authentication_classes decorator from rest_framework. Not sure where to start to manipulate parse_body. Can you point me into the right direction?Cataplexy
github.com/graphql-python/graphene-django/issues/404 ok I found a solution posted here:)Cataplexy
D
2

Checkout sample apps and see how they do things,

e.g. https://github.com/mjtamlyn/graphene-tutorial they do the following:

from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView

url(r'^explore', GraphQLView.as_view(graphiql=True)),
url(r'^graphql', csrf_exempt(GraphQLView.as_view())),
Dantzler answered 5/6, 2017 at 12:24 Comment(0)
A
2

Here's how I was able to get a successful response from Postman using a graphene Django backend with a simple mutation:

  1. Set method to POST
  2. Add the URL to your graphQL endpoint, e.g. http://localhost:8000/api/
  3. Add one header -- key: "Content-Type" , value: "application/json"
  4. Set the body to "raw"
  5. Paste in your query into the body window, e.g. {"query":"{myModels {id}}","variables":"null","operationName":null}

This sounds pretty much like what you did, so you must be close.

Algetic answered 12/6, 2017 at 21:37 Comment(0)
H
2

I faced the same problem when I try to used graphQl query using POSTMAN, In POSTMAN send data in row with json type. You have to make json data grapQl query and mutations data like this

Query Command:

{"query":"{user(id:902){id,username,DOB}}"}

Mutations Command:

{ "query": "mutation {createMutations(reviewer:36, comments:\"hello\",loan: 1659, approved: true ){id}}" }

       #commnent: String Type
       #data_id:Int Type
       #approved:Boolean Type
Hautemarne answered 26/4, 2018 at 12:52 Comment(0)
R
1

Enable graphine on django

  url(r'^graphql', csrf_exempt(GraphQLView.as_view(graphiql=settings.DEBUG))),

Execute some query and see it is working

On Chrome browser, go to graphiQL endpoint: http://localhost:8000/graphql? open "Developer Tools" in browser and go to "Network" tab.

Execute your query again. Now it appears on list of requests. Now right mouse click on it and copy it "copy as CURL". Now you can strait copy paste it to linux terminal with curl installed. Or like in your case you can try to deduct what is what there, and try to reuse it in your IDE like client like Insomnia or Postman. For instance you may discover that authorisation that works with session on graphiQL enpoint, is not what you want at the end...

curl 'http://localhost:8000/graphql?' -H 'Origin: http://localhost:8000' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,pl;q=0.8,de;q=0.7' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Cookie: _ga=GA1.1.1578283610.1528109563; _gid=GA1.1.920024733.1541592686; csrftoken=EGBeegFoyMVl8j1fQbuEBG587nOFP2INwv7Q0Ee6HeHHmsLOPUwRonzun9Y6pOjV; sessionid=4u9vngcnmjh927a9avpssvc4oq9qyqoe' -H 'Connection: keep-alive' -H 'X-CSRFToken: EGBeegFoyMVl8j1fQbuEBG587nOFP2INwv7Q0Ee6HeHHmsLOPUwRonzun9Y6pOjV' --data-binary '{"query":"{\n  allStatistics(projectId: 413581, first:25) {\n    pageInfo {\n      startCursor\n      endCursor\n      hasPreviousPage\n      hasNextPage\n    }\n    edges {\n      cursor\n      node {\n        id\n        clickouts\n        commissionCanc\n        commissionConf\n        commissionLeads\n        commissionOpen\n        eventDate\n        extractTstamp\n        hash\n        leads\n        pageviews\n        projectId\n        transactionsCanc\n        transactionsConf\n        transactionsOpen\n      }\n    }\n  }\n}\n","variables":null,"operationName":null}' --compressed
Rare answered 8/11, 2018 at 14:24 Comment(0)
M
0

I encountered exactly the same problem as the original poster, Gasim. Studying the code in 'graphiql.html' I see that they're converting the query string, that goes into the body, into the query parameter in the URL. Thus you end up with this URL being sent via Postman:

http://127.0.0.1:8000/graphql?query=%7B%0A%20%20allCategories%20%7B%0A%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20name%0A%20%20%20%20%20%20%20%20ingredients%20%7B%0A%20%20%20%20%20%20%20%20%20%20edges%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20node%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A

It seems nonsensical to me to duplicate precisely what's in the body in the query string in the URL too but that appears to be the only way to get the Graphene server to return a valid response.

Surely this is a bug/shortcoming that will be fixed?

Robert

Mycenae answered 22/6, 2017 at 23:52 Comment(0)
U
-1

The problem in my code was that I had the URL improperly setup for graphQL. I had the following:

url(r'^graphql/', GraphQLView.as_view())

The forward slash was a huge difference. Removing it fixed the problem. The proper way to do it would be:

url(r'^graphql', GraphQLView.as_view())
Umbilicate answered 15/7, 2017 at 15:38 Comment(1)
Try ^graphql/$ so that it catches everything in the URLPhago

© 2022 - 2024 — McMap. All rights reserved.