教你 10 分鐘構建一套 RESTful API 服務( 中 )

image

1. 前言

上一篇文章,介紹了使用 Java + Spring Boot + MyBatis 構建 RESTful API 的詳細步驟;不少小夥伴表示,更願意用 Python 編寫 RESTful API 服務,但願我能寫一下python

本篇將以 Python 開始介紹搭建 RESTful API 的流程 ,使用的技術棧是:Flask + flask-restful + flasggermysql

​2. 安裝依賴

使用 Python 編寫 RESTful API 以前,咱們須要先在虛擬環境內安裝對應的依賴具體包含:sql

  • Flask- 基礎 Web 框架數據庫

  • flask_restful- Flask 的擴展,增長了對快速構建 REST API 的支持json

  • flasgger- flask 支持的 Swagger UI,能夠生成 API 接口文檔flask

# 安裝flask
pip3 install flask

# 安裝flask-restful
pip3 install flask-restful

# 安裝flasgger
# 注意:須要更新setuptools
pip3 install -U setuptools
pip3 install flasgger

# 管理數據庫的依賴
pip3 install flask_script
pip3 install flask_migrate
複製代碼

3. Hello World

首先,咱們使用 Pycharm 建立一個 Flask Web 項目,初始化代碼以下:api

from flask import Flask

app = Flask(__name__)
​

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()
複製代碼

從 flask_restful 文件中導入 Api、Resource 兩個類,使用上面的 app 對象,構建一個 api 對象,接着準備一個列表數據bash

from flask_restful import Api,Resource

app = Flask(__name__)

# 實例化一個 Api 對象,用來建立、管理 RESTful Api
api = Api(app)


# 準備一個列表數據
datas = [{'id': 1, 'name': 'xag', 'age': 18}, {'id': 2, 'name': 'xingag', 'age': 19}]
複製代碼

而後,利用 Flask 中的 CBV 模式,建立一個 Resource 類的子類,用於定義資源路由微信

這裏以 GET / POST 動做爲例,重寫 get、post 方法,並編寫內部邏輯,返回數據便可restful

class UserView(Resource):
    """ 經過繼承 Resource 來實現調用 GET/POST 等動做方法 """
    def get(self):
        """ GET 請求 :return: """
        return {'code': 200, 'msg': 'success', 'data': datas}


    def post(self):
        # 參數數據
        json_data = request.get_json()

        # 追加數據到列表中
        new_id = len(datas)+1
        datas.append({'id':new_id,**json_data})

        # 返回新增的最後一條數據
        return {'code': 200, 'msg': 'ok', 'success': datas[new_id - 1]}
複製代碼

最後,使用 Api 的實例對象,將上面定義的資源,利用路徑,徹底暴露出去

# 暴露接口出去
# 資源路由:UserView
# 路徑:/user
api.add_resource(UserView,'/user')
複製代碼

運行程序後,就能夠拿 Postman 或 cURL 去測試接口了

image

4. 項目實戰

在實際項目開發中,數據結構、層級關係每每要複雜不少,咱們須要對項目進行一次整合,按功能進行封裝,具體步驟以下:

第 1 步,編寫配置文件

新建一個配置文件 config.py,將數據庫( 以 Mysql 爲例 )的鏈接信息,包含:用戶名、密碼、端口號、數據庫名、鏈接驅動和 Swagger 的設置信息追加進去

# config.py
USERNAME = 'root'
PASSWORD = 'root'
HOSTNAME = "127.0.0.1"
PORT = '3306'
DATABASE = 'xag'

DIALECT = 'mysql'
DRIVER = 'pymysql'

# 鏈接數據的URI
DB_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT, DRIVER, USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)

SQLALCHEMY_DATABASE_URI = DB_URI

SQLALCHEMY_TRACK_MODIFICATIONS = True

SWAGGER_TITLE = "API"
SWAGGER_DESC = "API接口"
# 地址,必須帶上端口號
SWAGGER_HOST = "localhost:5000"
複製代碼

第 2 步,模型映射數據庫

建立一個模型類 Foo 繼承 SQLAlchemy 對象,使用  tablename 指定生成數據表的名稱、而後新增幾個經常使用字段

# models.py
from exts import db

class Foo(db.Model):
    """ 模型,將映射到數據庫表中 """
    __tablename__ = 'foo'

    # 主鍵ID
    id = db.Column(db.INTEGER, primary_key=True, autoincrement=True)
    # 名字
    name = db.Column(db.String(100), nullable=False)
    # 年齡
    age = db.Column(db.INTEGER)
複製代碼

接着,建立 manage.py 文件

顯式導入上面建立的 Foo 類,使用 flask_migrate 中的 Migrate 綁定 App 和數據庫,利用 flask_script 中的 Manager 實例去添加一個腳本命令

# manager.py
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager

from exts import db
from api_app import app
from models import Foo

manager = Manager(app)
migrate=Migrate(app, db)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()
複製代碼

