Skip to content
This repository has been archived by the owner on Sep 6, 2022. It is now read-only.

Passing query as JSON (for variables, etc.) seems broken #24

Open
uebayasi opened this issue Oct 28, 2016 · 8 comments
Open

Passing query as JSON (for variables, etc.) seems broken #24

uebayasi opened this issue Oct 28, 2016 · 8 comments

Comments

@uebayasi
Copy link

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. ;)

@uebayasi
Copy link
Author

Probably checking Content-Type (either application/graphql or application/json) would be saner.

@ekampf
Copy link
Collaborator

ekampf commented Oct 28, 2016

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.

@uebayasi
Copy link
Author

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).

@ekampf
Copy link
Collaborator

ekampf commented Oct 29, 2016

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))

@ekampf
Copy link
Collaborator

ekampf commented Oct 29, 2016

This is part of the webob 1.2.3 library that webapp2 depends on

@uebayasi
Copy link
Author

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. :(

@uebayasi
Copy link
Author

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... :(

@nolanw
Copy link
Contributor

nolanw commented Feb 27, 2017

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants