对接口规范的一些思考

更新日期: 2019-05-29 阅读: 2.7k 标签: 规范

起因

团队中如果不同的项目,不同的人员可能在接口设计上有许多不统一的地方。导致了开发效率低下的问题。
由于我在工作中遇到了,所以整理下来,说一说自己的一些看法。


怎样进行接口规范化

因为每个人对自己使用语言有不同的理解、HTTP协议熟悉程度不同、思维逻辑、开发经验不一样。对接口规范有想法的人应该提出自己的观点,给出自己的理由。让别人去评价,讨论出一套统一的规则,最终统一成一个内部的标准。
形成统一标准后由相关人员写出示例。例如前端要对GET请求针对jquery.ajax、fetch、axios等请求库给出示例代码。以后直接参照示例代码进行开发。

由于每个项目在定义接口时有许多不同的方式,我根据以往的经验,从请求方法、请求头、请求体、响应状态码、响应体等几个方面对接口的规范说说自己的看法。


我对标准的理解

我们不同的项目使用的请求方式大概有两种:

  • GET、POST
  • GET、POST、PUT、DELETE

如果使用前者,PSOT的URL中应该指明要执行的动作,而后者不需要指定。

POST /api/user/add HTTP/1.1
POST /api/user/set HTTP/1.1
POST /api/user/delete HTTP/1.1

# 这里例子中约定PUT是新增,POST是修改
POST /api/user HTTP/1.1
PUT /api/user HTTP/1.1
DELETE /api/user HTTP/1.1

至于使用前者还是后者,我更倾向于前者。
如果使用后者时,什么情况下使用PSOT、什么情况下使用PUT,搜索到了到了一些资料,但看不懂。


接口URL

接口URL应该见名知意,有一定的规律。
这里我不太懂,就不做过多赘述。


数据类型的约定

前端请求中不应该有undefined,因为后端不支持(json也不支持)该数据类型。
如果Content-Type为multipart/form-data,前端不应该传null,因为会被转化成字符串,后端不能判断出这是用户输入还是null类型。

每个项目应该约定请求时下面这些数据代表什么意思

  • null数据类型表示什么
  • 空字符串类型表示什么


GET请求

作用

GET请求应该读取数据,不应该产生任何的“副作用”操作。
这里要注意一点浏览器URL长度是有限制的,如果查询的URL长度过长会引起不可预期的后果。可以采用POST/PUT进行查询。

方式

GET请求的参数应该放在请求的URL中而不应该放在请求体中。
例如下面是一个标准的这个GET请求(不相关HTTP头字段已剔除)

GET /api/user?userId=12345 HTTP/1.1
Host: http://www.example.com


POST/PUT/DELETE请求

这三种请求方法传参数格式都相同,下面以POST为例。
POST类型使用的方式非常多样,见识过各种各样奇葩的方式,也是耽误时间最长的,严重影响开发进度。这里只讨论我认为标准的方式。

作用

POST请求用于新增、修改或删除数据,少数情况下用于查询数据。

方式

POST请求的参数必须放在请求体中。
而POST的请求方式有四种方式

  • application/x-www-form-urlencoded
  • multipart/form-data
  • application/json
  • text/xml

这几种方式通过HTTP头中的Content-Type头字段进行控制。

multipart/form-data

我们现在使用的最多的是multipart/form-data。

POST /api/user/set HTTP/1.1
Host: http://www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2KbanAZwv0mKceX0

------WebKitFormBoundary2KbanAZwv0mKceX0
Content-Disposition: form-data; name="userName"

张三
------WebKitFormBoundary2KbanAZwv0mKceX0
Content-Disposition: form-data; name="userId"

123456
------WebKitFormBoundary2KbanAZwv0mKceX0--

这种方式不适合复杂数据类型的传递,例如有个接口需要同时修改多个用户:

const userList = [
  {
    userID: 123,
    userName: '张三',
    isAdmin: true,
  }, {
    userID: 456,
    userName: '李四',
    isAdmin: false,
  },
];

那么在POST请求时只能这么做

POST /api/userlist/set HTTP/1.1
Host: http://www.example.com
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary2KbanAZwv0mKceX0

------WebKitFormBoundary2KbanAZwv0mKceX0
Content-Disposition: form-data; name="userID"

123,456
------WebKitFormBoundary2KbanAZwv0mKceX0
Content-Disposition: form-data; name="userName"

张三,李四
------WebKitFormBoundary2KbanAZwv0mKceX0
Content-Disposition: form-data; name="isAdmin"

1,0
------WebKitFormBoundary2KbanAZwv0mKceX0--

