graphene-gae
graphene-gae copied to clipboard
Passing query as JSON (for variables, etc.) seems broken
I'm very new to this GraphQL world but my understanding of GraphQL is that, in order to pass variables
or operation_name
in addition to query
, the body of POST has to be encoded in JSON. A GraphQL query HTML body, with a pair of query
and variables
, would look like:
{ "query": "...", "variables": "..." }
This does not seem to work with graphene-gae. I put many logging.warn()'s in _get_grapl_params()
but could not understand the intent. If the said assumption that GraphQL query body is either raw GraphQL or JSON, this _get_grapl_params()
would look like:
def _get_grapl_params(self):
try:
(read body as JSON)
except:
(read body as raw GraphQL)
(I even have no idea why this handler has to be implemented in graphene-gae, not graphene.)
I'm trying to fix this myself, but I'm slow; new to Python, new to GraphQL, new to Web world. Feel free to beat me. ;)
Probably checking Content-Type (either application/graphql
or application/json
) would be saner.
hey @uebayasi ,
do _get_graphql_params
starts with this code:
try:
request_data = self.request.json_body
if isinstance(request_data, basestring):
request_data = dict(query=request_data)
except:
request_data = {}
Meaning, if you send a JSON object ({ "query": "...", "variables": "..." }
) it'll use that, and if you send a JSON string it'll treat is as the query
.
The code that follows reads operation_name
and variables
from request_data
.
So if you send a POST request that looks like { "query": "...", "variables": "..." }
GraphQLHandler should handle it properly.
Are you having problems with such a request?
The reason this handler is implemented in graphene-gae
and not graphene
is that its written specifically for the Google AppEngine environment - using webapp2
which is GAE's web framework.
The main graphene
library should not depend on GAE specific code thats of no use to people on other platforms.
Thanks for the quick reply!
Now I see the problem; self.request.json_body
is failing for me. I grep -r'ed json_body
under google-cloud-sdk/platform/google_appengine/lib/webapp2-*
and got no result. There are references under other subdirectories but I have no idea of relevance.
json.loads(self.request.body)
surely works and that's I'm using it for now.
This is google-cloud-sdk 132.0.0 (2016/10/19).
In requests.py there's this code:
def _json_body__get(self):
"""Access the body of the request as JSON"""
return json.loads(self.body.decode(self.charset))
def _json_body__set(self, value):
self.body = json.dumps(value, separators=(',', ':')).encode(self.charset)
def _json_body__del(self):
del self.body
json = json_body = property(_json_body__get, _json_body__set, _json_body__del)
So basically self.request.json_body
is the same as doing json.loads(self.request.body.decode(self.charset))
This is part of the webob 1.2.3 library that webapp2 depends on
I see that webapp2-2.5.1 and webob-1.2.3 are used (imported) here. I can't figure out why those inherited methods are called.
I'll try to investigate this later, but I can't promise. Feeling like Python not being my friend. :(
For some reasons the request
object inherits class BaseRequest
in webob-1.1.1/webob/request.py, where _json_body__get
is not defined. webob-1.2.3's class BaseRequest
does define it.
Obviously this problem is not relevant to graphene-gae. It is either google-gcloud-sdk or python2.7 or my local environment causing the oddity. Feel free to close this issue.
Fortunately my project is not really started yet. I'm considering to switch to something and stay away from Python if possible... :(
I just ran into this issue on a fresh install of Google Cloud SDK. It seems that webob
version 1.1 gets loaded even though 1.2 is available. I fixed it by specifying the newer webob
in my app.yaml
:
libraries:
- name: webob
version: 1.2.3
- name: webapp2
version: 2.5.2