专栏首页Coder Sam的专栏体验Django REST framework,解读REST架构风格
原创

体验Django REST framework,解读REST架构风格

因为项目中使用了REST API,所以对REST架构风格做了一些研究。如果有对REST架构风格还不了解,或者一知半解的朋友,可以读读我的另一篇文章《那些年,我们一起误解过的REST》。

一开始在项目中使用的是OpenResty来实现REST API,但使用起来一直觉得不方便。主要是因为Lua没有ORM,也没有REST架构风格的框架。直到最近在用Django时,接触到Django REST framework,在深感便利的同时,也进一步加深了对REST架构风格的理解。所以写下这篇文章,一方面记录Django REST framework的体验过程,同时借此解读下REST架构风格。

1. 体验Django REST framework

1.1 安装

pip install django
pip install djangorestframework

1.2 创建Django项目并初始化

django-admin startproject rest_example  # 创建Django项目
django-admin.py startapp app    # 创建应用
python manage.py migrate    # 执行迁移
python manage.py createsuperuser --email admin@example.com --username admin # 创建超级用户

1.3 项目配置

在项目INSTALL_APP配置中加入rest_framework,修改rest_example/settings.py。

INSTALLED_APPS = (
    ...
    'rest_framework',
)

1.4 REST framework配置

在项目配置中加入REST_FRAMEWORK配置,在rest_example/settings.py加入以下内容。

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'
    ]
}

1.5 创建序列化器

创建rest_example/app/serializers.py文件,内容如下。

from django.contrib.auth.models import User, Group
from rest_framework import serializers


class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email', 'groups')


class GroupSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Group
        fields = ('url', 'name')

序列化器会自动将模型序列化。对于RESTful架构来说,超链模型序列化器是非常合适的,因为可以提供连通性。

1.6 创建视图

修改rest_example/app/views文件,内容如下。

from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_example.app.serializers import UserSerializer, GroupSerializer


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer


class GroupViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer

ViewSet封装了通用的视图,实现了get、post、put、delete等请求方法对应的通用处理方法,直接继承可以极大地简化代码。

1.7 配置路由

修改rest_example/urls文件,内容如下。

from django.conf.urls import url, include
from rest_framework import routers
from rest_example.app import views

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)

# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]

其中,api-auth路由是用于对REST API进行鉴权。

1.8 大功告成

启动Django,在浏览器中访问http://127.0.0.1:8000/,可以看到如下图所示界面。

image.png

只通过简单的配置,就得到了一个完善的REST API,可谓相当的便利。

2. 解读REST架构风格

2.1 资源URI

先看最简单的资源GET /,响应如下。

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "users": "http://127.0.0.1:8000/users/",
    "groups": "http://127.0.0.1:8000/groups/"
}

上述响应表示存在两种资源(可引用的对象):user资源和group资源,其URI分别为http://127.0.0.1:8000/users/和http://127.0.0.1:8000/groups/。

REST是面向资源的架构,在REST中,URI代表某个或某种资源,所以URI中只能有名词,而且一般是复数形式

再看user资源GET /users,响应如下。

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "url": "http://127.0.0.1:8000/users/1/",
        "username": "admin",
        "email": "admin@example.com",
        "groups": []
    }
]

上述响应表示当前只有一个user资源,用户名是admin,对应的URI是http://127.0.0.1:8000/users/1/。

因为URI表示的是具体的资源,所以应该在URI中包含user id。假如写为http://127.0.0.1:8000/users?id=1,这样代表的是从所有的user资源中过滤出id=1的资源集合,而不是表示id=1的具体资源。

在资源URI中,id需要放在URI路径中,不能放在请求参数中。请求参数适用于放过滤条件、分页信息等内容

2.2 连通性

在GET /请求的响应中,包含了user资源和对应group资源的URI。

在GET /users请求的响应中,也包含了groups资源,只是因为当前没有group资源,所以是空数组。我们在页面登录后,创建名称为superuser的group,再把admin用户加入到superuser组中。此时再请求GET /users,响应如下。

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "url": "http://127.0.0.1:8000/users/1/",
        "username": "admin",
        "email": "admin@example.com",
        "groups": [
            "http://127.0.0.1:8000/groups/1/"
        ]
    }
]

可以看到,groups数组表明admin用户只属于一个组,该group资源对应的URI为http://127.0.0.1:8000/groups/1/。如果需要了解该group资源的具体信息,则可以通过请求GET http://127.0.0.1:8000/groups/1获取。

在资源响应中包含关联资源的URI,可以提供后续操作的入口,将各种资源串联起来,便于客户端进行下一步操作

2.3 统一请求方法

