全称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')) ]
后续会对上述的全部点进行详细说明。