看到标题上的 REST 四个英文字母,不知道有没有令你想起了什麽?
对,就是 RESTful API 的那个 REST(Representational State Transfer,表现层状态转换),所以这个插件就是可以让你轻松的产生 RESTful 型态的 API(对,这篇讲得基本上都是关於 API 的东西)。
开始介绍它之前,我想先来说一下它的身世(为什麽我要说呢,因为我想提到另一个东西),刚开始是有一个叫做 Flask-RESTful 的插件。因为这个插件就只是普通的能够产生 RESTful 的 API,虽然没有什麽不好,但是如果要交接给其他人;或是要写技术文件时,第一个念头通常是 Word。虽然没有不好,不过时间久了在维护时会常常会遇到没有更新或是参数错误发生,这时候如果有一个东西,可以在更新程序的时候,自动生成相应的描述 API 的文件那就好了。
所以产生了後来的 Flask-RESTPlus ,这个是插件是以 Flask-RESTful 为基础,增加了自动生成 Swagger 这种可以描述 API 的东西(我扯了这麽多,就是想讲 Swagger 而已)。不过後来因为看似没有被积极维护的原因,所以有些热心的人就分支出了 Flask-RESTX 的版本。这就是它的身世,所以 Flask-RESTful 跟 Flask-RESTPlus 用法是大致相同的(目前是这样啦,之後会不会大改不知道)。
那 Swagger 是什麽呢?根据维基百科的说明:
Swagger是一种接口描述语言。
好了,现在讲完了 Flask-RESTX 以及提到了 Swagger ,那就来看看如何使用吧。
要使用之前,当然是先安装啦。安装方式依然是透过熟悉的 pip 安装啦,然後依然开一个新的专案。
$ pipenv install flask-restx
然後改完後的架构长这样:
ithome
├── apis
│ ├── __init__.py # 空的
│ └── api.py
├── base
│ └── __init__.py # 初始化
├── db # (假的)资料库
│ └── __init__.py # 资料库连线以及操作
├── app.py
├── config.py
├── Pipfile
└── Pipfile.lock
首先先来看一下资料库吧(因为我前面没有讲到资料库,以及我懒,所以我用已存在的 Redis 来假装成一个资料库)。
db/__init__.py
from redis import Redis
# 使用 Redis 假装资料库,并且使用 Redis 的 Hash 储存
# name 相当於资料表,key 相当於主键(ID),value 相当於其他资料(帐号、密码)
# 我只写了有用到的几个 function 而已,其他要用自己加
# 实际上线的服务不要这样玩,还有密码不要用明文存。
class Database:
redis_client = None
@classmethod
def initial(self):
self.redis_client = Redis(host='localhost', port=6379, db=2)
@classmethod
def insert(self, name, key, value):
self.redis_client.hsetnx(name, key, value)
@classmethod
def length(self, name):
return self.redis_client.hlen(name)
然後我们从程序入口开始看起。
app.py
from base import app
if __name__ == "__main__":
app.run()
为什麽只有一个路由?别急,我们开始往回找,接着看 base 做了什麽。
base/__init__.py
from flask import Flask
from flask_restx import Api
from apis.account.api import api as account_ns
import config
from db import Database
app = Flask(__name__, instance_relative_config=True)
app.config.from_object(config.DevelopmentConfig)
# 设定一个 API 核心(很烂,看不懂对吧,但我已经用尽我毕生的中文功力去形容了,将就一下吧)
# 第一个参数必须为 Flask 实体或是 Blueprint
# doc 为 Swagger 的路由位置
api = Api(app, version='0.0.1',
title='Flask-RESTX and Swagger test', doc='/api/doc')
# 加入名称空间(跟上面同样烂)
api.add_namespace(account_ns)
# 初始化资料库
Database.initial()
是不是突然多了很多东西,好像都看不太懂对吧,没关系,我们慢慢往回看。db 的看过了,那就接着来看一下有关 api 的东西(这边考量到长度的关系,所以只做了一个注册的 API)。
apis/api.py
from flask_restx import Namespace, fields, Resource
import ast
from db import Database as db
# 新增一个叫 account 的名称空间
api = Namespace("account", description="帐号管理")
# ---------- 输入输出的格式 ----------
base_output_payload = api.model('基本输出', {
'status': fields.String(required=True, default=0),
'message': fields.String(required=True, default="")
})
account_register_input_payload = api.model('注册帐号input', {
'email': fields.String(required=True, example="[email protected]"),
'password': fields.String(required=True, example="test")
})
account_register_output_payload = api.clone('注册帐号output', base_output_payload)
# ---------- 路由以及功能 ----------
@api.route('/register')
class register(Resource):
@api.expect(account_register_input_payload)
@api.marshal_with(account_register_output_payload)
def post(self):
data = api.payload
try:
nums = str(db.length('users'))
data = str({'email': data['email'], 'password': data['password']})
db.insert('users', nums, data)
except Exception:
message = {'status': 1, 'message': 'error'}
else:
message = {'status': 0, 'message': ''}
finally:
return message
那麽程序的部分大概就这样,接着我们来到浏览器看一下效果。
输入 http://localhost:5000/api/doc
看看(因为有用到 Redis ,所以记得先启动 redis-server 喔),如果都没问题的话,应该会像这样。
接着点一下 Try it out
再点下方的 Execute
看看,如果都正常的话,在更下方的 Response
-> Server response
里面的 Response body
应该会出现像这样的结果。
Flask-RESTful vs Flask-RESTplus
那麽就大概这样,Flask-RESTX 是开发 RESTful API 很好用的插件;Swagger 在测试 API 时也很方便,能够当成技术文件的同时,也避免了没有即时更新的问题(话说我本来想偷懒不装资料库的,但我怎麽好像反而花了更多功夫呢?)。
大家掰~掰~
<<: D31 - 「来互相伤害啊!」:无聊我要见到血流成河
前言 这篇文章想学习的主题是常见的资料分析函数 前一篇学到了利用groupby.() 搭配聚合函数进...
前一篇的裁剪计划使用Excel设计, 现已将其系统化, 由系统安排裁剪计划并开立开裁通知单 不习惯看...
前言 在上一章节中,讲述了Linux process之基本原理与机制,以及控制jobs工作的方法,并...
今天的内容 一、图文资讯元件 二、ICON: Webfont & SVG 三、通知讯息元件 ...
昨天介绍了 before 之後今天就可以直接来看 let 搂! let、let! let =>...