Restful API
基礎(chǔ)介紹:
? RESTful API(Representational State Transfer)是一種基于HTTP協(xié)議設(shè)計(jì)的應(yīng)用程序編程接口(API)風(fēng)格,用于在客戶端和服務(wù)器之間進(jìn)行通信。它提供了一組規(guī)范和約束,用于創(chuàng)建可伸縮、可靠和可維護(hù)的網(wǎng)絡(luò)服務(wù)。
-
路徑(URI)設(shè)計(jì):
- 使用有意義的路徑來(lái)表示資源,例如
/users
表示用戶資源。 - 遵循路徑層次結(jié)構(gòu),使用斜杠
/
分隔不同的資源和子資源,例如/users/{id}/orders
表示特定用戶的訂單資源。 - 避免在路徑中使用動(dòng)詞,使用HTTP方法來(lái)表示操作類(lèi)型。
- url鏈接中,不能有動(dòng)詞,只能有名詞。并且對(duì)于一些名詞,如果出現(xiàn)復(fù)數(shù),那么應(yīng)該在后面加s。
- 使用有意義的路徑來(lái)表示資源,例如
-
HTTP方法(Verbs):
-
使用適當(dāng)?shù)腍TTP方法來(lái)表示對(duì)資源的操作:
- GET:從服務(wù)器上獲取資源。
- POST:在服務(wù)器上新創(chuàng)建一個(gè)資源。
- PUT:在服務(wù)器上更新資源。(客戶端提供所有改變后的數(shù)據(jù))
- PATCH:在服務(wù)器上更新資源。(客戶端只提供需要改變的屬性)
- DELETE:從服務(wù)器上刪除資源。
-
合理使用HTTP狀態(tài)碼來(lái)表示請(qǐng)求的結(jié)果:
-
200 OK 服務(wù)器成功響應(yīng)客戶端的請(qǐng)求。 400 INVALID REQUEST 用戶發(fā)出的請(qǐng)求有錯(cuò)誤,服務(wù)器沒(méi)有進(jìn)行新建或修改數(shù)據(jù)的操作 401 Unauthorized 用戶沒(méi)有權(quán)限訪問(wèn)這個(gè)請(qǐng)求 403 Forbidden 因?yàn)槟承┰蚪乖L問(wèn)這個(gè)請(qǐng)求 404 NOT FOUND 用戶發(fā)送的請(qǐng)求的url不存在 406 NOT Acceptable 用戶請(qǐng)求不被服務(wù)器接收(比如服務(wù)器期望客戶端發(fā)送某個(gè)字段,但是沒(méi)有發(fā)送)。 500 Internal server error 服務(wù)器內(nèi)部錯(cuò)誤,比如出現(xiàn)了bug
-
-
3.參數(shù)傳遞
在 RESTful API 中,參數(shù)傳遞可以使用不同的方式,包括查詢參數(shù)(Query Parameters)、路徑參數(shù)(Path Parameters)、請(qǐng)求體(Request Body)和請(qǐng)求頭(Request Headers)。這些不同的方式可以根據(jù)具體的需求和語(yǔ)義選擇使用。
以下是對(duì)每種參數(shù)傳遞方式的簡(jiǎn)要說(shuō)明:
- 查詢參數(shù)(Query Parameters):
- 查詢參數(shù)是附加在URL末尾的鍵值對(duì),以
?
開(kāi)頭,多個(gè)參數(shù)使用&
分隔,例如:/users?name=john&age=25
。 - 查詢參數(shù)常用于過(guò)濾、排序、分頁(yè)等操作。
- 在服務(wù)器端,可以通過(guò)解析URL中的查詢參數(shù)來(lái)獲取傳遞的值。
- 查詢參數(shù)是附加在URL末尾的鍵值對(duì),以
- 路徑參數(shù)(Path Parameters):
- 路徑參數(shù)是包含在URL路徑中的變量,由花括號(hào)
{}
表示,例如:/users/{id}
。 - 路徑參數(shù)用于標(biāo)識(shí)特定的資源,如獲取特定用戶的信息。
- 在服務(wù)器端,可以通過(guò)解析URL路徑來(lái)提取路徑參數(shù)的值。
- 路徑參數(shù)是包含在URL路徑中的變量,由花括號(hào)
- 請(qǐng)求體(Request Body):
- 請(qǐng)求體是在HTTP請(qǐng)求中包含的數(shù)據(jù),通常使用POST、PUT等方法發(fā)送。
- 請(qǐng)求體可以包含結(jié)構(gòu)化數(shù)據(jù),如JSON、XML等格式,用于傳遞更復(fù)雜的參數(shù)。
- 在服務(wù)器端,可以通過(guò)解析請(qǐng)求體來(lái)獲取傳遞的值。
- 請(qǐng)求頭(Request Headers):
- 請(qǐng)求頭是包含在HTTP請(qǐng)求頭部中的鍵值對(duì),用于傳遞元數(shù)據(jù)和其他信息。
- 請(qǐng)求頭可以用于身份驗(yàn)證、內(nèi)容類(lèi)型指定等目的。
- 在服務(wù)器端,可以通過(guò)解析請(qǐng)求頭來(lái)獲取傳遞的值。
4.錯(cuò)誤處理
- 使用適當(dāng)?shù)腍TTP狀態(tài)碼來(lái)指示錯(cuò)誤,如400表示請(qǐng)求錯(cuò)誤、401表示未授權(quán)、500表示服務(wù)器內(nèi)部錯(cuò)誤等。
- 提供有用的錯(cuò)誤信息,幫助客戶端識(shí)別和解決問(wèn)題。
案例:
現(xiàn)在給出代碼,展示Restful APi 在Flask中的使用:
from flask import Flask, url_for, redirect, request
app = Flask(__name__)
app.debug = True
@app.route('/article/<id>/')
def article(id):
return '%s article detail' % id
@app.route('/login/', methods=['GET', 'POST'])
def login():
return 'login page'
@app.route('/profile/', methods=['GET', 'POST'])
def profile():
name = request.args.get('name') # get請(qǐng)求使用request.args獲取參數(shù)
if not name:
# 如果沒(méi)有name,說(shuō)明沒(méi)有登錄,進(jìn)行重定向,重定向到路由函數(shù)login
return redirect(url_for('login'))
else:
return "hello " + name
if __name__ == '__main__':
# host=0.0.0.0可以讓其他電腦也能訪問(wèn)到該網(wǎng)站,port指定訪問(wèn)的端口。默認(rèn)的host是127.0.0.1,port為5000
app.run(host='0.0.0.0', port=9000)
改進(jìn):
class User(Base):
# 定義表名為users
__tablename__ = 'users'
# 將id設(shè)置為主鍵,并且默認(rèn)是自增長(zhǎng)的
id = Column(Integer, primary_key=True, autoincrement=True)
# name字段,字符類(lèi)型,最大的長(zhǎng)度是50個(gè)字符
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(100))
# 修改內(nèi)置方法
def __str__(self):
return "<User(id='%s',name='%s',fullname='%s',password='%s')>" % (
self.id, self.name, self.fullname, self.password)
def to_json(self): # 封裝一個(gè)可以轉(zhuǎn)化為json格式的函數(shù)方法
return {"id": self.id, "name": self.name, "fullname": self.fullname, "password": self.password}
@app.route('/users/<id>/', methods=['GET'])
def users_get_by_id(id):
result = get_user_by_id(id)
return jsonify(result.to_json())# 這里的result應(yīng)該是python的字典類(lèi)型,最后使用Flask中的jsonify函數(shù)修飾一下
@app.route('/users/', methods=['GET'])
def users_get():
result = get_user_list()
return jsonify([x.to_json() for x in result]) # 使用列表生成式,對(duì)列表中的每一個(gè)元素都是用 to_json()
def get_user_by_id(user_id):
Session = sessionmaker(bind=engine)
session = Session()
return session.query(User).filter(User.id == user_id).all()[0]# 返回一個(gè)對(duì)象
def get_user_list():
Session = sessionmaker(bind=engine)
session = Session()
return session.query(User).order_by(User.id).all()
這樣改進(jìn)后,我們發(fā)現(xiàn)每一個(gè)路由函數(shù)的返回結(jié)果都是一個(gè)json對(duì)象,這樣也可以作為Ajax請(qǐng)求的地址來(lái)實(shí)現(xiàn)動(dòng)態(tài)加載數(shù)據(jù)了。
增刪改查:
增加:
def put_user(name, fullname, password):
Session = sessionmaker(bind=engine) # 導(dǎo)入引擎
session = Session() # 實(shí)例化一個(gè)session對(duì)象
add_user = User(name=name, fullname=fullname, password=password)
session.add(add_user)
session.commit()
return "ok"
結(jié)合一下:
@app.route('/users/' methods=['PUT·]]
def users_put():
name = request.args.get('name′)
fullname = request.args.get('fullname')
password = request.args.get('password')
try:
result = put_user(name, fullname, password)
if result == "ok":
return jsonify({
"status": "successful", "content":"add user Successful" ,"function":"put_user"
}),208
except Exception as e:
return jsonify({"status": "fail","content":e}),500
return 'users page'
修改:
def update_user_by_id(id, name, fullname,password):
Session = sessionmaker(bind=engine)
session = Session()
result =θ
if name:
result = session.query(User).filter(User.id == id).update({"name": name})
if fullname:
result = session.query(User).filter(User.id == id).update({"fullname": fullname})
if password:
result = session.query(User) .filter(User.id == id).update({"password": password})
session.commit()
session.close()
return result
在上面的操作中,如果更新成功,result會(huì)被置為1.
@app.route(/users/<id>/*, methods=['PATCH'])
def users_patch(id):
fullname = request.args.get('fullname')
name = request.args.get('name*)
password = request.args.get('password')
result = update_user_by_id(id, name, fullname, password)
if result == 1:
return jsonify(
{"status": "successful", "content":"update user successful", "function": "update_user_by_id"}), 200
if result == θ:
return jsonify(
{"status": "fail", "content": "Failed to update user data", "function": "update_user_by_id"}), 408
except Exception as e:
return jsonify(f"status": "fail", "Error Name": e.--class-- "content": eb), 500
刪除:
def delete_user_by_id(user_id):
Session = sessionmaker(bind=engine)
session = Session()
session.query(User).filter(User.id == user_id).delete()
session.commit()
session.close()
return "ok"
@app.route('/users/<id>/" methods=['DELETE'])
def users_delete_by_id(id):
try:
result = delete_user_by_id(id)
if result == "ok":
return jsonify({"status": "successful", "content": "delete user successful", "function": "put_user"}), 200
except Exception as e:
return jsonify({"status": "fail","content": e}),500
總結(jié):
? 在本篇博客中,我們深入探索了RESTful API的基礎(chǔ)知識(shí),并了解了如何在Flask框架中使用它來(lái)構(gòu)建強(qiáng)大的API。我們學(xué)習(xí)了RESTful原則、路徑設(shè)計(jì)、HTTP方法、參數(shù)傳遞等關(guān)鍵概念,并通過(guò)示例代碼演示了它們的實(shí)際應(yīng)用。
? 通過(guò)使用Flask框架,我們可以輕松地創(chuàng)建和管理RESTful API,從而使我們的應(yīng)用程序更加靈活、可擴(kuò)展和易于維護(hù)。Flask提供了強(qiáng)大的路由和視圖函數(shù)機(jī)制,使我們能夠以簡(jiǎn)潔的方式定義API的端點(diǎn)和動(dòng)作。
? 同時(shí),我們還探討了RESTful API的設(shè)計(jì)原則,如良好的路徑命名、合適的HTTP狀態(tài)碼和錯(cuò)誤處理等,這些原則幫助我們?cè)O(shè)計(jì)出易于理解和使用的API接口,提供良好的開(kāi)發(fā)者體驗(yàn)。
? 通過(guò)學(xué)習(xí)和實(shí)踐RESTful API的基礎(chǔ)知識(shí),我們可以構(gòu)建出符合標(biāo)準(zhǔn)的API,并為前端開(kāi)發(fā)人員、移動(dòng)應(yīng)用程序開(kāi)發(fā)人員和其他客戶端提供一致、可靠的接口。這不僅有助于提高開(kāi)發(fā)效率,還能促進(jìn)團(tuán)隊(duì)間的協(xié)作和集成,為構(gòu)建現(xiàn)代化、高性能的應(yīng)用奠定堅(jiān)實(shí)基礎(chǔ)。
? 無(wú)論是構(gòu)建簡(jiǎn)單的API還是復(fù)雜的分布式系統(tǒng),掌握RESTful API的基礎(chǔ)知識(shí)都是非常重要的。希望本篇博客對(duì)您在理解和應(yīng)用RESTful API方面起到了指導(dǎo)作用,并能為您的API開(kāi)發(fā)之旅提供一些有價(jià)值的見(jiàn)解。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-812081.html
? 祝您在使用Flask和構(gòu)建RESTful API的過(guò)程中取得巨大成功!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-812081.html
到了這里,關(guān)于探索Flask中的RESTful API設(shè)計(jì)與實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!