
如何快速實現REST API集成以優化業務流程
現在,讓我們安裝我們的 Flask 包:
pip install flask
在當前目錄中,我們需要創建一個名為 api
的文件夾。創建這個文件夾的目的是為了容納我們的應用程序的其他子文件夾和文件。
mkdir api && cd api
接下來,創建一個main.py
文件,它將作為我們應用程序的入口點:
touch main.py
打開main.py
,輸入以下代碼:
#main.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return 'Hello World'
if __name__ == '__main__':
app.run()
讓我們來回顧一下我們所做的步驟。首先,我們從 Flask 包中導入了 Flask 類。接著,我們創建了這個類的一個實例,并將其賦值給變量?app
。隨后,我們定義了第一個端點,它對應于應用的根路徑。簡而言之,這個端點是一個視圖函數,當用戶訪問根路徑時會調用它,并返回 “Hello World” 的響應。
讓我們運行應用程序:
python main.py
這將啟動我們的本地服務器,它會在 https://127.0.0.1:5000/
上為我們的 Flask 應用程序提供服務。只需在瀏覽器中輸入這個 URL,您就能在屏幕上看到 “Hello World” 的響應。
看!我們的 Flask 應用程序已經成功啟動并運行了。接下來,我們的任務是確保它能夠正常工作,并進行一些擴展。
為了測試和調用我們的 API 端點,我們將使用 Postman,這是一個專為開發人員設計的用于測試 API 端點的服務。您可以從 Postman 的官方網站下載并安裝它。
現在,讓我們修改 main.py
文件,讓它返回一些實際的數據,而不僅僅是 “Hello World”。
#main.py
from flask import Flask, jsonify
app = Flask(__name__)
songs = [
{
"title": "Rockstar",
"artist": "Dababy",
"genre": "rap",
},
{
"title": "Say So",
"artist": "Doja Cat",
"genre": "Hiphop",
},
{
"title": "Panini",
"artist": "Lil Nas X",
"genre": "Hiphop"
}
]
@app.route('/songs')
def home():
return jsonify(songs)
if __name__ == '__main__':
app.run()
在這里,我們定義了一個包含歌曲列表的數組,每首歌曲都有標題和藝術家名字。接著,我們將根路由 /
更改為 /songs
。這個新的路由會返回我們指定的歌曲數組。為了將列表以 JSON 格式返回,我們使用了 jsonify
函數來轉換列表。現在,當我們訪問 https://127.0.0.1:5000/songs
時,不再看到簡單的 “Hello World” 響應,而是會看到包含藝術家和歌曲標題的列表。
get
回應(大預覽)您可能已經注意到,在每次對代碼進行更改后,都需要手動重新啟動服務器才能看到效果。為了能夠在代碼更改時自動重新加載服務器,我們可以啟用 Flask 的 debug 選項。要實現這一點,只需將 app.run()
調用修改為包含 debug=True
參數,如下所示:
app.run(debug=True)
接下來,讓我們使用post請求向數組中添加一首歌曲。首先,導入request
對象,這樣我們就可以處理來自用戶的傳入請求。稍后我們將在view函數中使用request
對象來獲取JSON格式的用戶輸入。
#main.py
from flask import Flask, jsonify, request
app = Flask(__name__)
songs = [
{
"title": "Rockstar",
"artist": "Dababy",
"genre": "rap",
},
{
"title": "Say So",
"artist": "Doja Cat",
"genre": "Hiphop",
},
{
"title": "Panini",
"artist": "Lil Nas X",
"genre": "Hiphop"
}
]
@app.route('/songs')
def home():
return jsonify(songs)
@app.route('/songs', methods=['POST'])
def add_songs():
song = request.get_json()
songs.append(song)
return jsonify(songs)
if __name__ == '__main__':
app.run(debug=True)
我們的add_songs
view函數接受用戶提交的歌曲,并將其添加到現有的歌曲列表中。
到目前為止,我們都是從 Python 列表中返回數據的,但這只是實驗性的做法,因為在更實際的應用場景中,如果我們重新啟動服務器,之前添加的數據就會丟失,這顯然是不可行的,因此,我們需要一個實時的數據庫來存儲和檢索數據,這就是 Cloud SQL 的用武之地。
根據 Google 官方網站的介紹:
Google Cloud SQL 是一項完全托管的數據庫服務,能夠輕松地在云中設置、維護、管理和操作關系型 MySQL 和 PostgreSQL 數據庫。Cloud SQL 托管在 Google Cloud Platform 上,為在任何位置運行的應用程序提供數據庫基礎架構支持。
這意味著我們可以將數據庫基礎設施的管理完全外包給 Google,同時享受靈活的定價策略。
在 Google Cloud 上,我們可以在 Compute Engine 基礎設施上啟動虛擬機,并在其上安裝 SQL 實例。但這樣做的話,我們就需要負責垂直可擴展性、復制以及許多其他配置工作。而使用 Cloud SQL,我們可以獲得大量開箱即用的配置,從而能夠將更多時間花在編寫代碼上,減少設置和配置的時間。
在我們開始使用 Cloud SQL 之前,需要先完成以下準備工作:
注冊 Google Cloud 后,在左側面板中,滾動到“SQL”選項卡并單擊它。
首先,我們需要選擇一個 SQL 引擎。在本文中,我們將使用 MySQL。
接下來,我們將創建一個 Cloud SQL 實例。默認情況下,實例將在美國創建,并且區域會自動為我們選擇。
在設置過程中,我們需要為實例設置 root 密碼并命名,然后點擊“創建”按鈕。如果想要進一步自定義實例的配置,可以點擊“顯示配置選項”下拉列表。這些設置允許我們調整實例的大小、存儲容量、安全性、可用性、備份等參數。不過,在本文中,我們將使用默認設置來簡化流程。請放心,這些設置在未來是可以更改的。
實例的創建過程可能需要幾分鐘時間。當看到綠色的對勾標記時,就意味著實例已經準備就緒。此時,可以點擊實例的名稱進入詳細信息頁面。
現在,我們的 Cloud SQL 實例已經啟動并運行,接下來我們需要完成以下任務:
導航到 “Database” 選項卡以創建數據庫。
在 “Host name” 部分中,將其設置為允許 “% (any host)”。
要連接到數據庫實例,您可以選擇使用私有 IP 地址或公共 IP 地址。使用私有 IP 地址需要配置 Virtual Private Cloud(VPC)。在本文中,我們選擇使用公共 IP 地址,因為這是默認選項且更為簡便。盡管公共 IP 地址是公開的,但只有那些 IP 地址已被列入白名單的用戶才能訪問數據庫,從而確保了安全性。
要將您的 IP 地址添加到白名單中,請首先在搜索引擎中輸入“my ip”以獲取您的當前 IP 地址。然后,在 Cloud SQL 控制臺中,轉到“連接”選項卡,并選擇“添加網絡”。在出現的窗口中,輸入您剛才獲取的 IP 地址,以便將其添加到允許訪問數據庫的白名單中。
接下來,導航到“概述”面板并使用 Cloud Shell 進行連接。
控制臺中會預先提供用于連接到 Cloud SQL 實例的命令。
您可以選擇使用 root 用戶或之前創建的其他用戶進行連接。以下命令示例展示了如何以用戶 flask-demo
的身份連接到名為 USERNAME
的實例(請將 USERNAME
替換為實際的實例名):
系統會提示您輸入該用戶的密碼以完成連接。
gcloud sql connect flask-demo --user=USERNAME
如果您收到一條錯誤消息,指出您沒有項目 ID,您可以通過運行以下命令來獲取項目的 ID:
gcloud projects list
取上面命令輸出的項目ID,并將其輸入到下面的命令中,將PROJECT_ID
替換為它。
gcloud config set project PROJECT_ID
然后,運行gcloud sql connect
命令,我們將連接。
運行以下命令以查看活動數據庫:
> show databases;
我的數據庫名為db_demo
,我將運行下面的命令來使用db_demo
數據庫。您可能會看到其他一些數據庫,例如information_schema
和performance_schema
。它們用于存儲表Meta數據。
> use db_demo;
接下來,創建一個表,該表鏡像 Flask 應用程序中的列表。在記事本上鍵入以下代碼并將其粘貼到 Cloud Shell 中:
create table songs(
song_id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(255),
artist VARCHAR(255),
genre VARCHAR(255),
PRIMARY KEY(song_id)
);
這段代碼是一個SQL命令,它創建了一個名為songs
的表,其中有四列(song_id
、title
、artist
和genre
)。我們還指示表應該將song_id
定義為主鍵,并從1自動遞增。
現在,運行show tables;
以確認表已創建。
就這樣,我們已經成功創建了一個數據庫以及名為 songs
的表。
接下來,我們的任務是配置 Google App Engine,以便能夠部署我們的應用程序。
App Engine 是一個全面托管的平臺,專為大規模開發和托管 Web 應用程序而設計。它的一大優勢在于能夠自動擴展應用程序以滿足不斷變化的流量需求。
App Engine 官網介紹道:
“借助零服務器管理和零配置部署,開發人員可以全身心地投入到構建卓越的應用程序中,而無需為管理事務分心?!?/p>
配置 App Engine 可以通過 Google Cloud Console 的用戶界面完成,也可以通過 Google Cloud SDK 實現。在本節中,我們將采用 SDK 的方式。SDK 允許我們從本地計算機上部署、管理和監控 Google Cloud 實例。
請按照提供的指南下載并安裝適用于 Mac 或 Windows 的 SDK。安裝完成后,您需要在命令行界面中初始化 SDK,并選擇要操作的 Google Cloud 項目。
現在,SDK 已經準備就緒,接下來我們將更新 Python 腳本,添加數據庫憑證,并將應用程序部署到 App Engine。
為了適應新的架構(包括 Cloud SQL 和 App Engine),我們需要在本地環境中進行相應的設置更新。
首先,我們需要在項目的根文件夾中添加一個名為 app.yaml
的文件。這是 App Engine 托管和運行應用程序所必需的配置文件。它包含了 App Engine 運行應用程序所需的運行時環境和其他變量信息。對于我們的應用程序,我們需要將數據庫憑證作為環境變量添加到 app.yaml
文件中,以便 App Engine 能夠識別并連接到我們的數據庫實例。
在 app.yaml
文件中,添加以下代碼片段。您需要根據在設置 Cloud SQL 時獲取的信息,替換運行時環境和數據庫變量的值,包括用戶名、密碼、數據庫名稱和連接名稱。
#app.yaml
runtime: python37
env_variables:
CLOUD_SQL_USERNAME: YOUR-DB-USERNAME
CLOUD_SQL_PASSWORD: YOUR-DB-PASSWORD
CLOUD_SQL_DATABASE_NAME: YOUR-DB-NAME
CLOUD_SQL_CONNECTION_NAME: YOUR-CONN-NAME
現在,我們將安裝 PyMySQL。這是一個 Python MySQL 包,用于連接 MySQL 數據庫并對其執行查詢。通過在 CLI 中運行以下行來安裝 PyMySQL 軟件包:
pip install pymysql
此時,我們已準備好使用 PyMySQL 從應用程序連接到我們的 Cloud SQL 數據庫。這將使我們能夠在數據庫中獲取和插入查詢。
首先,在我們的根文件夾中創建db.py
文件,并添加以下代碼:
#db.py
import os
import pymysql
from flask import jsonify
db_user = os.environ.get('CLOUD_SQL_USERNAME')
db_password = os.environ.get('CLOUD_SQL_PASSWORD')
db_name = os.environ.get('CLOUD_SQL_DATABASE_NAME')
db_connection_name = os.environ.get('CLOUD_SQL_CONNECTION_NAME')
def open_connection():
unix_socket = '/cloudsql/{}'.format(db_connection_name)
try:
if os.environ.get('GAE_ENV') == 'standard':
conn = pymysql.connect(user=db_user, password=db_password,
unix_socket=unix_socket, db=db_name,
cursorclass=pymysql.cursors.DictCursor
)
except pymysql.MySQLError as e:
print(e)
return conn
def get_songs():
conn = open_connection()
with conn.cursor() as cursor:
result = cursor.execute('SELECT * FROM songs;')
songs = cursor.fetchall()
if result > 0:
got_songs = jsonify(songs)
else:
got_songs = 'No Songs in DB'
conn.close()
return got_songs
def add_songs(song):
conn = open_connection()
with conn.cursor() as cursor:
cursor.execute('INSERT INTO songs (title, artist, genre) VALUES(%s, %s, %s)', (song["title"], song["artist"], song["genre"]))
conn.commit()
conn.close()
我們在這里完成了幾個關鍵步驟來集成 Google App Engine 和 Cloud SQL。
首先,我們利用 app.yaml
文件從 os.environ.get
方法中檢索數據庫憑證。App Engine 能夠使 app.yaml
中定義的環境變量在應用程序代碼中輕松可用。
其次,我們創建了一個名為 open_connection
的函數,它使用這些憑證來建立與 MySQL 數據庫的連接。
接著,我們添加了兩個重要的函數:get_songs
和 add_songs
。get_songs
函數通過調用 open_connection
函數來建立數據庫連接,并查詢 songs
表。如果表中沒有記錄,則返回“No Songs in DB”的消息。而 add_songs
函數則負責在 songs
表中插入新的記錄。
最后,我們回到 main.py
文件,對代碼進行了重構。現在,我們調用 add_songs
函數來插入新的歌曲記錄,并調用 get_songs
函數從數據庫中檢索歌曲記錄,而不是像之前那樣從某個對象中獲取歌曲數據。
現在,讓我們來重構 main.py
文件,以確保它能夠正確地與數據庫進行交互。
#main.py
from flask import Flask, jsonify, request
from db import get_songs, add_songs
app = Flask(__name__)
@app.route('/', methods=['POST', 'GET'])
def songs():
if request.method == 'POST':
if not request.is_json:
return jsonify({"msg": "Missing JSON in request"}), 400
add_songs(request.get_json())
return 'Song Added'
return get_songs()
if __name__ == '__main__':
app.run()
我們導入了 get_songs
和 add_songs
函數,并在 songs()
視圖函數中根據請求類型分別調用它們。當接收到 POST 請求時,我們調用 add_songs
函數;當接收到 GET 請求時,我們調用 get_songs
函數。
至此,我們的應用程序已經開發完成。
接下來,我們需要添加 requirements.txt
文件。這個文件列出了運行應用程序所必需的所有程序包。App Engine 會自動檢查這個文件,并安裝其中列出的所有程序包,以確保應用程序能夠順利運行。
pip freeze | grep "Flask\|PyMySQL" > requirements.txt
為了獲取應用程序中使用的 Flask 和 PyMySQL 這兩個包及其版本信息,我們創建了一個 requirements.txt
文件,并將這些信息追加到了該文件中。
至此,我們已經成功添加了三個新文件:db.py
、app.yaml
和 requirements.txt
。
執行以下命令,部署您的應用。
gcloud app deploy
如果運行順利,您的控制臺將輸出以下內容:
您的應用現在正在App Engine上運行。要在瀏覽器中查看它,請在CLI中運行gcloud app browse
。
我們可以啟動Postman來測試我們的post
和get
請求。
get
請求(大預覽)我們的應用程序現已托管在 Google 的基礎設施之上,能夠充分利用無服務器架構所帶來的各種優勢,只需通過調整配置即可實現。展望未來,您可以基于本文的內容,進一步增強無服務器應用程序的健壯性。
借助 App Engine 和 Cloud SQL 等平臺即服務(PaaS)基礎設施,我們得以從底層架構的繁瑣事務中抽身,從而更專注于應用的快速構建。作為開發人員,我們無需再為配置管理、備份恢復、操作系統維護、自動擴展、防火墻設置以及流量遷移等事項而費心。當然,如果您對底層配置有著更為精細的控制需求,那么自定義構建的服務可能會是更好的選擇。
原文鏈接:https://www.smashingmagazine.com/2020/08/api-flask-google-cloudsql-app-engine/