Playing With GraphQL + Python Flask + Mongo
Recently I begin to learn GraphQL and try to use it in my side-project with flask and mongo, and there are some tutorials to show how to build it, but most of them are built from scratch (ex: [flask-graphql-example] (https://github.com/msoedov/flask-graphql-example)), or out of date, so I decide to start it my own: Graphene-Mongo.
Today I will not go to the detail of the implementation of Graphene-Mongo, but show you how to build a beauty in simplicity flask application based on it.
Setup the project
# Create the project directory
mkdir flask_graphene_mongo
cd flask_graphene_mongo
# [Optional but suggested] Create a virtualenv to isolate our package dependencies locally
virtualenv env
source env/bin/activate
# Install required packages
pip install Flask
pip install Flask-GraphQL
pip install graphene-mongo
# Install mongomock or you have to run a real mongo server instance somewhere.
pip install mongomock
Defining our models
Let’s get start with following models:
# flask_graphene_mongo/models.py
from datetime import datetime
from mongoengine import Document
from mongoengine.fields import (
DateTimeField, ReferenceField, StringField,
)
class Department(Document):
meta = {'collection': 'department'}
name = StringField()
class Role(Document):
meta = {'collection': 'role'}
name = StringField()
class Employee(Document):
meta = {'collection': 'employee'}
name = StringField()
hired_on = DateTimeField(default=datetime.now)
department = ReferenceField(Department)
role = ReferenceField(Role)
Schema
Here I assume you guys have the basic knowledage of how schema works in GraphQL, that I define the root type as the Query
class below with the ability to list all employees, all roles in flask_graphene_mongo/schema.py
:
# flask_graphene_mongo/schema.py
import graphene
from graphene.relay import Node
from graphene_mongo import MongoengineConnectionField, MongoengineObjectType
from models import Department as DepartmentModel
from models import Employee as EmployeeModel
from models import Role as RoleModel
class Department(MongoengineObjectType):
class Meta:
model = DepartmentModel
interfaces = (Node,)
class Role(MongoengineObjectType):
class Meta:
model = RoleModel
interfaces = (Node,)
class Employee(MongoengineObjectType):
class Meta:
model = EmployeeModel
interfaces = (Node,)
class Query(graphene.ObjectType):
node = Node.Field()
all_employees = MongoengineConnectionField(Employee)
all_role = MongoengineConnectionField(Role)
role = graphene.Field(Role)
schema = graphene.Schema(query=Query, types=[Department, Employee, Role])
Creating some data
I put some data to make this demo can run directly:
# flask_graphene_mongo/database.py
from mongoengine import connect
from models import Department, Employee, Role
# You can connect to a real mongo server instance by your own.
connect('graphene-mongo-example', host='mongomock://localhost', alias='default')
def init_db():
# Create the fixtures
engineering = Department(name='Engineering')
engineering.save()
hr = Department(name='Human Resources')
hr.save()
manager = Role(name='manager')
manager.save()
engineer = Role(name='engineer')
engineer.save()
peter = Employee(name='Peter', department=engineering, role=engineer)
peter.save()
roy = Employee(name='Roy', department=engineering, role=engineer)
roy.save()
tracy = Employee(name='Tracy', department=hr, role=manager)
tracy.save()
Creating GraphQL and GraphiQL views in Flask
There is only one URL from which GraphQL is accessed, and we take the advantage of Flask-GraphQL
to generate the GraphQL interface for easily accessed by a browser:
from database import init_db
from flask import Flask
from flask_graphql import GraphQLView
from schema import schema
app = Flask(__name__)
app.debug = True
default_query = '''
{
allEmployees {
edges {
node {
id,
name,
department {
id,
name
},
role {
id,
name
}
}
}
}
}'''.strip()
app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql', schema=schema, graphiql=True))
if __name__ == '__main__':
init_db()
app.run()
Testing
We are ready to launch the server!
$ python app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Then go to http://localhost:5000/graphql to test your first query. The full example can get from this github repository.
Happy Coding :)
Til next time,
abawchen
at 18:00