須要注意的是,Foo 模型必須顯式導入,不然無法映射到數據庫中

最後,經過下面 3 個腳本命令,將模型映射到數據庫中

除了第一次須要生成遷移腳本外,後面映射數據庫,只須要執行後面兩個命令便可

# 初始化遷移文件
python3 manager.py db init

# 映射到文件
python3 manager.py db migrate

# 映射到數據庫
python3 manager.py db upgrade
複製代碼

打開 Navicat For Mysql,便可以看到剛剛映射過來的數據表及遷移表

image

第 3 步,建立資源路由

下面以建立列表查詢( GET )、單條記錄的查詢( GET )、更新( PUT )、新增( POST )、刪除( DELETE )爲例

flask_restful 中的 marshal_with 類能夠做爲裝飾器,定義到動做函數上,指定要返回的字段;而後使用 SQLAlchemy ORM 操做數據庫,將數據直接進行返回

好比:返回獲取數據列表

# api_foo.py
from flask_restful import Resource, fields, marshal_with, request

class FooListApi(Resource):
    # 定義要返回的字段
    resource_fields = {
        'id': fields.Integer,
        'name': fields.String,
        'age': fields.String
    }

    # 裝飾器,定義返回數據
    @marshal_with(resource_fields)
    def get(self):
        """ 返回全部記錄 :return: """
        # 查詢數據庫
        foos = db.session.query(Foo).all()
        return foos
複製代碼

對於新增一個對象( POST 動做)

# api_foo.py
class FooApi(Resource):
    def post(self):
        """ 建立一條記錄 :return: """
        # 參數
        params = request.get_json()
        name = params.get("name")
        age = params.get("age")
        # 構建一個模型
        foo = Foo(name=name, age=age)

        # 加入到數據庫
        db.session.add(foo)
        db.session.commit()

        return success("新增一條記錄成功!")
複製代碼

第 4 步,返回數據統一化

爲了保證返回的數據結構一致,能夠將返回碼、返回信息及數據進行一次封裝,經過jsonify進行格式化返回

# restful_utils.py
from flask import jsonify

class HttpCode(object):
    ok = 200
    un_auth_error = 401
    params_error = 400
    server_error = 500

def restful_result(code, message, data):
    return jsonify({"code": code, "message": message, "data": data or {}})

def success(message="", data=None):
    """ 正確返回 :return: """
    return restful_result(code=HttpCode.ok, message=message, data=data)
複製代碼

第 5 步,暴露接口

使用 flask_restful 中的 Api 實例對象,將上面定義的資源路由暴露出去

#api_app.py
from flask_restful import Api

api = Api(app)

# 某一條記錄
api.add_resource(FooApi, '/api/v1/foo','/api/v1/foo/<int:id>')

# 全部記錄
api.add_resource(FooListApi, '/api/v1/foos')
複製代碼

第 6 步,自動生成接口文檔

Flask 中一樣能夠利用 Swagger 自動生成接口幫助文檔

首先,從配置文件 config.py 中讀取配置,實例化 Swagger 對象

#api_app.py
from flasgger import Swagger

# API可視化管理
swagger_config = Swagger.DEFAULT_CONFIG

# 標題
swagger_config['title'] = config.SWAGGER_TITLE   
# 描述信息
swagger_config['description'] = config.SWAGGER_DESC
# Host 
swagger_config['host'] = config.SWAGGER_HOST    

# 實例化
swagger = Swagger(app,config=swagger_config)
複製代碼

而後,在資源路由的動做內新增 swagger 註釋內容,包含:請求方式、參數、響應數據、描述信息等

具體能夠參考:editor.swagger.io/#/

以獲取某一條數據爲例:

class FooApi(Resource):

    resource_fields = {
        'id': fields.Integer,
        'name': fields.String,
        'age': fields.String
    }

    @marshal_with(resource_fields)
    def get(self, id):
        """獲取用戶信息 --- schemes: - http parameters: - name: id in: path type: integer required: true default: 1 description: 用戶id responses: 200: description: 返回用戶信息 examples: { "id": 1, "name": "xag", "age":"18" } """
        foo = db.session.query(Foo).get(id)
        return foo
複製代碼

最後,運行項目,訪問下面的連接,便可以看到定義好的 RESTful API 服務了

http://localhost:5000/apidocs/#/

image

5. 最後

上面就是經過 Flask + flask_restful 單表實現 RESTful API 完整的流程了,項目中涉及的多表,只須要更改數據庫的邏輯操做就能夠了

我已經將文中所有源碼上傳到公衆號後臺,關注公衆號「 AirPython 」後回覆「 rest2 」便可得到所有源碼

若是你以爲文章還不錯,請你們點贊分享下。你的確定是我最大的鼓勵和支持。

推薦閱讀 教你 10 分鐘構建一套 RESTful API 服務( 上 )

推薦幾款優質 Chrome 摸魚插件,帶你暢快划水

用 Python 分析微信羣聊記錄,是怎樣一種體驗?

相關文章
相關標籤/搜索