开发目标: 实现一个 Web 服务,这个服务使用 Flask 框架,API 使用 Graphql。
这个 Web 服务很简单,它提供书籍的查询与添加功能(修改和删除与添加类似,故不赘述)。通过这个例子,希望可以帮助大家了解以下两点
- 如何使用 Graphql 进行API设计
- 如何进行 Graphql 的后端开发
Install
首先,安装一下下面这几个模块。
# python 3.6 以上
pip install graphene
pip install Flask-GraphQL
API Design
下面,开始设计 API,也就是先写一份我们的 Graphql Schema(Schema Define Language,SDL)。
创建文件 books.graphql
(如果 IDE 是 vscode ,可装 graphql 插件)
type Book {
id: ID!
name: String!
}
type Query {
books: [Book!]!
}
type Mutation {
add(name: String!): Book!
}
我们定义了三个东西:
- Book,书,相当于一个类,可以理解为资源
- Query,查询接口定义,我们只定义了一个查询接口
- Mutation,数据修改接口定义,我们定义了一个接口,增
每个GraphQL schema都有三种特殊的根类型,称为查询(Query),修改(Mutation)和订阅(Subscription)。这些根类型的字段定义了API接受的操作。我们使用了 查询和修改。
Web Service
下面,我们创建服务,创建文件 server.py
,根据文档编写下面的代码(请注意,代码不是根据 API 文档自动生成的):
from flask import Flask
from flask_graphql import GraphQLView
import graphene
app = Flask(__name__)
books = []
class Book(graphene.ObjectType):
""" Book
"""
id = graphene.ID(description="book ID")
name = graphene.String(description="book name")
create = lambda id, name: Book(id=id, name=name)
books.append(create(1, "The First Book"))
class Query(graphene.ObjectType):
""" query your books
"""
books = graphene.List(Book, description="list books")
version = graphene.String(description="version")
def resolve_books(self, info):
return books
def resolve_version(self, info):
return "v0.1"
# Mutation
class AddBook(graphene.Mutation):
""" Add books
"""
Output = Book
class Arguments:
name = graphene.String()
def mutate(self, info, name):
book = create(len(books) + 1, name)
books.append(book)
return book
class Mutation(graphene.ObjectType):
""" mutate books
"""
add = AddBook.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
app.add_url_rule('/graphql', view_func=GraphQLView.as_view('graphql',
schema=schema, graphiql=True))
app.run(port=4901, debug=True)
代码分析:
books
是一个全局变量,用于保存所有的 books,可把它当做数据库,很多示例都有数据库,为了保持简单,最方便运行,所以,我只用了这么一个变量Query
是比较简单的,语义很清晰,和 API 文档不同的是,在Query
中增加了一个version
,这是为了简单对比一个restful
,如果是restful
的话,我们要获取books
和version
这两个资源,需要两个API
,但graphql
只需要一个Mutation
分为两步,第一步定义一个Mutate
,里面必须要有mutate
方法,第二个创建Mutation
,用于组合所有的Mutate
。/graphql
是给我们提供一个可视化的 API 展示,类似 Swagger,当然,生产环境就不要加这个了,加在开发、测试环境即可
运行代码:
python server.py
访问: http://127.0.0.1:4901/graphql ,可看到类似 Github V4 API 的 Explorer 界面。
点击最右侧的 Docs
,可看到我们的 API 设计。
Query All Books
在最左侧的框中输入:
query {
books {
name
id
}
version
}
然后,点击那个类似 “播放”(运行) 的按钮,即可在中间的框中,看到输出。
Add a Book
下面,输入:
mutation {
add(name: "The second Book") {
id
}
}
运行一下,即可添加 Book。可以再运行一下上面的 query,看一下当前所有书籍。
上面是 Web 界面,我们也可以使用 curl 做测试:
curl http://127.0.0.1:4901/graphql\?query\=query%20%7Bbooks%20%7Bid%20name%20%7D%20version%7D
建议大家可以自己实现一下 removeBook
和 updateBook
之类的方法,加深理解。