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.
Virtual Environment
python3 -m venv venv
Step 2: Activate the virtualenv and install Robyn
Activating the virtualenv
source venv/bin/activate
Installing Robyn and Strawberry
pip install robyn strawberry-graphql
Step 3: Coding the App
Code
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.
Section 1
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
.
Section 2
@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.
Section 3
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.
Section 4
@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.
Section 5
@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. :D Keep an eye out for more updates on this page. We will be adding more examples and documentation as we go along.