基于Django的RESTful通用程序接口研究与实践

2018-01-04 10:59张云飞杨明光
电脑知识与技术 2018年28期

张云飞 杨明光

摘要:随着网站开发技术的发展,前后端分离的设计方法已经成为主流技术路线,这种方式一方面能够使开发工作精细化,前后端开发人员各司其职,互不干扰,另一方面使整个系统易于维护和扩展。这种开发模式的关键在于后端开发人员要设计出一个简洁、清晰、权限分明的通用程序接口,用于与系统前端程序进行数据交互。本文通过对目前最流行的REST(Representational State Transfer)规范的研究,实现通用程序接口设计与开发,进而实现应用开发的前后端分离。REST规范能有效降低开发人员的沟通成本。Django是采用Python编写的网络程序设计框架,采用Django框架能极大的简化通用程序接口设计的工作量。

关键词:Django;RESTful;网络通用接口

中图分类号:TP391 文献标识码:A 文章编号:1009-3044(2018)28-0030-03

Research and Practice of RESTful General Program Interface Based on Django

(CNOOC Research Institute, Beijing 100028, China)

Abstract: With the development of Web site development technology, the design method of front and back end separation has become the mainstream technical route, this way can make the development work fine, the front and back end developers have their own duties, mutual interference, on the other hand, the whole system is easy to maintain and expand. The key to this development pattern is that the backend developer should design a concise, clear, and privileged Universal program interface for data interaction with the system front-end program. Through the research of the most popular rest (representational state Transfer) specification, this paper realizes the design and development of universal Program interface, and then realizes the separation of the front and back end of application development. Rest specifications can effectively reduce the communication costs of developers. Django is a network programming framework written in Python, and the Django framework can greatly simplify the work of common Program interface design.

Key words: Django;restful; web API

1 引言

在移動互联网时代,各类终端设备如潮水般涌现,如常见的各类PAD,各种尺寸的Mobile,还有已经久经沙场的各类PC。这些设备给使用人员带去了便利,但是对于开发人员来讲却是噩梦的开始。以往采用浏览器的响应方式很显然已经无法满足用户对高用户体验的要求。如何将开发的应用快速适配到各类型设备,尽可能地减少开发人员的工作量,提升效率,快速形成生产力,是对开发人员提成的最迫切的要求。基于此,前后端分离的需求越来越被重视,前端与用户打交道,负责展现数据与用户交互;后端负责业务和相关数据的处理,前后端通过统一的接口规范来进行数据的交互。

目前,要使应用在开发过程中前后端分离,在设计实现统一通用接口方面,最佳实践是采用REST规范。

2 REST规范介绍

2.1 定义

REST是“REpresentational State Transfer”的缩写,中文翻译成“表现状态转换”【1】。该规范由2000年Roy Thomas Fielding博士提出。该规范并不是一种新技术的或者新组件或者新服务的创造,而是一种理念的创新,将现有的WEB技术特征和能力进行整合,使其符合一些准则和约束。如果一个架构符合REST规范,就称它为RESTful架构【3】。

2.2 资源

与面向对象的编程语言中一切都是对象一样,在REST规范的世界里,一切都是资源;而与编程语言中的对象不一样的是,在REST规范中,资源只定义了有限的方法。理解REST规范的重点在于理解什么是资源。可以把资源理解成一种对象,包括对象的类型、数据、关系、操作等等。

资源要能够被识别,就需要给每个资源分配一个唯一的标识。在REST规范中,这个唯一的标识是URI(Uniform Resource Identifier)【1】。URI的最大特点是可读性强,能够降低前后端开发人员的沟通次数,提高效率。例如:http://www.xxx.abc/employees/c001表示的是编号为001的员工。

2.3 资源接口统一

REST规范规定要使用统一的接口原则,也就是上文提到的资源只限定了有限的方法,无论什么资源,都可以通过使用限定的这几类方法进行资源的访问。REST中规定了六种类型的请求方式:GET、POST、PUT、DELETE、HEAD、OPTIONS,正好与CRUD(Create-Retrieve-Update-Delete,增删改查)四种操作相对应,例如,GET(查)、POST(增)、PUT(改)、DELETE(删)。例如:

[REST請求 描述 GET:/employees 获取所有员工的信息 GET:/employees/001 获取ID为001的员工信息 PUT:/employees/001 更新ID为001的员工信息 DELETE:/employees/001 删除ID为001的员工信息 POST:/employees/001 创建ID为001的员工信息 ]

2.4 具体约束

REST规定了4个约束:

l 每个资源拥有一个标识,这个标识可以用来唯一的标明该资源

l 消息具备自描述性

l 资源的自描述性

l HTTP超媒体作为应用状态引擎

上图是一个典型的服务端返回的结果信息,从结果信息中可以得知下一步的操作信息,该向哪个URL发送请求,还能知道资源的描述情况、唯一标识是什么以及采用什么消息格式进行交互理解的。所以,一个典型的REST规范形成的服务,不需要额外的接口描述文档,直接通过服务器端返回的信息,即可知道在该资源上能进行哪些操作。这可以缩短前后端开发人员的交流成本。

3 接口设计与实现

3.1 Django-REST-Framework介绍

Django REST framework是一个基于Django的用于创建网络应用通用接口的REST框架,功能强大且灵活【2】。具备以下特点:

l 对开发人员友好的可视网络通用接口

l 具备权限管理模块

l 序列化同时支持ORM和非ORM数据源

l 采用功能性视图即可自定义所有通用接口

l 有强大的社区支持

l 应用广泛,包括Mozilla,Red Hat等

3.2 接口设计及实现

