全栈工程师开发手册 (作者:栾鹏)
数据架构师全解
当我们使用flask构建一个简单应用时,我们通常会像下面这样构建该应用:
from flask import Flask
import json
app = Flask(__name__)
@app.route("/")
def homepage():
return "Welcome!"
@app.route("/get_response", methods=['GET'])
def response():
return json.dumps({
"name": "Siri",
"said":"Hello world!"
})
if __name__ == '__main__':
app.run(host='127.0.0.1',port='8080')
以上,我们构建了一个简单的web应用,当打开127.0.0.1/8080时,我们得到以下结果:
当我们打开网址127.0.0.1/8080/get_response时,我们得到以下结果:
那么,既然我们已经会用flask构建应用了,为什么还需要学习flask-graphql这个python库呢?在知道答案之前,我们先来了解以下graphql。
以下是graphql的官方站:https://graphql.cn/
通过官方的实例,我们可以知道,graphql的主要功能,是进行API测试,与其他的API测试工具相比,graphql有几个优势:
1、graphql可以通过图形化界面的方式,在同一个界面上交互式地进行API数据测试,所解析的数据结构清晰,避免手动解析再排版检查;
2、graphql能够没有冗余地获取数据,不会返回前端页面,避免了后台测试时获取到冗余内容;
3、典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 可以通过一次请求就获取你应用所需的所有数据,只需要把多个URL的功能封装在一个Query内;
4、GraphQL 使用类型来保证应用只请求可能的数据,还提供了清晰的辅助性错误信息。
因此,graphql能够让我们在进行API测试时更直观,稳定,快速。那么我们如何在flask应用中使用graphql,来同时进行应用构建和API测试呢?下面给出一个使用flask-graphql的示例。使用flask构建的基础应用和前面的应用是一样的,不同之处在于,这次我们加上了graphql测试的功能,具体涉及到两个包:flask_graphql及graphene。
flask-graphql:
使用flask-graphql,最主要就是三个工作:1)定义数据格式,即schema;2)定义查询;3)添加graphql的entrypoint到flask应用。
Graphene:
Graphene是一个提供使用代码优先方法在Python中实现GraphQL API的工具的库。将Graphene的代码优先方法与Schema-first方法(如Apollo Server(JavaScript)或Ariadne(Python))构建GraphQL API进行比较。我们没有编写GraphQL架构定义语言(SDL),而是编写Python代码来描述服务器提供的数据。Graphene具有最流行的Web框架和ORM的集成功能。Graphene生成的方案完全符合GraphQL规范,并提供了用于构建符合中继标准的API的工具和模式。
也就是说,我们通过graphene定义graphql所能接受的数据结构,构建起schema和query,再将query添加到graphql视图中,将视图函数的entrypoint添加到flask应用,这样当我们打开/graphql这个url时,就能进入到接口测试页面,进行数据测试了。测试时,输入的测试数据,要按照graphene定义的数据格式来输入,如果发生了错误,graphql的测试界面会有错误提示的。
from flask import Flask
from flask_graphql import GraphQLView
import json
from graphene import ObjectType,String,Schema
app = Flask(__name__)
# flask原生使用方法
@app.route("/")
def homepage():
return "Welcome!"
# flask原生使用方法
@app.route("/get_response", methods=['GET'])
def response():
return json.dumps({
"name": "Siri",
"said":"Hello world!"
})
# flask_graphql使用方法
class Query(ObjectType):
# this defines a Field `welcome` in our Schema with a single Argument `name`
# 等价于定义flask中的路由
welcome = String(name=String(default_value="stranger"))
goodbye = String()
# our Resolver method takes the GraphQL context (root, info) as well as
# Argument (name) for the Field and returns data for the query Response
# 绑定路由对应的试图函数,如果有要新增的试图函数,前缀必须是resolve_,并且必须带root,info入参
def resolve_welcome(root, info, name):
return 'Welcome %s!' % (name)
def resolve_goodbye(root, info):
return 'See ya!'
schema = Schema(query=Query, auto_camelcase=False)
app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql',
schema=schema, graphiql=True))
if __name__ == '__main__':
app.run(host='127.0.0.1',port='8080')
测试一下graphql,不传入name参数,则默认传入的name是stranger
在测试时传入参数name=”siri”,结果更新了
到这里就介绍完了,enjoy~