全稱Representational State Transfer,即表現層狀態轉換,若是一個架構符合REST原則,咱們就稱他爲Restfull架構,其主要包括以下方面:html
REST的名稱"表現層狀態轉化"中,省略了主語。"表現層"其實指的是"資源"(Resources)的"表現層"。shell
所謂"資源",就是網絡上的一個實體,或者說是網絡上的一個具體信息。它能夠是一段文本、一張圖片、一首歌曲、一種服務,總之就是一個具體的實在。你能夠用一個URI(統一資源定位符)指向它,每種資源對應一個特定的URI。要獲取這個資源,訪問它的URI就能夠,所以URI就成了每個資源的地址或獨一無二的識別符。django
所謂"上網",就是與互聯網上一系列的"資源"互動,調用它的URI。json
"資源"是一種信息實體,它能夠有多種外在表現形式,咱們把"資源"具體呈現出來的形式,叫作它的」表現「api
好比,文本能夠用txt格式表現,也能夠用HTML格式、XML格式、JSON格式表現,甚至能夠採用二進制格式;圖片能夠用JPG格式表現,也能夠用PNG格式表現。服務器
URI只表明資源的實體,不表明它的形式。嚴格地說,有些網址最後的".html"後綴名是沒必要要的,由於這個後綴名錶示格式,屬於"表現層"範疇,而URI應該只表明"資源"的位置。它的具體表現形式,應該在HTTP請求的頭信息中用Accept和Content-Type字段指定,這兩個字段纔是對"表現層"的描述restful
狀態轉化(State Transfer)網絡
訪問一個網站,就表明了客戶端和服務器的一個互動過程。在這個過程當中,勢必涉及到數據和狀態的變化。架構
互聯網通訊協議HTTP協議,是一個無狀態協議。這意味着,全部的狀態都保存在服務器端。所以,若是客戶端想要操做服務器,必須經過某種手段,讓服務器端發生"狀態轉化"(State Transfer)。而這種轉化是創建在表現層之上的,因此就是"表現層狀態轉化"。app
客戶端用到的手段,只能是HTTP協議。具體來講,就是HTTP協議裏面,四個表示操做方式的動詞:GET、POST、PUT、DELETE。它們分別對應四種基本操做:GET用來獲取資源,POST用來新建資源(也能夠用於更新資源),PUT用來更新資源,DELETE用來刪除資源。
綜上,其實RESTful架構就是:
(1)每個URI表明一種資源;
(2)客戶端和服務器之間,傳遞這種資源的某種表現層;
(3)客戶端經過四個HTTP動詞,對服務器端資源進行操做,實現"表現層狀態轉化"。
但願URI中不出現動詞
如 顯示文章
野生寫法:/artical/show/1
正規寫法:/artical/1
若是必需要動詞,此時動詞須要看做爲一個服務,如銀行轉帳,從帳戶1向帳戶2匯款500元
野生寫法:POST /accounts/1/transfer/500/to/2
正規寫法:
POST /transaction HTTP/1.1 Host: 127.0.0.1 from=1&to=2&amount=500.00
但願URL中不出現版本號
http://www.example.com/app/1.0/foo http://www.example.com/app/1.1/foo http://www.example.com/app/2.0/foo
由於不一樣的版本,能夠理解成同一種資源的不一樣表現形式,因此應該採用同一個URI。版本號能夠在HTTP請求頭信息的Accept字段中進行區分
協議 API最好使用https
域名 儘可能使用專用API域名,如 api.baidu.com
路徑 又稱爲endpoint,表示API的具體資源,在restfull架構中,每一個URI表明一種資源,因此URI中的名詞需和實際功能對應
HTTP 動詞
經常使用動詞
GET(select) 獲取資源
POST (create)建立資源
PUT (update)更新資源(客戶端提供改變後的完整資源)
DELETE (delete)刪除資源
PATCH(update) 更新資源(客戶端提供改變的屬性)
不經常使用的HTTP動詞:
HEAD 獲取資源的元數據
OPTIONS 獲取信息,關於資源的那些屬性是客戶端能夠改變的
過濾信息
若是記錄的數量不少,服務器須要分段返回給用戶,API應該提供參數,過濾返回結果,以下:
狀態碼
返回結果
針對不一樣的操做,server向用戶返回的結果應該符合以下規範
RESTful api 關於django的插件名爲 djangorestframework,官方網站爲:http://www.django-rest-framework.org/
pip install djangorestframework
在project的settings.py中進行註冊app,並添加驗證配置
INSTALLED_APPS = [ ... 'rest_framework', ] #對於匿名只讀 REST_FRAMEWORK = { # Use Django's standard `django.contrib.auth` permissions, # or allow read-only access for unauthenticated users. 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' ] }
class IDC(models.Model): '''機房''' name = models.CharField(max_length=64, unique=True) def __str__(self): return self.name class Host(models.Model): hostname = models.CharField(max_length=64,unique=True) ip_addr = models.GenericIPAddressField() port = models.SmallIntegerField(default=22) idc = models.ForeignKey('IDC',blank=True,null=True) system_type_choices = ((0,'Linux'),(1,'Windows')) system_type = models.SmallIntegerField(choices=system_type_choices,default=0) memo = models.CharField(max_length=128,blank=True,null=True) enabled = models.BooleanField(default=1,verbose_name="啓用本機") class Meta: unique_together = ('ip_addr','port') verbose_name = "主機表" def __str__(self): return "%s(%s)"%( self.hostname,self.ip_addr)
rest_serializer.py
from app01 import models from rest_framework import serializers class IDCSerializer(serializers.ModelSerializer): class Meta: model = models.IDC fields = ('name',) class HostSerializer(serializers.ModelSerializer): class Meta: model = models.Host fields = ('id','hostname','ip_addr','port','idc','system_type','memo','enabled')
rest_views.py
from rest_framework import viewsets from app01 import models from app01 import rest_searializer class UserViewSet(viewsets.ModelViewSet): queryset = models.UserProfile.objects.all() serializer_class = rest_searializer.UserSerializer class IDCViewSet(viewsets.ModelViewSet): queryset = models.IDC.objects.all() serializer_class = rest_searializer.IDCSerializer class HostViewSet(viewsets.ModelViewSet): queryset = models.Host.objects.all() serializer_class = rest_searializer.HostSerializer
from rest_framework import routers from app01 import rest_viewset from django.conf.urls import url,include router = routers.DefaultRouter() router.register(r'idc',rest_viewset.IDCViewSet) router.register(r'host',rest_viewset.HostViewSet) urlpatterns = [ url(r'^', include(router.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) ]
後續會對上述的全部點進行詳細說明。