我认为一套接口应该尽量满足以下几个原则:

  • 安全可靠,高效,易扩展。
  • 简单明了,可读性强,没有歧义。
  • API 风格统一,调用规则,传入参数和返回数据有统一的标准。

我们当然可以根据自己的经验,或者参考知名公司的接口总结设计出一套满足要求的接口,但是每个人对接口的理解不同,设计出来的接口也会有所不同,接口的命名,请求参数的格式,响应的结果,错误响应的错误码,等等很多地方都会有不一样的实现。当你去寻求一种设计理念来帮助我们设计出满足要求的接口,一定会发现 RESTful。
RESTful 的设计理念基于 HTTP 协议,因为 Roy Fielding 就是 HTTP 协议(1.0 版和 1.1 版)的主要设计者。它是一种设计风格,没有规定我们一定如何实现,但是为我们提供了很好的设计理念。风格的统一,使得我们不需要过多的解释,就能让使用者明白该如何使用,同时也会有很多现成的工具来帮助我们实现 RESTful 风格的接口。

RESTful 设计原则

1.HTTPS

HTTPS 为接口的安全提供了保障,可以有效防止通信被窃听和篡改。而且现在部署 HTTPS 的成本也越来越低,你可以通过 certbot 等工具,方便快速的制作免费的安全证书,所以生产环境,我们使用了 HTTPS。

2.域名

应当尽可能的将 API 与其主域名区分开,可以使用专用的域名,访问我们的 API,例如:api.exeedcars.com。甲方申请域名太过于麻烦,所以这边我们使用https://bbs.exeedcars.com/api/代替

3.版本控制

随着业务的发展,需求的不断变化,API 的迭代是必然的,很可能当前版本正在使用,而我们就得开发甚至上线一个不兼容的新版本,为了让旧用户可以正常使用,为了保证开发的顺利进行,我们需要控制好 API 的版本。
我们的接口比较少所以直接将版本号直接加入 URL 中,例如:
https://bbs.exeedcars.com/api/v1/
https://bbs.exeedcars.com/api/v2/

4.用 URL 定位资源

先来看看 github 的 例子:
GET /issues 列出所有的 issue
GET /orgs/:org/issues 列出某个项目的 issue
GET /repos/:owner/:repo/issues/:number 获取某个项目的某个 issue
POST /repos/:owner/:repo/issues 为某个项目创建 issue
PATCH /repos/:owner/:repo/issues/:number 修改某个 issue
PUT /repos/:owner/:repo/issues/:number/lock 锁住某个 issue
DELETE /repos/:owner/:repo/issues/:number/lock 解锁某个 issue

5.用 HTTP 动词描述操作


来看看参考例子我们写的部分路由

6.资源过滤

我们需要提供合理的参数供客户端过滤资源,例如:
?state=closed: 不同状态的资源
?page=2&per_page=100:访问第几页数据,每页多少条。
?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序。
为了让我们的接口更灵活,除了简单的资源过滤以外,我们还需要知道客户端具体需要哪些数据,如果客户端只是显示一下所有话题的标题,但是接口却返回了所有相关的数据,不仅做了额外的查询,还增加了响应的数据。
在这里用了一个很好用的扩展包来实现:spatie/laravel-query-builder
我写了一个公用查询构造器如下:

路由解析:

控制器:

使用效果:

到这里我们就可以按需加载需要的数据了。

7.正确使用状态码

HTTP 提供了丰富的状态码供我们使用,正确的使用状态码可以让响应数据更具可读性。

  • 200 OK - 对成功的 GET、PUT、PATCH 或 DELETE 操作进行响应。也可以被用在不创建新资源的 POST 操作上
  • 201 Created - 对创建新资源的 POST 操作进行响应。应该带着指向新资源地址的 Location 头
  • 202 Accepted - 服务器接受了请求,但是还未处理,响应中应该包含相应的指示信息,告诉客户端该去哪里查询关于本次请求的信息
  • 204 No Content - 对不会返回响应体的成功请求进行响应(比如 DELETE 请求)
  • 304 Not Modified - HTTP 缓存 header 生效的时候用
  • 400 Bad Request - 请求异常,比如请求中的 body 无法解析
  • 401 Unauthorized - 没有进行认证或者认证非法
  • 403 Forbidden - 服务器已经理解请求,但是拒绝执行它
  • 404 Not Found - 请求一个不存在的资源
  • 405 Method Not Allowed - 所请求的 HTTP 方法不允许当前认证用户访问
  • 410 Gone - 表示当前请求的资源不再可用。当调用老版本 API 的时候很有用
  • 415 Unsupported Media Type - 如果请求中的内容类型是错误的
  • 422 Unprocessable Entity - 用来表示校验错误
  • 429 Too Many Requests - 由于请求频次达到上限而被拒绝访问
    在响应数据格式里面我们配置好HTTP状态码输出
    8.响应数据格式
    考虑到响应数据的可读性及通用性,默认使用 JSON 作为数据响应格式。
    对于错误数据,仅仅是HTTP状态码是不够的,还需要具体的错误code,默认使用如下结构:

例如:

首先我在公共controller里面定义

然后我们统一定义报错code

Try catch的时候调用

9.调用频率限制

为了防止服务器被攻击,减少服务器压力,需要对接口进行合适的限流控制,需要在响应头信息中加入合适的信息,告知客户端当前的限流情况
X-RateLimit-Limit :100 最大访问次数
X-RateLimit-Remaining :93 剩余的访问次数
X-RateLimit-Reset :1513784506 到该时间点,访问次数会重置为 X-RateLimit-Limit

超过限流次数后,需要返回 429 Too Many Requests 错误。
我们先定义不同情况的调用频次参数新建 /config/api.php配置

