REST 是現代領域 Web API 的一個極其強大的解決方案。它提供了廣泛的優勢,可以幫助任何服務變得更高效、更快迭代、更穩定。
Python 是一種強大的高級語言,可以在廣泛的系統和設備類別中解鎖高級功能。它是人類可讀的、高效的并且被廣泛采用。
這兩種技術結合起來,可以在 API 領域提供令人難以置信的產品。在本指南中,我們將討論什么是 REST、如何打造真正的 RESTful 以及 Python 如何支持這項工作。我們將研究一些最佳實踐。
REST(即表述性狀態傳輸)是系統通信的范例。這一概念是讓系統通過一種無狀態模式相互通信,這種模式利用資源狀態的表示而不是資源本身。本質上,每次交互都是利用資源請求者和資源持有者之間的特定關系進行有狀態表示,這允許跨各種用例進行無縫交互。
REST 作為一個概念首次在Roy Fielding 的一篇現已著名的論文中被分享。在這篇論文中,菲爾丁定義了一種基于表征狀態轉移的新通信方式。雖然在實踐中有多種可選屬性可以使某些東西變得“RESTful”,但 REST 的核心本質最好定義如下:
充分了解 REST 后,我們來看看 Python。 Python 是一種編程語言,于 1991 年首次發布,作為 ABC 的后繼語言。該語言的目的是人類可讀且高效,重點是垃圾收集、動態類型和多范式支持。它將各種庫打包在一起,以實現大量的功能和用途,因此,它是 Web API 的一個非常受歡迎的選擇。
Python 很受歡迎,因為它很容易上手。它使用簡單的語法,具有很高的可讀性,利用正常的人類語音和空格使事情變得更清晰、更容易理解。它將許多復雜的底層功能抽象為簡單的結構,使您能夠以低摩擦快速上手。
值得注意的是,Python 在各種系統和環境中具有高度的跨平臺支持。該社區異常強大,這意味著在那些沒有本機 Python 支持的環境中,可能存在允許此功能和集成的社區擴展或系統。
出于本文的目的,我們將使用 Python 和 Flask。有多種優秀的 Python API 開發工具,但我們使用 Flask,因為它不需要任何工具或庫即可開始構建 Web API。 Flask 確實有擴展來添加額外的功能,但對于這個 API,我們將直接使用開箱即用的工具集。
首先,本教程假設您已經安裝了 Python。如果不這樣做,請導航到 Python 網頁并通過適合您的環境“可緩存”的方法進行安裝。
安裝Python后,必須先安裝Flask。為此,請發出以下命令:
pip install flask
這將從 Python 包索引安裝 Flask。
接下來,您需要為 Python API 創建一個目錄。我們將此目錄稱為“Moesif_tutorial:
mkdir moesif_tutorial && cd moesif_tutorial
此代碼將創建目錄 (mkdir) 并將工作目錄 (cd) 更改為新創建的位置。從這里,您需要創建新的項目文件。我們將其稱為“tutorial_app”。
touch tutorial_app.py
通過“觸摸”該文件,我們正在創建構建文件并準備好保存我們的項目。 “touch”將創建該文件,但我們需要啟動一個虛擬環境來處理它。為此,請使用以下命令:
python3 -m venv <venv>/bin/activate
此命令將取決于您的環境目錄 – 有關如何正確啟動此目錄的更多信息,請參閱Python 文檔。
創建環境后,我們將制作 API。這個 API 非常簡單 – 它將包含有關三個 Python 框架的詳細信息,并允許用戶檢索有關這些框架的信息。
要開始構建 API,我們將直接編輯tutorial_app.py。在該文件中,添加以下代碼:
from flask import Flask
app = Flask(__name__)
它的作用是實例化 Flask 類,實際上是“創建”應用程序。有了這個,我們接下來創建了一個具有名稱值的類實例,我們將在其中將 Flask 指向各種文件和元素。
這是 Python 應用程序的最基本版本 – 但為了使其成為 RESTful 版本,我們需要查詢端點,在我們的例子中,這意味著我們需要一些數據供其引用。由于我們沒有連接數據庫,因此我們可以直接將此數據存儲為數據存儲。在Python中,數據存儲是我們可以存儲在應用程序本身中的一段任意代碼,這使我們能夠在沒有數據庫或外部數據存儲解決方案的情況下托管數據。
為此,我們可以將數據存儲附加到我們的文件中:
from flask import Flask
app = Flask(__name__)
in_memory_datastore = {
"Flask" : {"name": "Flask", "created": 2010, "parent": "Python"},
"Django" : {"name": "Django", "created": 2005, "parent": "Python"},
"Bottle" : {"name": "Bottle", "created": 2009, "parent": "Python"},
"Tornado" : {"name": "Tornado", "created": 2010, "parent": "Python"},
}
現在您已經有了 API 的骨架——它有一個實例化的應用程序和一個資源。接下來,我們需要創建可以查詢的端點。為此,我們將使用 HTTP 動詞 GET 從tutorial_app.py 檢索數據:
@app.get('/frameworks')
def list_frameworks():
return {"frameworks":list(in_memory_datastore.values())}
這里有幾件事要提一下。首先,“/frameworks”區域定義了我們的端點。使用 GET HTTP 謂詞向該端點發出的請求將觸發此功能。對于其他端點,您只需更改此名稱并生成新端點即可。其次,@app.get 是另一種方法的簡寫。一些 Python 開發人員可能更熟悉“@app.route”——在這種情況下,app.get 和 app.route 是同一個,只是構建略有不同。
我們的方法如下所示:
@app.get('/frameworks')
另一種寫法如下:
@app.route('/frameworks', methods=["GET"])
請注意,這兩段代碼執行相同的操作 – 我們的版本只是更短?;氐酱a中所寫的:
@app.get('/frameworks')
def list_frameworks():
return {"frameworks":list(in_memory_datastore.values())}
代碼的其余部分定義了一個帶有“frameworks”標簽的 JSON 對象,并將其指向我們數據存儲中的值。這將允許我們訪問 /frameworks 端點并查看所有資源的列表。為此,您可以導航至:
http://127.0.0.1:5000/frameworks
到目前為止,我們已經有了一個 API,可以讓我們檢索數據列表。我們需要做的是開始添加額外的 CRUD 功能。例如,我們可以利用 PUT 創建一個更新函數。為此,我們可以更新代碼以添加 POST 動詞,從而在數據存儲中創建新條目。首先,我們需要創建創建函數:
def create_framework(new_framework):
framework_name = new_framework['name']
in_memory_datastore[framework_name] = new_framework
return new_framework
這定義了一種將框架輸入系統的新方法。接下來,我們需要添加一個路由方法來支持 CLI 命令與端點交互:
@app.route('/frameworks'’, methods=['GET', 'POST'])
def frameworks_route():
if request.method == 'GET':
return list_frameworks()
elif request.method == "POST":
return create_framework(request.get_json(force=True))
可以對 CRUD 功能所需的所有路由重復此操作。
現在您已經有了提供基本功能的 API 服務,您將需要開始添加一些系統以真正使其成為 RESTful。第一步是利用有效的 HATEOAS 上下文系統。
目前市場上有多種選擇。 JSON-LD是一個很好的解決方案,它允許您提供鏈接數據作為資源的一部分。
在我們的實例中,這可能是這樣的:
{
"@context": "https://example.com/frameworks.jsonld",
"@id": "https://example.com/frameworks/Flask",
"relatedName": "Flask-RESTPlus",
"relatedDocs": "https://flask-restplus.readthedocs.io/",
}
這也是您可能需要開始考慮用于緩存、優化等的額外框架的一點。一旦您擁有了一個穩定的 API 可供使用,您就可以開始添加額外的安全和穩定的功能,使您的應用程序真正實現 RESTful。
確保您使用基于最小權限原則的身份驗證和授權來部署服務。盡可能鎖定對資源的訪問。確保你的上下文參考是有效的,并且它們是值得的——超媒體很棒,但暴露任何東西并不是對一個更加封閉、非上下文世界的正確反應。確保您提供的有用數據不會被用來對付您,并確保以安全的方式提供數據。
請記住,RESTful API 主要是面向資源的。資源應該有一個具有特定功能的HTTP 動詞,并且應該是冪等的(例如,每次調用時響應的類型都是相同的,即使內容不同)。確保您充分鏈接到上下文信息并向客戶端提供緩存。確保您與本文開頭的 REST 考慮因素保持一致。
RESTful 設計并不難做,但往往很難做得正確。通過一些前瞻性的思考和規劃,您可以使用 Python 啟動極其強大的 RESTful API。即使只是這篇文章中的代碼也可以成為下一個大型 API 的核心——它只需要一些想象力和規劃。
原文鏈接:https://www.moesif.com/blog/api-monetization/api-strategy/Creating-Python-APIs/