REST介绍

全称Representational State Transfer,即表现层状态转换,如果一个架构符合REST原则,我们就称他为Restfull架构,其主要包括如下方面:

  • 资源Resources

REST的名称"表现层状态转化"中,省略了主语。"表现层"其实指的是"资源"(Resources)的"表现层"。

所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的实在。你可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的URI。要获取这个资源,访问它的URI就可以,因此URI就成了每一个资源的地址或独一无二的识别符。

所谓"上网",就是与互联网上一系列的"资源"互动,调用它的URI。

  • 表现层 Representation

"资源"是一种信息实体,它可以有多种外在表现形式,我们把"资源"具体呈现出来的形式,叫做它的”表现“

比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图片可以用JPG格式表现,也可以用PNG格式表现。

URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定,这两个字段才是对"表现层"的描述

  • 状态转化(State Transfer)

    访问一个网站,就代表了客户端和服务器的一个互动过程。在这个过程中,势必涉及到数据和状态的变化。

    互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。

    客户端用到的手段,只能是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。

    综上,其实RESTful架构就是:

    ​ (1)每一个URI代表一种资源;

      (2)客户端和服务器之间,传递这种资源的某种表现层;

      (3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现"表现层状态转化"。

    RESTful架构设计规范

    • 希望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应该提供参数,过滤返回结果,如下:

      • ?limit=10 指定返回的记录数量
      • ?offset=10 指定反馈记录的开始位置
      • ?page=2&per_page=100 指定第几页,以及每页的记录数量
      • ?sortby=name&order=asc 指定返回的结果按那个属性进行排序,以及如何排序
      • ?animal_type_id=1 指定筛选条件
    • 状态码

      • 200 (“OK”) 用于一般性的成功返回, 不可用于请求错误返回
      • 201 (“Created”) 资源被创建
      • 202 (“Accepted”) 用于Controller控制类资源异步处理的返回,仅表示请求已经收到。对于耗时比较久的处理,一般用异步处理来完成
      • 204 (“No Content”) 此状态可能会出现在PUT、POST、DELETE的请求中,一般表示资源存在,但消息体中不会返回任何资源相关的状态或信息。
      • 301 (“Moved Permanently”) 资源的URI被转移,需要使用新的URI访问
      • 302 (“Found”) 不推荐使用,此代码在HTTP1.1协议中被303/307替代。我们目前对302的使用和最初HTTP1.0定义的语意是有出入的,应该只有在GET/HEAD方法下,客户端才能根据Location执行自动跳转,而我们目前的客户端基本上是不会判断原请求方法的,无条件的执行临时重定向
      • 303 (“See Other”) 返回一个资源地址URI的引用,但不强制要求客户端获取该地址的状态(访问该地址)
      • 304 (“Not Modified”) 有一些类似于204状态,服务器端的资源与客户端最近访问的资源版本一致,并无修改,不返回资源消息体。可以用来降低服务端的压力
      • 307 (“Temporary Redirect”) 目前URI不能提供当前请求的服务,临时性重定向到另外一个URI。在HTTP1.1中307是用来替代早期HTTP1.0中使用不当的302
      • 400 (“Bad Request”) 用于客户端一般性错误返回, 在其它4xx错误以外的错误,也可以使用400,具体错误信息可以放在body中
      • 401 (“Unauthorized”) 在访问一个需要验证的资源时,验证错误
      • 403 (“Forbidden”) 一般用于非验证性资源访问被禁止,例如对于某些客户端只开放部分API的访问权限,而另外一些API可能无法访问时,可以给予403状态
      • 404 (“Not Found”) 找不到URI对应的资源
      • 405 (“Method Not Allowed”) HTTP的方法不支持,例如某些只读资源,可能不支持POST/DELETE。但405的响应header中必须声明该URI所支持的方法
      • 406 (“Not Acceptable”) 客户端所请求的资源数据格式类型不被支持,例如客户端请求数据格式为application/xml,但服务器端只支持application/json
      • 409 (“Conflict”) 资源状态冲突,例如客户端尝试删除一个非空的Store资源
      • 412 (“Precondition Failed”) 用于有条件的操作不被满足时
      • 415 (“Unsupported Media Type”) 客户所支持的数据类型,服务端无法满足
      • 500 (“Internal Server Error”) 服务器端的接口错误,此错误于客户端无关
    • 返回结果

      针对不同的操作,server向用户返回的结果应该符合如下规范

      • GET 返回资源对象的列表或单个资源
      • POST 返回新生的资源对象
      • PUT 返回完整的资源对象
      • PATCH 返回完整的资源对象
      • DELETE 返回空文档,并告知结果

Django + RESTful安装配置

RESTful api 关于django的插件名为 djangorestframework,官方网站为:http://www.django-rest-framework.org/

  • 安装

pip install djangorestframework

  • setting配置

在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'
]
}
  • models配置
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)
  • Serializers配置

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')
  • views配置

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
  • URL 配置
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'))
]
  • 启动Django 测试