REST通过统一请求方法,只知道资源URI就可以进行一系列增删查改的操作。反应到页面上,在GET /users资源时,页面可以提供如下页面来创建一个新的user资源,而这一切都是因为约定了POST是创建操作,资源描述通过body传递,资源ID由服务器自动生成,新生成资源的URI会通过请求响应返回。

image.png

同时,因为统一了请求方法,并且在Header中声明了该资源支持的请求方法,所以页面可以针对该资源,提供增删查改的一系列操作入口。如下图右上角所示。

image.png

2.4 资源的表述

在《那些年,我们一起误解过的REST》文中我提到过,同一个资源可以有多个不同的表述,每个表述需要是自描述的。例如,请求GET /users/1,可以选择返回json格式还是api格式,如下图右上角所示。

image.png

当请求json格式时,REST API返回纯json的表述;当请求api格式(实际上是html格式)时,REST API返回渲染过的html页面,所以才有上文的各种功能丰富的截图。这两种表述都是对相同资源的表述,本质上是相同的。至于究竟返回的是什么格式的表述,则需要通过响应Header中的Content-type字段说明。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Django REST Framework 教程开篇

    欢迎来到 HelloDjango 全栈系列教程第二步——Django REST Framework 教程!

    HelloGitHub
  • django-rest-framework配置json web token进行接口的认证

    使用django-rest-framework开发api并使用json web token进行身份验证 在这里使用django-rest-framework-j...

    earthchen
  • Django API开发: 使用Python和Django构建web APIs

    中文翻译版:Django API开发: 使用Python和Django构建web APIs

    宇宙之一粟
  • 在学习django-rest-framework时收集的学习资料推荐

    由于我平时开发的 django 项目都比较小,所以一直以来都是使用 django 模板引擎渲染 html 页面这种比较原始的方式在开发。最近发起了一个 Djan...

    追梦人物
  • 在学习django-rest-framework时收集的学习资料推荐

    由于我平时开发的 django 项目都比较小,所以一直以来都是使用 django 模板引擎渲染 html 页面这种比较原始的方式在开发。最近发起了一个 Djan...

    追梦人物
  • Python周刊:第 2 期

    TalkPython
  • Django+Vue开发生鲜电商平台之1.项目介绍

    本项目旨在使用Django、Vue和REST Framework等技术开发一个前后端分离的生鲜电商平台。

    cutercorley
  • Django-rest-framework 是个什么鬼?

    其实,基于 django-rest-framework 的 RESTful API 的开发,过程是完全类似的:

    HelloGitHub
  • 第 3 篇:实现博客首页文章列表 API

    此前在讨论基于模板引擎的开发方式和 django-rest-framework 开发的异同时说过,django-rest-framework 开发和传统的开发方...

    HelloGitHub
  • REST架构风格详解

    REST是Representational State Transfer(在表示层上的状态传输)的缩写,这个词的意思要在文章的后面才能解释清楚。REST是一种W...

    Java架构师历程
  • 一、二、开发准备

    Freshman
  • Django REST framework+Vue 打造生鲜超市(一)

    一、项目介绍 1.1.掌握的技术 Vue + Django Rest Framework 前后端分离技术 彻底玩转restful api 开发流程 Django...

    zhang_derek
  • 全栈“食”代:用 Django + Nuxt 实现美食分享网站(一)

    Django 作为 Python 社区最受欢迎的 Web 框架之一,凭借其高度抽象的组件和强大方便的脚手架,将快速且流畅的开发体验演绎到了极致。而 Nuxt 作...

    一只图雀
  • DRF系列总结一:DRF是啥?为啥子要用?

    目前组内很多项目都在用Django REST framework(简称DRF)来构建Restful WebApi,并推广到了许多实习生同学和外部服...

    高木工
  • 第 5 篇:用视图集,简化你的代码

    在 RESTful 架构中,对资源的常规操作无非就是查询、新增、修改、删除等这么几种。为此,django-rest-framework 分别提供了对应通用类视图...

    HelloGitHub
  • django_restframework模块学习

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

    菲宇
  • FastAPI框架诞生的缘由(上)

    原文:https://fastapi.tiangolo.com/alternatives/

    somenzz
  • Restful接口开发与测试—Django安装

    Django是一个开放源代码的Web应用框架,由Python写成。采用了MVC的框架模式,即模型M,视图V和控制器C。它最初是被开发来用于管理劳伦斯出版集团旗下...

    清风穆云
  • TO-do api

    在接下来的两章中,我们将构建一个Todo API后端,然后将其与React前端连接。 我们已经制作了第一个API,并回顾了HTTP和REST的抽象工作原理,但是...

    宇宙之一粟

扫码关注云+社区

领取腾讯云代金券