資源 Resource 的擺放
在使用Flask-RESTful的Resource類簡化API開發(fā)步驟時(shí)泥兰,所有的資源都可以通過繼承Resource類來構(gòu)建一個(gè)單獨(dú)的class,
并將所有與此資源相關(guān)的CRUD操作作為methods添加到對(duì)應(yīng)的class下苟穆,使得整個(gè)程序結(jié)構(gòu)更加清晰明了。
這種情況下峻呛,各資源之間互不影響踊餐,可以專門建立一個(gè)名為resources的文件夾,并將各資源class單獨(dú)建立文件:
./resources
| --- __init__.py
|--- item.py
|--- user.py
注意在一些較舊的python版本中需要在文件夾中添加init.py來告訴python可以將其視為package闲坎。
更清晰的資源操作方法
使用各資源class下的get()
方法來對(duì)應(yīng)GET嘗試獲取資源。
最簡單的情況下茬斧,只要根據(jù)發(fā)來的請求直接提供對(duì)應(yīng)的信息即可腰懂。
比如,請求中包含了用戶姓名项秉,則返回姓名對(duì)應(yīng)的用戶信息:
# user.py
class User(Resource):
def get(self, name):
{% 根據(jù)提供的name從數(shù)據(jù)庫中找到對(duì)應(yīng)user的邏輯 %}
return {'user': user}, 200 if user is not None else 404
而這段冗長的由name找到數(shù)據(jù)庫中user的邏輯可以提取出來單獨(dú)作為一個(gè)method使代碼更優(yōu)美:
# user.py
class User(Resource):
def get(self, name):
user = self.find_by_name(name)
return {'user': user}, 200 if user is not None else 404
@classmethod
def find_by_name(cls, name):
{% 根據(jù)提供的name從數(shù)據(jù)庫中找到對(duì)應(yīng)user的邏輯 %}
return user
這樣有了單獨(dú)的find_by_name
后绣溜,get
只要直接調(diào)用它即可。
新 Method 到新 Class
將與底層數(shù)據(jù)庫的交互邏輯轉(zhuǎn)移到新的method中去可以大幅提高代碼的可讀性娄蔼。
在此基礎(chǔ)上我們還可以更進(jìn)一步怖喻,將所有類似的邏輯從原資源中剝離出來,構(gòu)建一個(gè)新class:
# user.py
class UserModel():
@classmethod
def find_by_name(cls, name):
{% 根據(jù)提供的name從數(shù)據(jù)庫中找到對(duì)應(yīng)user的邏輯 %}
return user
class User(Resource):
def get(self, name):
# Call the find_by_name() method from class UserModel
user = UserModel.find_by_name(name)
return {'user': user}, 200 if user is not None else 404
資源與模型
到目前為止岁诉,所有資源class中僅剩直接與API調(diào)用者直接交互的方法锚沸,get()/post()/put() ...
其余輔助CRUD操作的邏輯都被轉(zhuǎn)移到了新的對(duì)應(yīng)class中,由CRUD操作來調(diào)用涕癣,
比如之前用來舉例的 Class User (資源)
對(duì)應(yīng) Class UserModel (輔助)
哗蜈。
為了更好的工程結(jié)構(gòu),可以把所有的輔助class單獨(dú)成文件坠韩,
并集中到專門的models
文件夾下距潘,
#models/user.py
class UserModel:
...
#resources/user.py
from flask_restful import Resource, reqparse
from models.user import UserModel
class User(Resource):
def get(self, name):
# Call the find_by_name() method from class UserModel
user = UserModel.find_by_name(name)
return {'user': user}, 200 if user is not None else 404
文件名盡量便于識(shí)別,可以一眼認(rèn)出與資源class的對(duì)應(yīng)關(guān)系:
./resources
| --- __init__.py
|--- item.py
|--- user.py
./models
| --- __init__.py
|--- item.py
|--- user.py
因此同眯,resources(資源)
文件夾下都是外部API調(diào)用者直接交互的部分绽昼,
即API的外部展示唯鸭,
models(模型)
下則是各種內(nèi)部邏輯(如與數(shù)據(jù)庫的交互)须蜗,
即API的內(nèi)部表示。
整體交互關(guān)系如下:
API caller <--> resources <--> models <--> DataBases
這樣目溉,我們就可以得到一個(gè)較為清晰的代碼結(jié)構(gòu)明肮。