在flask项目中使用graphql

什么是Graphql?

GraphQL是一种API查询语言,是一个对自定义类型系统执行查询的服务端运行环境。一个GraphQL查询是一个被发往服务端的字符串,该查询在服务端被解释和执行后返回JSON数据给客户端。GraphQL最早由Facebook开发,现在已经形成一个强大的社区。

GraphQL可以理解为平行于传统Restful接口的一套并行的查询接口,其特点是简单且强大。

简单示例

废话不多说,我们先来写一个简单的接口来演示一下Graphsql的写法。

首先创建一个传统的flask项目:

1
2
3
4
5
6
7
8
9
10
11
12
13

from flask import Flask

app = Flask(__name__)

@app.route("/getname", methods=['GET'])
def get_name():
return json.dumps({
"name": "张三"
})

if __name__ == '__main__':
app.run(host='0.0.0.0', port=os.environ.get('PORT', 5000))

服务端包含一个简单的REST接口,返回一个json格式的人名。

接下来我们使用graphql的方式来重写这个接口,首先顶一个User的数据模型:

1
2
3
4
class User(ObjectType):

id = Int()
name = String()

这个模型非常简单,只包括一个id和一个姓名name.

然后我们定义一个查询(Query):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Query(ObjectType):

users = List(User, id=Int(required=True))
user = Field(User, id=Int(required=True))

def resolve_user(self, info, id):
"""返回单个实例对象"""
from app import get_name
data = json.loads(get_name())
return User(id=id, name=data["name"])

def resolve_users(self, info, id):
"""返回列表对象"""
from app import get_name
data = json.loads(get_name())
return [User(id=id, name=data["name"])]

这个查询包含两个resolver,一个返回单个的用户,一个返回一组用户。

接下来,我们把这个graphql添加到flask路由中:

1
2
3
view_func = GraphQLView.as_view(
'graphql', schema=Schema(query=Query), graphiql=True)
app.add_url_rule('/graphql', view_func=view_func)

然后我们就可以运行这个项目了:

1
2
if __name__ == '__main__':
app.run(host='0.0.0.0', port=os.environ.get('PORT', 5000))

运行结果如下图:

demo

结合Sqlalchemy

通常我们的项目中都会用到ORM,sqlalchemy是我们常见的ORM框架,Graphql同样支持Sqlalchemy。

首先需要安装第三方框架Graphene-SQLAlchemy:

1
pip install "graphene-sqlalchemy>=2.0"

然后像正常项目那样创建model、数据库对象等操作,这里我们还是以User为例:

1
2
3
4
5
6
7
8
9

from app import db

class User(db.Model):

__tablename__ = 'users'

id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String)

创建完数据库模型,我们就开始写graphql的业务模型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from graphene_sqlalchemy import SQLAlchemyObjectType
from models import User
from graphene import ObjectType,List, Schema

class UserGraph(SQLAlchemyObjectType):

class Meta:
model = User

only_fields = ("name",)



class Query(ObjectType):

users = List(UserGraph)

def resolve_users(self,info):
query = UserGraph.get_query(info)
return query.all()


schema = Schema(query=Query)

很简单,也非常好理解。

最后,启动项目,就可以看到跟前边图片类似的画面里,完整的代码请参考我的github