simonw / datasette-graphql

Datasette plugin providing an automatic GraphQL API for your SQLite databases
https://datasette-graphql-demo.datasette.io/
Apache License 2.0
101 stars 6 forks source link

Support GET as well as POST #6

Closed simonw closed 4 years ago

simonw commented 4 years ago

GraphiQL desktop app provides this as an option.

simonw commented 4 years ago

https://graphql.org/learn/serving-over-http/#http-methods-headers-and-body

Your GraphQL HTTP server should handle the HTTP GET and POST methods.

GET request

When receiving an HTTP GET request, the GraphQL query should be specified in the "query" query string. For example, if we wanted to execute the following GraphQL query:

{
  me {
    name
  }
}

This request could be sent via an HTTP GET like so:

http://myapi/graphql?query={me{name}}

Query variables can be sent as a JSON-encoded string in an additional query parameter called variables. If the query contains several named operations, an operationName query parameter can be used to control which one should be executed.

simonw commented 4 years ago

I'm serving GraphiQL from on GET to /graphql at the moment if there is now POST body.

https://github.com/simonw/datasette-graphql/blob/c06b5e3566a05a9ddfedd8f5f3cfb7ef6f988c2c/datasette_graphql/__init__.py#L24-L39

To support GET I can change this logic to include a check to see if ?query= was passed.

simonw commented 4 years ago

I'm going to imitate Starlette here: they do this:

        if request.method in ("GET", "HEAD"):
            if "text/html" in request.headers.get("Accept", ""):
                if not self.graphiql:
                    return PlainTextResponse(
                        "Not Found", status_code=status.HTTP_404_NOT_FOUND
                    )
                return await self.handle_graphiql(request)

Where handle_graphiql(request) returns the GraphiQL interface.

One difference: I'm going to set Vary: accept on the GraphiQL response to ensure things can be cached correctly.