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.
python3 -m venv venvStep 2: Activate the virtualenv and install Robyn
source venv/bin/activatepip install robyn strawberry-graphqlStep 3: Coding the App
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.
from typing import List, Optional
from robyn import Robyn, jsonify
import json
import dataclasses
import strawberry
import strawberry.utils.graphiqlHere, we are creating a base User type with a name property.
We are then creating a GraphQl Query that returns the User.
@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.
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.
@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.
@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.