3.2.1 环境搭建及数据序列化

作为实验,强烈建议创建一个与真是环境隔离的实验环境,本接口设计采用Python3自带的venv创建虚拟环境,并安装好相关包及依赖包,涉及django和djangorestframework。其中,django用于按照我们熟悉的开发架构,去涉及开发符合REST规范的通用程序接口,而djangorestframework则可以看成是该框架下的一个APP,只需要将rest_framework添加到INSTALLED_APPS中即可,简单快捷。

通常情况下,前端从调用后台API,API肯定需要返回数据给前端,返回的数据必须具有统一的格式,目前主流用的比较多的是JSON,可能有少部分还在用XML。具体到djangorestframework中,序列化就是将数据实例信息(Model信息)自动转换为JSON,而且也可以将前端传给后台的JSON数据转换为python的数据类型(dict/list/set等)。举个简单的例子:

序列化之前:

classBookSerializer(serializers.ModelSerializer):

tracks = serializers.StringRelatedField(many=True)

class Meta:

model = Book

fields = ('writer', 'price', 'public')

序列化之后:

{ 'writer': 'libai',

‘price: ‘$65,

'public': ‘sanhe,

}

3.2.2 请求和响应

请求和响应是REST framework的核心部分,是上一章提到的基于HTTP请求与响应的具体实现。

在请求部分,在djangorestframework框架中,Request对象负责所有的请求工作。该对象继承自普通的HttpRequest,但更灵活。在Request对象中,最核心的是request.data属性,比Django中的Request.POST更加灵活,能处理更多的请求。Request.POST只能采用POST方法去处理相关表单(form)数据,而request.Data则可以采用‘POST、‘PUT、‘PATCH等方法处理任意数据。

在响应部分,Response对象负责所有相关操作,是一种模板响应,将纯粹的内容返还给客户端去展示。具体的返回数据的形式则可以通过内容协商来决定。在代码中,return Response(data)即可完成响应。

需要注意的是,响应时,经常会出现各种异常响应,就好比在浏览网页时,经常出现404等代码,称之为状态码。这些状态码,就是响应对象提供的。在djangorestframework框架中,有着非常人性化的涉及,状态码并不是一堆数字的堆砌,而是提供了更加明确的标识,比如HTTP_404_NOT_FOUND等。下面是一个具体的代码片段,用于实现请求和响应。

@api_view(['GET', 'PUT', 'DELETE'])

defbook_detail(request, pk):

"""

读取, 更新或删除。

"""

try:

book = Book.objects.get(pk=pk)

exceptBook.DoesNotExist:

return Response(status=status.HTTP_404_NOT_FOUND)

ifrequest.method == 'GET':

serializer = BookSerializer(book)

return Response(serializer.data)

elifrequest.method == 'PUT':

serializer = BookSerializer(book, data=request.data)

ifserializer.is_valid():

serializer.save()

return Response(serializer.data)

return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

elifrequest.method == 'DELETE':

book.delete()

return Response(status=status.HTTP_204_NO_CONTENT)

代碼中提到的@api_view是djangorestframework提供的通用视图的封装,这些封装的视图,提供了确保视图能够收到Request实例,将内容赋予Response对象等一些基本功能。

上述的代码片段跟开发Django应用时采用的视图很相似,但视图中请求/响应的内容类型已经不需要明确解析/定义,request.data会对输入的json请求进行自行处理。

3.2.3 认证和权限

认证和权限是一个通用接口设计过程中不可缺少的一部分。通过认证,可以保障接口的安全使用,而权限则能将一些敏感信息保护起来,特别是删除权限,不能随便调用。基于djangorestframework框架来添加接口认证及权限设置需要以下几方面工作:

l 将序列化的模型与其创建者相互关联

l 只有经过身份验证(登录)的用户才可以创建模型

l 只有创建该模型的用户才可以对其进行更改或者删除

l 未经验证的用户只具有访问(只读)的功能

模型与创建者的关联,在具体程序实现上,只需要在model模块增加所有者字段,后台的效果就是在数据库中增加了一个该模型的所有者字段,与开发Django应用时无差别;在权限的控制上,可以用框架提供的permissions模块,通过该模块即可完成数据模型的精细化控制,比如通过permission_classes = (permissions.IsAuthenticatedOrReadOnly,)即可实现只有登录的用户才有权限创建修改,否则只有读的权限。

3.2.4 小结

Djangorestframework框架的功能非常丰富,限于篇幅,只介绍了三个在设计实现通用接口时必备的功能模块,有了数据的序列化,就有了后台数据与前台数据相互交流的统一格式,一般采用json格式,通俗来讲就是前后台要用同一种语言,才能沟通;有了请求和响应,相当于一种载体,有了这种载体,可以把前台的数据送到后端,后端的数据可以发给前端,有来有去相互交互;权限认证则是为了能够保障接口的安全性,后台数据是敏感的,设计一个通用接口时,认证和权限模块必不可少。

4 结论

本文介绍了目前流行的REST规范,目的是应用该规范设计开发通用程序接口;介绍了基于Django的REST规范框架djangorestframework,该框架提供了丰富的类,能快速、简洁地实现符合REST规范的通用程序接口;以创建一个图书数据管理通用接口为例,介绍了在接口实现过程中必备的三个模块及具体实现方法,供开发人员做参考设计。

参考文献:

[1] 赵震一,李哲.RESTful Web APIs中文版[M].北京:电子工业出版社,2014.

[2] http://www.django-rest-framework.org/.

[3] 郭理勇.RESTful API开发实战[M].北京:清华大学出版社,2018.

【通联编辑:唐一东】