更重要的是这种方式不支持数据类型,传入的所有格式的数据都会转成字符串类型。后端经常要使用1表示true,需要将数组或对象拆分开。

application/json

这是我推荐使用的方式,有效的弥补了multipart/form-data的缺陷。
但不知什么原因现在我们团队基本不使用这种方式。
application/json也有一个缺陷就是不支持上传文件(有特殊的方法这里也不建议使用),想上传文件还是使用multipart/form-data。

下面是请求示例

POST /user HTTP/1.1 
Host: http://www.example.com
Content-Type: application/json;charset=utf-8

[{"userID":123,"userName":"张三","isAdmin":true},{"userID":456,"userName":"李四","isAdmin":false}]


响应

不知道服务器对于不同的处理会返回什么样的状态码,这里不做讨论。
我们会返回一个逻辑状态码code与提示信息msg,响应体像下面这样。

{"code":200,"msg":"处理成功!","data":{}}

在此基础上增加一些限制:

建议data字段始终为对象类型

易于扩展,例如当前接口是用户列表页,data使用数组。v2版本接口加入了分页查询,就必须使data变为对象类型了。

如果字段为复杂类型,不允许为null

复杂类型包括数组与对象。
为了方便阅读,这里将json字符串转化为了JS对象。

const resBody = {
  code: 200,
  msg: '处理成功',
  data: {
    list: [
      {
        userID: 123,
        userName: '张三',
      },
    ],
  },
};

如果没有数据的时候返回

const resBody = {
  code: 200,
  msg: '处理成功',
  data: {
    list: null,
  },
};

这样前端在遍历list时,null会导致代码出错,应该始终保证该字段的数据类型不变,正确返回方式如下。

const resBody = {
  code: 200,
  msg: '处理成功',
  data: {
    list: [],
  },
};

原文来自:https://github.com/TheNorthWindRises/blog/issues/2


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/3474

相关推荐

什么是驼峰命名?骆驼式命名法规范

骆驼式命名法(Camel-Case)又称驼峰式命名法,是电脑程式编写时的一套命名规则(惯例)。正如它的名称CamelCase所表示的那样,是指混合使用大小写字母来构成变量和函数的名字

web开发,前后分离接口规范

目前我们现在用的前后端分离模式属于第一阶段,下一阶段可以在前端工程化方面,对技术框架的选择、前端模块化重用方面,可多做考量。也就是要迎来“==前端为主的 MV* 时代==”。

CSS规范

CSS 指层叠样式表 (Cascading Style Sheets),定义如何显示 HTML 元素,但由于 CSS 天生全局性,随着项目复杂度增加,极易出现样式覆盖以及其它的问题。

前端变量命名规范

程序开发过程中变量命名不仅是一个头疼问题,也是一个对开发者综合素质的检验,它会直接影响到代码的最终交付质量、代码Review人员心智承受力。如何写出具有创造性、优雅性、易读性的高质量代码,需要开发者在实际工作中不断总结、提炼

js中箭头函数的编码规范,如何更好的使用箭头函数

当您必须使用匿名函数,请使用箭头函数表示法,它创建了一个在 this 上下文中执行的函数的版本,这通常是你想要的,而且这样的写法更为简洁。如果你有一个相当复杂的函数,你或许可以把逻辑部分转移到一个声明函数上。

Web前端开发规范手册

文件命名规则:文件名称统一用小写的英文字母、数字和下划线的组合。引文件统一使用index.htm index.html index.asp文件名(小写),图片的名称分为头尾两部分,用下划线隔开,头部分表示此图片的大类性质

W3C标准及规范

W3C的意思是万维网联盟(World Wide Web Consortium),创建于1994年10月,是一个会员组织,它的工作是对web进行标准化--->W3C 致力于实现所有的用户都能够对 web 加以利用

web前端js中ES6的规范写法

引号的使用,单引号优先(如果不是引号嵌套,不要使用双引号)、空格的使用问题:(关键字后 符号后 排版 函数 赋值符号= )等、不写没有使用过的变量,如果定义了一个变量,后来一直没有参与过运算,那么不应该定义这个变量...

JavaScript 命名约定最佳实践

在开发过程中,遵循标准的命名约定可以提高代码的可读性。下面就来看看 JavaScript 中命名约定的最佳实践。JavaScript 变量名称是区分大小写的,大写和小写字母是不同的。

用standard来管理JavaScript 代码规范

standard是一个开源的JS代码规范库,制定了所谓standard(标准)的JS代码规范,配合编辑器插件可以实时检查代码规范以及语法错误,通过执行命令检查代码规范以及语法错误,自动修复(可以直接修复的)不合规范的代码,使其符合规范

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!