对前后端分离设计模式的理解总结(部分Django描述)

最近对前后端分离设计模式的理解总结:

为什么要做前后端分离:

  • 有些人会说:因为职责明确,因为不再用模板做视图层 render HTML,后端不用自己写前端就会轻松些... 这些大多说的不错,但还是比较表象,主要的原因其实是 源于需求变化

    在现代web开发中,我们对于前端的需求越来越复杂,我们需要 PC端浏览器、手机端浏览器 、Android APP 和 iPhone APP 、微信小程序等多种需求。

    由于我们前端可能涉及设计到的页面种类越来越多,而 vue、angular、react 等前端框架越来越好的支持:“ Code once,run everywhere. ”,所以前端的开发渐渐独立、并更为体系化。

    故而曾经那种单凭一套模板渲染页面的方法似乎太局限了。

  • 而一旦采用 前后端分离 的模式,并且采用 restful 设计规范,那么后端就只需要提供数据 API 接口即可,后端只需要长期维护这一套代码就行了。

Django 的 FBV & CBV

FBV:Function base view 基于方法的视图

CBV:Class base view 基于类的视图

在我最开始尝试用 Flask 框架遵循 Restful 规范按路由设计接口时,常常有这样几个疑问和思考:

  • 我的需求这么多,难道没一个都要设计一个接口吗?这样方便维护吗?
  • 比如一个接口可能有 GET、POST 或是 PUT 等类型的请求,我难道每次都要写一个选择分支:if request.method == ' ... ': 才可以吗?

所以之后我了解到,其实是我没有了解 FBV 与 CBV 的概念。

正所谓:类就是 把数据封装进对象里 ,并赋予对象 行为 的能力。

所以我们完全可以把一个需求的接口封装成为一个类:

from django.views import View

class UserView(View): # 我们假设这是一个关于用户的接口,django/Flask中路由也叫视图。
        
    def get(self, request, *args, **kwargs):
        # ... 对应GET请求
        
    def post(self, request, *args, **kwargs):
        # ... 对应POST请求
        
    def put(self, request, *args, **kwargs):
        # ... 对应PUT请求
    
    def delete(self, request, *args, **kwargs):
        # ... 对应DELETE请求
        

因为继承了 django 的 View 类,所以在默认情况下,会自动根据请求类型映射该类中对应的请求方法。

但是在所有的 python web 框架乃至一些其他语言的框架之中,对 HTTP 请求类型的方法映射都是由一个专门的反射函数来实现的

# 本身在django的源码 base.py 中:
def dispatch(self, request, *args, **kwargs):
    # 是有这样一个基础的反射方法的。
    
# Override (但在我们继承了 View 的类中,我们可以重载它试验一下)
from django.views import View
class User(View):
    def dispatch(self, request, *args, **kwargs):
        func = getattr(self, request.method.lower()) #必须要小写化不然映射不到我们刚才写的四个对应方法
        ret = func(self, request, *args, **kwargs)
        return ret

    # ...下面四个方法同上

所以,总结如下:

  • CBV:基于反射实现根据请求方式不同,执行不同的方法。

    原理:URL -> view方法 -> dispatch方法(反射执行其他:GET/POST/DELETE/PUT)

另外值得一提的是:自己那个类中的 dispatch 方法中如果不自己去映射而是调用父类(django 的 View)的 dispatch 方法,另外还在前后做一些附加操作,这样的功能跟 “装饰器” 就很相似了。

RESTful API 设计规范

RESTful 规范是一种建议而非硬性要求,但是在前后端分离是大趋势的当下,越来越多的程序员们开始喜欢遵照 RESTful 规范来设计后端接口。

