Python Tech

GraphQL+Django提供基本API

GraphQL是Facebook去年开源的一套数据查询语言,对于大型系统,GraphQL提供一种灵活的访问通用数据的方式。当时正好有一个项目,需要前端调用后台的数据(Express+Postgresql)实现图表展示,我就从Postgresql里把数据导出成JSON文件(后来用Promise改成直接查询数据库),前端直接用GraphQL获取自己需要的数据,后台就省掉了制作API、写SQL的工作,运行至今基本稳定。

当时GraphQL还没有针对Django的modules,前两个月发布了graphene-django,做的事情不多,但可以搭配其他插件例如django-filters来实现更丰富的查询。GraphQL的优势在于查询语句的通用性和易读性,相比REST架构来说时间较短还不够成熟,如果是复杂需求后台的开发量仍然不小,现阶段在生产环境用Django做一个API服务还是rest framework等成熟的方案会更好。本文实现一个针对Django自带的User Model的简单API。

环境:

Django 1.10.4
graphene-django-1.2.0

Setup

安装graphene-django,如果是新建Django项目,创建后执行migrate创建表,再创建admin用户:

编辑settings.py,将graphene-django加入INSTALLED_APPS:

再编辑urls.py,导入GraphQLView,加上graphql的设置:

执行runserver,这时候访问/graphql会报错,显示没有提供schema。

Schema

在dmyz目录中新建schema.py文件,目录结构如下:

编辑schema.py文件,导入DjangoObjectType和graphene,处理django自带的User Model,代码如下:

最后编辑settings.py,加上配置:

现在重新访问/graphql,可以看到自带的前端界面,在左上方文本框中输入:

运行(点击上方▶️按钮)返回admin用户的username和email。右侧的Docs会显示Query信息,下划线命名也会自动转成驼峰命名。

查询语句完整格式是 query 名称{},上面的查询语句省掉了query,因为GraphQL默认会作为query语句执行,如果是mutation就需要加上了。关于查询语句可以参考官方文档:http://graphql.org/learn/queries/

Schema & Type & Field

无论后台是Python还是Nodejs,查询语句都是一样的,但不同语言对Schema的实现方式不同。Schema定义数据的呈现结构,包含各种Types,其中Query和Mutation是两个特殊的Type,Type通过Fields指定返回的数据字段。以之前的代码为例,代码中定义了Type(Query)和Fields(users),指定resolve来处理数据。

Filter

先增加一个测试用户,在后台添加或者执行:

执行之前的查询语句会返回两条记录。修改schema.py的修改Query:

执行新的查询语句,指定id:

新的查询语句用逗号分隔字段,增加了名字,执行后只返回id=2的用户:

Mutation

先继承graphene.Mutation创建一个类,定义输入的参数,再处理成ObjectType传递给Schema:

查询语句必须申明是mutation,传入Input中定义的字段,还要定义返回的内容:

执行后返回数据:

Afterword

如前文提到的,GraphQL不如REST架构历史悠久,但也有自己的独特优势:一是返回结果跟查询语句相关,对于返回的结构能有清晰认识,REST请求时并不知道会返回JSON还是XML,也不知道会返回那些字段;二是数据变动更灵活,不需要像以前一样v1/v2…vn来标明版本,采用单一查询入口更容易扩展。GraphQL是React生态的一部分(还有Relay),支持上目前来看是可以保证的。

Leave a Reply

Your email address will not be published. Required fields are marked *