graphql-python / flask-graphql

Adds GraphQL support to your Flask application.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Separate endpoint for GraphiQL

tlinhart opened this issue · comments

Hi,
wouldn't it make sense to have separate endpoints for GraphQL and GraphiQL? As per README, there should be two endpoints (/graphql and /graphiql), however only /graphql gets exposed. Let's say I would like to publish GraphiQL only to selected group of people (e.g. frontend developers) and protect it by authentication. Having a separate endpoint would make whole thing much easier.

If you set your graphql endpoint to not expose graphql and then add an authenticated view as a second endpoint at /graphiql is that enough for your situation?

class AuthenticatedView(GraphQLView):
    decorators = [some_authentication_method]

app.add_url_rule(
    '/graphiql',
    view_func=AuthenticatedView.as_view(
        'graphiql',
        schema=schema,
        graphiql=True
    )
)

Hi Jon,

I know the issue could be solved in a similar fashion to what you propose. I just don't think it's a clean solution. Mixing access to API endpoint and standalone tool that way doesn't feel right. In my opinion it simply violates separation of concerns principle with all the consequences it brings (code readability and maintainability etc.) If I omit the implementation part, the usage also doesn't seem too intuitive.

In the project I'm working on, I've separated the two, resulting in much cleaner code and components that can be handled completely independently of each other.

I have the same issue with you. So I just pass graphiql=False, copy the html templates comes from render_graphiql.py and change little codes:

...
var fetchURL = locationQuery(otherParams);
{% if requests_endpoint %}
  fetchURL = '{{ requests_endpoint }}' + fetchURL;
{% endif %}
...
@app.route('/graphiql', methods=['GET'])
def graphiql():
    return render_template_string(graphiql_template, graphiql_version='0.11.11', graphiql_html_title=None, result='null', params=GraphQLParams(None, None, None), requests_endpoint='/graphql')
from flask import Blueprint, jsonify
from app import db
from app.models import *
from flask_graphql import GraphQLView
from app.schema import schema


api = Blueprint('api', __name__)


@api.route("/")
def home():
    user = User(username="saki2", fname="saki", surname="saki", email="saki@saki.hr", password="saki")
    db.session.add(user)
    event = Event(title="idk", description="i don't know", organizer=User.query.filter_by(username="saki2").first())
    db.session.add(event)
    db.session.commit()
    return {"home": "page"}


# route for graphiql
api.add_url_rule(
    "/graphiql",
    "graphiql",
    view_func=GraphQLView.as_view(
        'graphql',
        schema=schema,
        graphiql=True
    )
)

# route for graphql without user interface (POST request)
api.add_url_rule(
    "/graphql",
    "graphql",
    view_func=GraphQLView.as_view(
        'graphql',
        schema=schema,
        batch=True
    )
)

This is what mine routes.py looks like for each endpoint

@api.route("/")
def home():

^^ This for adding users since i have not implemented mutations yet