一共有10个项目,那让我们一起来慢慢学习吧!

  1. API与用户的通信协议,总是使用HTTPS协议

    • 因为HTTPS比HTTP更加安全,所以在建立、部署大中型网站时企业都会选择使用HTTPS,但是由于HTTPS需要配置专门的证书,而如果需要具备较高的认可度的证书,则需要从证书商处购买,而价格大多不便宜。
  2. 域名配置要体现自己是个 API

  3. 后端API接口请区分版本

  4. 路径 -> 面向资源编程:

    何为面向资源编程呢?就是把互联网上的任何东西都视为一种资源,而我们在后端对该实体描述的 API 路由都为名词。

    而不是类似于 getUser、addUser 这样的动词!

    具体请看下一条 ...

  5. methods :HTTP方法

    始终记住 RESTful 设计要充分利用 HTTP协议里的 GET、POST、PUT、PATCH 和 DELETE 等 方法标志 来表达对数据的 增删改查

    • GET /collection:返回资源对象的列表(数组)
    • GET /collection/resource:返回单个资源对象
    • POST /collection:返回新生成的资源对象
    • PUT /collection/resource:返回完整的资源对象
    • PATCH /collection/resource:返回完整的资源对象
    • DELETE /collection/resource:返回一个空文档
  1. 对资源的条件过滤 -> 用 URL传参 来指定过滤条件

    类似于 例如查订单时 http://api.mall.com/orders?sortby=dectime 则是以按降序时间排列订单...

  2. 一定要使用 状态码

    常见的状态码:

    200 系列: 成功及其附属状态信息

    • 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
    • 201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
    • 202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
    • 204 NO CONTENT - [DELETE]:用户删除数据成功。
    • ...

300 系列:重定向类

  • 例如 301 MOVED PERMANENTLY
  • ...

400 系列 :客户端错误

  • 400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
  • 401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
  • 403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
  • 404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
  • 406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
  • 422 Unprocessable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  • ...

500 系列: 服务端错误

  • 500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
  • ...

单光用 HTTP状态码 在实际开发中是远远不够的哦!

一般还会加上一个我们自己的 code;

参见Alibaba Alipay支付宝文档:https://docs.open.alipay.com/common/105806 code( 返回码 )

这些自定义的返回码大大增加了我们能够表示的 服务对客户端请求的响应状态的类型。

由于状态码十分有限,所以一般前端大多会被要求处理 自定义的这个code。

  1. 错误处理

    承接上一个小段,当状态码是 4xx 时,应当返回错误信息,error 当做 key:

    {
        error:"Invalid API key!"
    }
    
  2. 以 API url 来确定返回类型!

    • GET /collection:返回资源对象的列表(数组)
    • GET /collection/resource:返回单个资源对象
    • POST /collection:返回新生成的资源对象
    • PUT /collection/resource:返回完整的资源对象
    • PATCH /collection/resource:返回完整的资源对象
    • DELETE /collection/resource:返回一个空文档

    这样干巴巴地说自然很难理解那个 collection 是什么意思:还是以订单举例:

    http://api.mall.com/orders/18924442 => orders 是复数(一般来说,数据库中的表都是同种记录的"集合"(collection),所以API中的名词也应该使用复数。),我的操作目标是 订单集合,而后面的 18924442(一个订单 id 示例)就代表着资源对象的实体 resource!

    那么我对这个 api url 的 post 、delete 、put / patch 和 get 就分别对应了该资源的 增删改查 接口。

  3. HypermediaAPI:

    即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

    比如:对于我正准备要实现的 RPZ计协 · 科丁特沃夫咖啡厅论坛 桌帖的评论列表 这件事情:

    • /coffeeComments?postid=12 第十二个咖啡桌帖的评论列表:
      [
          {
              id: '100030001',
              author: '飞翔的海猫',
              content: '你这个写的有bug呀!'
              datetime: '2019-01-19 22:10:35',
              likes: 0
              commentsList: 'https://api.sicnurpz.online/coffeeComments?commentid=100030001'
          }
      ]
      
    • 前面的都是 评论数据类型该有的基本信息比如 评论者的昵称、评论内容等,但为什么我要在最后加上一个 commentsList,还是个 url 地址字符串呢?

      因为这样我就不用再在服务端去拼接 查询该条评论的评论列表 的字符串了! 提高了后端接口处理的效率,在现代服务器存储量充足的情况下,数据存储空间 换 网络响应时间自然是不亏的啦!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容