Skip to content

GraphQL Support (With Strawberry 🍓)

This is in a very early stage right now. We will have a much more stable version when we have a stable API for Views and View Controllers.

Step 1: Creating a virtualenv

To ensure that there are isolated dependencies, we will use virtual environments.

py
python3 -m venv venv

Step 2: Activate the virtualenv and install Robyn

py
source venv/bin/activate
py
pip install robyn strawberry-graphql

Step 3: Coding the App

py
from typing import List, Optional
from robyn import Robyn, jsonify
import json

import dataclasses
import strawberry
import strawberry.utils.graphiql


@strawberry.type
class User:
  name: str


@strawberry.type
class Query:
  @strawberry.field
  def user(self) -> Optional[User]:
      return User(name="Hello")


schema = strawberry.Schema(Query)

app = Robyn(__file__)


@app.get("/", const=True)
async def get():
  return strawberry.utils.graphiql.get_graphiql_html()


@app.post("/")
async def post(request):
  body = request.json()
  query = body["query"]
  variables = body.get("variables", None)
  context_value = {"request": request}
  root_value = body.get("root_value", None)
  operation_name = body.get("operation_name", None)

  data = await schema.execute(
      query,
      variables,
      context_value,
      root_value,
      operation_name,
  )

  return jsonify(
      {
          "data": (data.data),
          **({"errors": data.errors} if data.errors else {}),
          **({"extensions": data.extensions} if data.extensions else {}),
      }
  )


if __name__ == "__main__":
  app.start(port=8080, host="0.0.0.0")

Let us try to decipher the usage line by line.

These statements just import the dependencies.

py
from typing import List, Optional

from robyn import Robyn, jsonify
import json

import dataclasses
import strawberry
import strawberry.utils.graphiql

Here, we are creating a base User type with a name property.

We are then creating a GraphQl Query that returns the User.

py
@strawberry.type
class User:
    name: str


@strawberry.type
class Query:
    @strawberry.field
    def user(self) -> Optional[User]:
        return User(name="Hello")


schema = strawberry.Schema(Query)

Now, we are initializing a Robyn app. For us, to serve a GraphQl app, we need to have a get route to return the GraphiQL(ide) and then a post route to process the GraphQl request.

py
app = Robyn(__file__)

We are populating the html page with the GraphiQL IDE using strawberry. We are using const=True to precompute this population. Essentially, making it very fast and bypassing the execution overhead in this get request.

py
@app.get("/", const=True)
async def get():
return strawberry.utils.graphiql.get_graphiql_html()

Finally, we are getting params(body, query, variables, context_value, root_value, operation_name) from the request object.

py
@app.post("/")
async def post(request):
body = request.json()
query = body["query"]
variables = body.get("variables", None)
context_value = {"request": request}
root_value = body.get("root_value", None)
operation_name = body.get("operation_name", None)

data = await schema.execute(
    query,
    variables,
    context_value,
    root_value,
    operation_name,
)

return jsonify(
    {
        "data": (data.data),
        **({"errors": data.errors} if data.errors else {}),
        **({"extensions": data.extensions} if data.extensions else {}),
    }
)

The above is the example for just one route. You can do the same for as many as you like. 😃

What's next?

That's all folks. 😄 Keep an eye out for more updates on this page. We will be adding more examples and documentation as we go along.

Released under the MIT License.