http://127.0.0.1:8000/api/

后续会对上述的所有点进行详细说明。

Django restframwork的更多相关文章

  1. Django restframwork获取列表详情

    z哎Django restframwork中就有一个类可以获取列表的详情内容,只有两行代码就可以搞定,在浏览器测试是ok的.但是这样的接口给前端,前端点击详情然后会将models.表名.objects ...

  2. django restframwork 教程之authentication权限

    当前我们的API在编辑或者删除的时候没有任何限制,我们不希望有些人有高级的行为,确保: 代码段始终与创建者相关联 只允许授权的用户可以创建代码段 只允许代码段创建者可以更新和删除 没有认证的请求应该有 ...

  3. Django restframwork教程之类视图(class-based views)

    我们也可以使用类的views写我们的API,我们将看到这是一个强大的模式,允许我们重用公共功能,让我们的代码整洁 使用Class-based Views重新改写我们的API 打开views.py文件, ...

  4. django restframwork教程之Request和Response

    从这一篇文章开始,我们会覆盖整个REST framwork框架的核心,接下来让我们介绍一些基础的构建块 Request 对象 REST framework 引入了一个扩展HttpRequest的请求对 ...

  5. Django restframwork实现自定义数据格式的分页与搜索

    最近因为在做分页时遇到的问题很多,页浪费了好多时间,所以记录一下.以后如遇到可用省去不必要的麻烦 restframwork中的官方文档对分页和搜索页进行了详细的介绍,但是我公司需要的return的js ...

  6. DRF之REST规范介绍及View请求流程分析

    编程是数据结构和算法的结合,而在Web类型的App中,我们对于数据的操作请求是通过url来承载的,本文详细介绍了REST规范和CBV请求流程. 编程是数据结构和算法的结合,小程序如简单的计算器,我们输 ...

  7. 利用 Django REST framework 编写 RESTful API

    利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...

  8. restframwork之序列化

    一 restframwork为我们提供了一个快速实例,方便我们快速理解restframwork的序列化的原理. 快速实例化 Django REST framework API 指南 二 restfra ...

  9. django的restfulapi

    Django Rest framework 的流程大概是这样的 建立 Models 依靠 Serialiers 将数据库取出的数据 Parse 为 API 的数据(可用于返回给客户端,也可用于浏览器显 ...

随机推荐

  1. 【Unity笔记】物体的Transform操作:速度、旋转、平移

    例如,通过按键/摇杆来操作飞机在三维空间的飞行状态.包括速度(大小,方向).位移. public class ExampleClass : MonoBehaviour { public float s ...

  2. mount -t nfs 不能使用

    去年使用一个新的文件系统的时候,发现mount -t nfs ip:/g/ftp ~/mnt -o tcp,nolock 不能使用 一直以为是因为mount 命令更新了,有些用法我不会用,但是刚才发现 ...

  3. Ext 的一些常用方法

    一.Ext 1.1 Ext.isEmpty(v, allowBlank) //是否为空[链接] 1.2 Ext.isArray(v) //是否为数组集合 1.3 Ext.isPrimitive(v) ...

  4. Missing artifact jdk.tools:jdk.tools:jar:1.8 pom.xml

    在maven项目中出现下面错误信息: Description Resource Path Location Type Missing artifact jdk.tools:jdk.tools:jar: ...

  5. CodeIgniter(3.1.4)框架中添加执行时间统计代码

    CodeIgniter(3.1.4)框架中添加,执行时间统计代码: system/core/CodeIgniter.php最后行处. /* * ---------------------------- ...

  6. sizeof(数组名)和sizeof(指针)

    在做这道题时: 32位环境下,int *p=new int[10];请问sizeof(p)的值为()A.4              B.10              C.40           ...

  7. 表单提交 多个name相同的input

    <form action="{:U('Index/test')}" method="post"> <foreach name="di ...

  8. thinkphp 查询指定分类下的文章

    $list = $Dao->query("SELECT xp_wztj.bt,xp_wztj.time,xp_wztj.gjz,xp_wztj.wz,xp_wzfl.name FROM ...

  9. Geometric deep learning on graphs and manifolds using mixture model CNNs

    Monti, Federico, et al. "Geometric deep learning on graphs and manifolds using mixture model CN ...

  10. 【转】DirectorySearcher.Filter属性说明

    DirectorySearcher.Filter属性扩充申明 DirectorySearcher mySearcher = new DirectorySearcher(entryOU, "( ...