graphql-python / graphene-gae

GraphQL Support for Google AppEngine [DEPRECATED - Looking for maintainers]

Home Page:http://docs.graphene-python.org/projects/gae/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GraphiQL Integration for Webapp2

mrrobby opened this issue · comments

Are there any guidelines for integrating GraphiQL here? I saw the Django integration, but it seems a bit different.

Hey @mrrobby
So basically Graphiql is a static React website - a bunch of html, js, css resources that you need to serve from some protcted path.

Basically if you look here:
https://github.com/graphql-python/django-graphiql/tree/master/django_graphiql

You need to:

  1. Take the files in static put them in your own folder where they're acccesible (see https://cloud.google.com/appengine/docs/python/getting-started/serving-static-files)
  2. Take templates/index.htmland convert it to a jinja2 template, also convert the path to teh static files to whatever you configured in #1
  3. You'll probably want to add some auth protection to the handler you write in #2 (https://cloud.google.com/appengine/docs/python/oauth/)

Thanks @ekampf
That makes total sense. I stepped into this project already built out and trying to add in graphQL to it. There's some static setup for admin purposes already. I'll try to integrate it there after lunch and let you know. Thanks again!

As a side note, it could be possible to follow the Flask-GraphQL approach, where the /graphql endpoint also serves the GraphiQL interface when possible (this way is also the same express-graphql is using).

This approach will be the default too in the next version of django-graphiql package (that will be merged into django-graphql-view).
Also, the GraphiQL view will be using the js assets from jsdelivr.net, this way you don't need to host the static files anywhere.

https://github.com/graphql-python/flask-graphql/blob/master/flask_graphql/render_graphiql.py

@syrusakbary sounds like I'll be bale to add a GraphiqlHandler to the library on the next branch...

It's being quite long since the last message here.

How can I serve GraphiQL today using webapp2?

Hey @svpino did you get this sorted? I did this a long time ago. Let's see if the pieces I have make sense:

# app/handlers/graphiql_handler.py
from . import *
from .. import *

import graphene
from graphene import relay, resolve_only_args
from graphene_gae import NdbNode, NdbConnectionField

#Admin only class for visual interface to GraphQL querying
#  IMPORTANT - We must check security on this before production
#  Set your security in BaseHandler

class GraphiQLHandler(BaseHandler):

    def get(self):
        user = users.get_current_user()
        query = self.request.get('query')
        variables = self.request.get('variables')
        response = ''
        graphql_url = '/graphql'

        values = dict(<your_other_values>, user=user, graphql_url=graphql_url, response=response,
                      variables=variables,query=query)


        path = os.path.dirname(__file__)
        path = os.path.join(path, '../templates/admin/graphiql.html')
        self.response.out.write(render_to_string(path, values))

In the graphiql.html file, I was having trouble with the root node. Here's the part I had to edit, but it still may need slight adjustment, and this is a bit older of code

<!DOCTYPE html>
<html>
  <head>
    <style>
      html, body {
        height: 100%;
        margin: 0;
        overflow: hidden;
        width: 100%;
      }
    </style>
    <link rel="stylesheet" href="/static/graphiql/graphiql.css" />
    <script src="/static/graphiql/react.min.js"></script>
    <script src="/static/graphiql/react-dom.min.js"></script>
    <script src="/static/graphiql/fetch.min.js"></script>
    <script src="/static/graphiql/graphiql.min.js"></script>
  </head>
  <body>
    <script>
.
.
.
     var fetchURL = locationQuery(otherParams);
      // Defines a GraphQL fetcher using the fetch API.
      function graphQLFetcher(graphQLParams) {
        var headers = {
          "Accept": "application/json",
          "Content-Type": "application/json"
        };

        /* mrrobby 
        Changed JSON.stringify(graphQLParams) to graphQLParams.query to remove 
        the "query": key from the front of the params
        - We should test it with a try catch block first */
        if (csrftoken)
          headers["X-CSRFToken"] = csrftoken;
        return fetch("{{ graphql_url|escapejs }}"+fetchURL, {
          method: "post",
          headers: headers,
          body: graphQLParams.query,
          credentials: "include",
        }).then(function (response) {
          return response.text();
        }).then(function (responseBody) {
          try {
            return JSON.parse(responseBody);
          } catch (error) {
            return responseBody;
          }
        });
      }
.
.
.
      ReactDOM.render(
        React.createElement(GraphiQL, {
          fetcher: graphQLFetcher,
          query: "{{ query|escapejs }}",
          variables: "{{ variables|escapejs }}",
          response: "{{ response|escapejs }}",
          onEditQuery: onEditQuery,
          onEditVariables: onEditVariables,
        }),
        document.body
      );
    </script>
  </body>
</html>

Hope it helps!