總述
REST是所有Web應(yīng)用都應(yīng)該遵守的架構(gòu)設(shè)計(jì)指導(dǎo)原則。
Representational State Transfer,翻譯是”表現(xiàn)層狀態(tài)轉(zhuǎn)化”。
REST核心: 資源, 狀態(tài)轉(zhuǎn)移, 統(tǒng)一接口
資源: 是REST最明顯的特征,是指對(duì)某類(lèi)信息實(shí)體的抽象,資源是服務(wù)器上一個(gè)可命名的抽象概念,資源是以名詞為核心來(lái)組織的,首先關(guān)注的是名詞。
狀態(tài)轉(zhuǎn)移: 是指客戶(hù)端痛服務(wù)端進(jìn)行交互的過(guò)程中,客戶(hù)端能夠通過(guò)對(duì)資源的表述,實(shí)現(xiàn)操作資源的目的。
統(tǒng)一接口: REST要求,必須通過(guò)統(tǒng)一的接口來(lái)對(duì)資源執(zhí)行各種操作。對(duì)于每個(gè)資源只能執(zhí)行一組有限的操作。 比如,客戶(hù)端通過(guò)HTTP的4個(gè)請(qǐng)求方式(POST, GET, PUT, PATCH)來(lái)操作資源,也就意味著不管你的url是什么,不管請(qǐng)求的資源是什么但操作的資源接口都是統(tǒng)一的。
GET用來(lái)獲取資源,POST用來(lái)新建資源(也可以用于更新資源),PUT(PATCH)用來(lái)更新資源,DELETE用來(lái)刪除資源。
api定義規(guī)范
http://xxx.com/api/
資源
在RESTful架構(gòu)中,每個(gè)網(wǎng)址代表一種資源(resource),所以網(wǎng)址中不能有動(dòng)詞,只能有名詞,而且所用的名詞往往與數(shù)據(jù)庫(kù)的表格名對(duì)應(yīng)。一般來(lái)說(shuō),數(shù)據(jù)庫(kù)中的表都是同種記錄的"集合"(collection),所以API中的名詞也應(yīng)該使用復(fù)數(shù)。
舉例來(lái)說(shuō),有一個(gè)API提供動(dòng)物園(zoo)的信息,還包括各種動(dòng)物和雇員的信息,則它的路徑應(yīng)該設(shè)計(jì)成下面這樣。
https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
http請(qǐng)求方式
GET(SELECT):從服務(wù)器取出資源(一項(xiàng)或多項(xiàng))
POST(CREATE):在服務(wù)器新建一個(gè)資源
PUT(UPDATE):在服務(wù)器更新資源(客戶(hù)端提供改變后的完整資源)
PATCH(UPDATE):在服務(wù)器更新資源(客戶(hù)端提供改變的屬性)
DELETE(DELETE):從服務(wù)器刪除資源
例子:
GET /zoos:列出所有動(dòng)物園
POST /zoos:新建一個(gè)動(dòng)物園
GET /zoos/ID:獲取某個(gè)指定動(dòng)物園的信息
PUT /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的全部信息)
PATCH /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的部分信息)
DELETE /zoos/ID:刪除某個(gè)動(dòng)物園
GET /zoos/ID/animals:列出某個(gè)指定動(dòng)物園的所有動(dòng)物
DELETE /zoos/ID/animals/ID:刪除某個(gè)指定動(dòng)物園的指定動(dòng)物
filter過(guò)濾
?page=2&per_page=100:指定第幾頁(yè),以及每頁(yè)的記錄數(shù)。
?sortby=name&order=asc:指定返回結(jié)果按照哪個(gè)屬性排序,以及排序順序。
?animal_type_id=1:指定篩選條件
狀態(tài)碼
服務(wù)端向用戶(hù)返回請(qǐng)求api的結(jié)果,在結(jié)果中包含了status codes 狀態(tài)碼的,可以通過(guò)狀態(tài)碼去判斷請(qǐng)求api的狀態(tài)是成功還是失敗
200 OK - [GET]:服務(wù)器成功返回用戶(hù)請(qǐng)求的數(shù)據(jù),該操作是冪等的(Idempotent)。
201 CREATED - [POST/PUT/PATCH]:用戶(hù)新建或修改數(shù)據(jù)成功。
202 Accepted - [*]:表示一個(gè)請(qǐng)求已經(jīng)進(jìn)入后臺(tái)排隊(duì)(異步任務(wù))
204 NO CONTENT - [DELETE]:用戶(hù)刪除數(shù)據(jù)成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用戶(hù)發(fā)出的請(qǐng)求有錯(cuò)誤,服務(wù)器沒(méi)有進(jìn)行新建或修改數(shù)據(jù)的操作,該操作是冪等的。
401 Unauthorized - [*]:表示用戶(hù)沒(méi)有權(quán)限(令牌、用戶(hù)名、密碼錯(cuò)誤)。
403 Forbidden - [*] 表示用戶(hù)得到授權(quán)(與401錯(cuò)誤相對(duì)),但是訪(fǎng)問(wèn)是被禁止的。
404 NOT FOUND - [*]:用戶(hù)發(fā)出的請(qǐng)求針對(duì)的是不存在的記錄,服務(wù)器沒(méi)有進(jìn)行操作,該操作是冪等的。
406 Not Acceptable - [GET]:用戶(hù)請(qǐng)求的格式不可得(比如用戶(hù)請(qǐng)求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用戶(hù)請(qǐng)求的資源被永久刪除,且不會(huì)再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 當(dāng)創(chuàng)建一個(gè)對(duì)象時(shí),發(fā)生一個(gè)驗(yàn)證錯(cuò)誤。
500 INTERNAL SERVER ERROR - [*]:服務(wù)器發(fā)生錯(cuò)誤,用戶(hù)將無(wú)法判斷發(fā)出的請(qǐng)求是否成功。
錯(cuò)誤處理
如果狀態(tài)碼是4xx,就應(yīng)該向用戶(hù)返回出錯(cuò)信息。一般來(lái)說(shuō),返回的信息中將error作為鍵名,出錯(cuò)信息作為鍵值即可。
{
error: '錯(cuò)誤信息'
}
django中使用restful
pip install djangorestframework==3.4.6
pip install django-filter # Filtering support
settings.py配置的修改
在工程目錄中的settings.py文件的INSTALLED_APPS中需要添加rest_framework
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'rest_framework',
]
在應(yīng)用app中定義路由URL
定義路由需要注意:
使用router.register注冊(cè)的url為資源,而且資源只能為名詞不能為動(dòng)詞。
定義的資源不要加'/'斜杠,在訪(fǎng)問(wèn)地址的時(shí)候,URL中會(huì)默認(rèn)的添加反斜杠'/'。
from rest_framework.routers import SimpleRouter
from app import views
# 引入路由
router = SimpleRouter()
# 使用router注冊(cè)的地址
router.register(r'^student', views.StudentView)
urlpatterns = [
]
urlpatterns += router.urls
在視圖views.py文件中定義StudentView類(lèi)
通過(guò)定義StudentView并繼承了mixins的方法,即可有對(duì)應(yīng)個(gè)增刪改查的方法。在StudentView中還定義了兩個(gè)變量queryset、serializer_class。
from rest_framework import viewsets, mixins
from app.models import Student
from app.serializers import StudentSerializer
class StudentView(mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.DestroyModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
viewsets.GenericViewSet):
# 返回?cái)?shù)據(jù)
queryset = Student.objects.all()
# 序列化結(jié)果
serializer_class = StudentSerializer
其中queryset參數(shù)表示需要需要序列化的數(shù)據(jù) serializer_class參數(shù)指定序列化的類(lèi)
定義序列化類(lèi)
序列化類(lèi)需要繼承ModelSerializer,使用ModelSerializer表明序列化整個(gè)Student模型,并且可以指定虛擬化哪些字段。
from rest_framework import serializers
from app.models import Student
class StudentSerializer(serializers.ModelSerializer):
class Meta:
# 指定序列化的模型
model = Student
# 指定序列化哪些字段
fields = ['id', 's_name', 's_age']
通過(guò)以上的代碼,可以通過(guò)以下的URL和HTTP請(qǐng)求方式,完成對(duì)資源Student的CRUD操作:
CRUD對(duì)應(yīng)的增刪改查:
增: POST http://127.0.0.1:8080/stu/addStu/
刪: DELETE http://127.0.0.1:8080/stu/addStu/1/
改: UPDATE http://127.0.0.1:8080/stu/addStu/1/
查: GET http://127.0.0.1:8080/stu/addStu/1/
