RESTful API 规范 v1.0

本文作者:IMWeb 梁伟盛 原文出处:IMWeb社区 未经同意,禁止转载

RESTful API 规范 v1.0

[toc]

URI

URI规范

  • 不要用大写
  • 单词间使用下划线'_'
  • 不使用动词,资源要使用名词复数形式,如:user、rooms、tickets
  • 层级 >= 三层,则使用'?'带参数 users/1/address/2/citys (bad) /citys?users=1&address=2; (good)

Request

Method

  • GET:查询资源
  • POST:创建资源
  • PUT/PATCH
    • PUT:全量更新资源(提供改变后的完整资源)
    • PATCH:局部更新资源(仅提供改变的属性)
  • DELETE:删除资源

安全性与幂等性

  • 安全性:任意多次对同一资源操作,都不会导致资源的状态变化
  • 幂等性:任意次对同一资源操作,对资源的改变是一样的 |Method|安全性|幂等性| |------|:---:|:---:| |GET|√|√| |POST|×|×| |PUT|×|√| |PATCH|×|√| |DELETE|×|√|

兼容

很多客户只支持GET/POST请求,一般有两种方式模拟PUT等请求

  • 添加_method参数 /users/1?_method=put&name=111
  • 添加X-HTTP-Method-Override请求头 (我们使用这种方式) X-HTTP-Method-Override: PUT

参数

Method

GET
  • 非id的参数使用'?'方式传输 /users/1?state=closed POST、PATCH、PUT、DELETE
  • 非id的参数使用body传输,并且应该encode

过滤

?type=1&state=closed

排序

  • +升序,如?sort=+create_time,根据id升序
  • -降序,如?sort=-create_time,根据id降序

分页

?limit=10&offset=10

  • limit:返回记录数量
  • offset:返回记录的开始位置

单参数多字段

使用, 分隔,如

    /users/1?fields=name,age,city

版本控制

三种方案:

  1. 在uri中加入版本: /v1/room/1
  2. Accept Header:Accept: v1
  3. 自定义 Header:X-Imweb-Media-Type: imweb.v1 (我们使用此方案)

自定义Media-Type参考资料github

状态码

成功

Code

Method

Describe

200

ALL

请求成功并返回实体资源

201

POST

创建资源成功

客户端错误

Code

Method

Describe

400

ALL

一般是参数错误

401

ALL

一般用户验证失败(用户名、密码错误等)

403

ALL

一般用户权限校验失败

404

ALL

资源不存在(github在权限校验失败的情况下也会返回404,为了防止一些私有接口泄露出去)

422

ALL

一般是必要字段缺失或参数格式化问题

服务器错误

CODE

METHOD

DESCRIBE

500

ALL

服务器未知错误

以上是常见的状态码,完整的状态码列表在这状态码

HATEOAS

在介绍HATEOAS之前,先介绍一下REST的成熟度模型

在介绍 HATEOAS 之前,先介绍一下 Richardson 提出的 REST 成熟度模型。该模型把 REST 服务按照成熟度划分成 4 个层次:

  • 第一个层次(Level 0)的 Web 服务只是使用 HTTP 作为传输方式,实际上只是远程方法调用(RPC)的一种具体形式。
  • 第二个层次(Level 1)的 Web 服务引入了资源的概念。每个资源有对应的标识符和表达。
  • 第三个层次(Level 2)的 Web 服务使用不同的 HTTP 方法来进行不同的操作,并且使用 HTTP 状态码来表示不同的结果。如 HTTP GET 方法来获取资源,HTTP DELETE 方法来删除资源。
  • 第四个层次(Level 3)的 Web 服务使用 HATEOAS。在资源的表达中包含了链接信息。客户端可以根据链接来发现可以执行的动作。

简述

HATEOAS(Hypermedia as the engine of application state)是 REST 架构风格中最复杂的约束,也是构建成熟 REST 服务的核心。它的重要性在于客户端和服务器之间的解耦。

例子

分页

request请求,查询user,每页显示10条,从第10条开始显示(第二页)

    /users?limit=10&offset=10

response

    {
        data: {
            xxxx
        },
        meta: {
            _link: [
                {rel: 'self', href: 'xxx/users?limit=10&offset=10'},
                {rel: 'first', href: 'xxx/users?limit=10&offset=0', title: 'first page'},
                {rel: 'last', href: 'xxx/users?limit=10&offset=50', title: 'last page'},
                {rel: 'prev', href: 'xxx/users?limit=10&offset=0', title: 'prev page'},
                {rel: 'next', href: 'xxx/users?limit=10&offset=20', title: 'next page'}
            ]
        }    
    }