然后使用频率限制中间件直接在route里面定义


10.编写文档

为了方便用户使用,我们需要提供清晰的文档,尽可能包括以下几点

  • 包括每个接口的请求参数,每个参数的类型限制,是否必填,可选的值等。
  • 响应结果的例子说明,包括响应结果中,每个参数的释义。
  • 对于某一类接口,需要有尽量详细的文字说明,比如针对一些特定场景,接口应该如何调用。
    接口目前直接放在apipost上面方便调试,后续考虑通过swagger-php直接由代码注释生产接口文档还能在线调试,这样的好处第一是方便其他阅读源码,理解每个接口的用处。第二是源码和接口文档都在一起,方便管理。

11.Laravel相关技巧

Laravel框架写接口的话,不得不提到API资源类,Laravel 的资源类能够让你以更直观简便的方式将模型和模型集合转化成 JSON。Laravel 的资源类能够让你以更直观简便的方式将模型和模型集合转化成 JSON。

使用资源的时候,我们有时候需要不同的情况下过滤某些参数,比如说我的个人信息和某个用户的个人信息接口都用到了User资源类,这个时候我们可以在资源类中定义个开关就可以简单实现。

调用的时候设置是否显示即可

API开发中就如何提高接口优雅性的理论实践相关推荐

  1. Android 开发中调用google语音接口

    最近项目开发中需求中要采用多种的输入方式,于是乎想起google的语音搜索做了一下尝试,做了一个简单的语音识别的demo,总结起来,大致的过程如下: 一.检查Androird手机上是否装上了googl ...

  2. 开发中是如何保证接口幂等性的?

    文章目录 一.定义 二.业务场景 三.保证幂等性常用方法 方案1: insert前先select(基于mysql的分布式锁) 方案2:加悲观锁 select * from table where id ...

  3. 开发中不可轻视的接口文档

    接口文档是描述如何与软件系统中的特定接口进行交互的文档,通常包含接口的名称.描述.请求和响应的格式.参数.返回值.错误码.调用示例等信息.它是开发人员在设计和开发软件系统时必不可少的参考资料. 日常工 ...

  4. oracle web API,在Web API程序中使用Swagger做接口文档

    #### 创建Web API程序 在VS2019中创建一个ASP.NET Web应用程序,选择Web API来创建RESTful的HTTP服务项目,构选MVC和Web API核心引用. #### 安装 ...

  5. Java网页开发中model实现Serializable接口的原因

    Object serialization的定义: Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原 ...

  6. 详解CentOS 7中RAID 6与RAID 10配置(理论+实践)

    RAID 6介绍 RAID6 是在RAID5 的基础上改良而成的,RAID6 再将数据校验位增加一位,所以允许损坏的硬盘数量也由 RAID5的一个增加到二个.由于同一阵列中两个硬盘同时损坏的概率非常少 ...

  7. Java开发中使用模拟接口moco响应中文时乱码

    场景 在开发中需要依赖一些接口,比如需要请求一个返回Json数据的接口,但是返回Json数据的接口要么是没搭建,要么是交互比较复杂. 此时,就可以使用moco来模拟接口返回接口数据,以便开发和测试工作 ...

  8. Java开发中模拟接口工具moco的使用

    场景 在开发中需要依赖一些接口,比如需要请求一个返回Json数据的接口,但是返回Json数据的接口要么是没搭建,要么是交互比较复杂. 此时,就可以使用moco来模拟接口返回接口数据,以便开发和测试工作 ...

  9. GitHub 优秀的 Android 开源项目 淘宝技术牛p博客整理开发中最常用的GitHub上 优秀的 Android 开源项目整理(精品)...

    原文地址为http://www.trinea.cn/android/android-open-source-projects-view/,作者Trinea 主要介绍那些不错个性化的View,包括Lis ...

最新文章

  1. 从工业云到工业互联网平台演进的五个阶段
  2. 牛逼!Redis 的字符串是这样实现的…
  3. tms570 can 接收大量数据_CAN通讯系列--AUTOSAR架构的CAN Interface7
  4. ecshop根目录调用_ecshop列表页 调用二级分类教程
  5. 剖析亿级请求下的多级缓存
  6. Linux文件默认权限和umask笔记
  7. 通过微型计算机的电流,单板微型计算机控制的电流型变频调速系统
  8. python四种方法实现去除列表中的重复元素
  9. 玩客币如何转账如何交易链克
  10. 基于Renascence架构的SQL查询引擎设计
  11. cf1163B2. Cat Party (Hard Edition)(简单总结一下map数据结构的简单方法)
  12. 风行 词:许巍 摄影:小虫子
  13. 下面哪个不是python常用的开发工具_Python程序员常用的IDE和其它开发工具
  14. 【渝粤教育】 广东开放大学 21秋期末考试大学英语210262k2
  15. cas66-71-7|1,10-菲啰啉有机配体/ 1,10-Phen/邻菲啰啉/邻二氮杂菲
  16. 商业智能BI的未来,如何看待AI+BI这种模式?
  17. [数据结构与算法]输出1~10000中的对称数
  18. 计算机光驱硬盘分区,深入隐藏光驱(磁盘分区)
  19. css 铺满父元素的最好用的一种方式
  20. 我所认识的BIMRevit

热门文章

  1. 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数。
  2. Matlab在最优化计算中的应用
  3. C/C++ 中的次方运算
  4. SGL8022W单通道直流LED 灯光控制触摸芯片
  5. java 中的extends_java中? extends T 和? super T解析
  6. adb 抓取logcat 日志
  7. VisualGDB 5.6 r4 Retail
  8. 细数小程序获量的6种方式和常见问题
  9. Android Studio安装与App开发步骤详解
  10. 呕心沥血之作-----线性代数总结(1)--行列式基础