_link返回了5个资源

  • rel: 'self',资源本身
  • rel: 'first',第一页资源
  • rel: 'last',最后一页资源
  • rel: 'prev',上一页资源
  • rel: 'next',下一页资源

权限相关

如用户查询一个订单

普通用户

request

    /orders/1

response

    {
        data: {
            xxx
        },
        meta: {
            _link: [
                {rel: 'self', href: 'xxx/orders/1'},
                {rel: 'related', href: 'xxx/orders/1/payment', title: 'pay the order'}
            ]
        }
    }

_link返回两个资源

  • rel: 'self',资源本身
  • rel: 'related',与当前资源相关的资源,/order/1/payment用户可以使用此资源进行支付

权限用户

request

    /orders/1

response

    {
        data: {
            xxx
        },
        meta: {
            _link: [
                {rel: 'self', href: 'xxx/orders/1'},
                {rel: 'edit', href: 'xxx/orders/1', title: 'edit the order'},
                {rel: 'delete', href: 'xxx/orders/1', title: 'delete the order'}
            ]
        }
    }

此用户拥有修改与删除订单的权限,因此返回了3个资源

  • rel: 'self',资源本身
  • rel: 'edit',此用户可修改该资源
  • rel: 'delete',此用户可删除该资源

常用rel

rel

describe

self

资源本身,每个资源表述都一个包含此关系

edit

指向一个可以编辑当前资源的链接

delete

指向一个可以删除当前资源的链接

item

如果当前资源表示的是一个集合,则用来指向该集合中的单个资源

collection

如果当前资源包含在某个集合中,则用来指向包含该资源的集合

related

指向一个与当前资源相关的资源

first、last、prev、next

分别用来指向第一个、最后一个、上一个和下一个资源

HATEOAS总结

由以上例子可以看出_link就是以Hyperlink表述资源与资源之间的关系,这种方式使客户端与服务端能很好的分离开来,只要接口的定义不变,客户端与服务端就可以独立的开发和演变。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏武军超python专栏

2018年8月5日对之前学习python中的问题总结

问题: linux中whereis和which的区别: whereis python     which python whereis是一个文件查找命令,...

10450
来自专栏软件开发 -- 分享 互助 成长

linux下进程相关操作

一、定义和理解 狭义定义:进程是正在运行的程序的实例。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。 进程的概念主要有两点: 第一...

25650
来自专栏人人都是极客

Linux 程序编译过程的来龙去脉

大家肯定都知道计算机程序设计语言通常分为机器语言、汇编语言和高级语言三类。高级语言需要通过翻译成机器语言才能执行,而翻译的方式分为两种,一种是编译型,另一种是解...

26630
来自专栏大魏分享(微信公众号:david-share)

实战:Bean的数据完整性验证方法| 从开发角度看应用架构11

Java应用程序将数据存储在Java对象中。这些Java对象通过网络,作为参数传递给方法,并存在于Java EE应用程序的不同层中。为了保持数据完整性,数据验证...

14530
来自专栏张戈的专栏

Linux运维工程师:30道面试题整理

前段时间,我在准备面试的时搜到的一套 Linux 运维工程师面试题,感觉比较全面,一直保存在草稿,刚在整理后台时翻了出来,干脆就发出来好了,以备不时之需。 1....

2.2K50
来自专栏PHP在线

PHP的错误机制总结

PHP的错误机制也是非常复杂的,做了几年php,也没有仔细总结过,现在就补上这一课。

24450
来自专栏大内老A

WCF技术剖析(卷1)之目录

第1章  WCF简介 (WCF Overview)     1.1  SOA基本概念的和设计思想        1.2  WCF是对现有Windows平台下...

23280
来自专栏顶级程序员

Java Web前端到后台常用框架介绍

来源: 小宝鸽 - CSDN博客 链接: http://blog.csdn.net/u013142781/article/details/50922010 一...

61270
来自专栏丑胖侠

Zookeeper开源客户端Curator之Master/Leader选举

在实际生产中,特别是分布式系统中,我们经常遇到这样的场景:一个复杂的任务,近需要从分布式机器中选出一台机器来执行。诸如此类的问题,我们统称为“Master选举”...

439100
来自专栏闵开慧

tomcat6.0下找不到jasper-runtime.jar

今天有点需求,需要用jasper-runtime.jar包。但是我在我的\apache-tomcat-6.0.16\lib目录下,怎么也找不到这个jar包。结果...

34850

扫码关注云+社区

领取腾讯云代金券