1.14.1 统一返回的格式

很明显地,默认情况下,我们选择了 JSON 作为统一的格式返回接口结果。这里简单说明一下选取JSON统一返回的原因:

  • JSON当前很流行,且普通接口都采用此格式返回
  • JSON在绝大部分开发语言中都支持,跨语言
  • JSON在浏览器浏览时,有可视化插件支持,如FF下:

1.14.2 统一返回结构

通常,我们正常情况下请求接口会返回类似:

 1 {
 2     "ret": 200,
 3     "data": {
 4         "title": "Default Api",
 5         "content": "PHPer您好,欢迎使用PhalApi!",
 6         "version": "1.1.0",
 7         "time": 1423142802
 8     },
 9     "msg": ""
10 }

其中,ret表示为返回状态码,200表示成功;data为领域业务数据,由接口自定义;最后msg为错误的提示信息。下面分别解释之。

(1)返回状态码 ret

参照HTTP的状态码,特约定:

  • 200:接口正常请求并返回
  • 4XX:客户端非法请求
  • 5XX:服务器运行错误

200 正常返回

当返回200时,需要同时返回data部分数据,以便客户端实现所需要的业务功能。

4XX 客户端非法请求

此类请求是由客户端不正确调用引起的,如请求的接口服务不存在,或者接口参数不对,验证失败等等。当这种情况发生时,客户端同学只需要调整修正调用即可。

对于此系统的状态码,在进行接口开发时,可由项目自已定义约定。 通常地,我们需要告知客户端签名失败时,可以这样:

throw new PhalApi_Exception_BadRequest('wrong sign', 1);

即抛出PhalApi_Exception_BadRequest异常即可,错误信息会返回客户端,对应msg字段;状态为1,系统对此类的异常会在400基础上相加的,即:401 = 400 + 1 。

5XX 服务器运行错误

此类错误是应该避免的,但当客户端发现有这种情况时,应该知会后台接口开发人员进行修正。
如当配置的参数规则不符合要求时,或者获取了不存在的参数等即会触发此类异常错误,通常由框架抛出。

(2)业务数据 data

data为接口和客户端主要沟通对接的数据部分,可以为任何类型,由接口自定义。但为了更好地扩展、向后兼容,建议都使用array。

返回格式的定义与在线查看

当我们在开发接口时,可以通过为接口添加注释的方式来定义接口的返回格式,然后就可以为外部提供在线文档的实时查看了。

如:

 1 <?php
 2
 3 class Api_User extends PhalApi_Api {
 4
 5     /**
 6      * 获取用户基本信息
 7      * @desc 用于获取单个用户基本信息
 8      * @return int code 操作码,0表示成功,1表示用户不存在
 9      * @return object info 用户信息对象
10      * @return int info.id 用户ID
11      * @return string info.name 用户名字
12      * @return string info.note 用户来源
13      * @return string msg 提示信息
14      */
15     public function getBaseInfo() {
16         // ... ...
17     }

然后在浏览器访问:
http://demo.phalapi.net/checkApiParams.php?service=User.getBaseInfo

可以看到:

注释格式

格式是以docs的 return 注释来标明的,其格式为:

@return  返回的类型  字段名字路径(以点号连接)  字段名字及解析

其中,返回的类型可以为:

关键字 说明
string 字符串
int 整型
float 浮点型
boolean 布尔型
date 日期
array 数组
fixed 固定值
enum 枚举类型
object 对象

温馨提示:array与object的区别
array是指没有下标的一个数组集合,或者有下标但下标是连续的自然数,且各元素的结构相同;object则是指一个结构体,类似字典。

此外,为了明确数组与对象间的返回格式,我们也推荐如果是元素来自数组,则在返回字段的后面添加方括号来表明,以提醒客户端在接收到此类返回时需要循环处理。如:

     * @return array list 用户列表* @return int list[].id 用户ID* @return string list[].name 用户名字* @return string list[].note 用户来源

当需要对接口进行更多说明时,可使用@desc注释,即:

     * @desc 用于获取单个用户基本信息

(3)错误信息 msg

当返回状态码不为200时,此字段不为空。即当有异常(如上面所说的客户端非法请求和服务端运行错误两大类)触发时,会自动将异常的错误信息作为错误信息msg返回。

但对于服务端的异常,出于对接口隐私的保护,框架在错误信息时没有过于具体地描述;相反,对于客户端的异常,由会进行必要的说明,以提醒客户端该如何进行调用调整。

此外,我们根据需要可以考虑是否需要进行国际化的翻译。如果项目在可预见的范围内需要部署到国外时,提前做好翻译的准备是很有帮助的。如下,开发时可以这样返回异常错误信息:

throw new PhalApi_Exception_BadRequest(T('wrong sign'), 1);

1.14.3 关于Exception类异常没捕捉的原因

我们没有对Exception类的异常进行捕捉,封装返回非200的形式,是因为我们出于以下的考虑:

  • 一来为了方便开发过程中快速发现及定位具体出错的位置;
  • 二来为了便于线上环境中nginx服务器对错误的捕捉和纪录;

1.14.4 JsonP格式和其他的返回

在部分H5页面异步请求的情况下,客户端需要我们返回JSONP格式的结果,则可以这样在入口文件重新注册response:

if (!empty($_GET['callback'])) {DI()->response = new PhalApi_Response_JsonP($_GET['callback']);
}

但是在测试环境中,我们是不希望有内容输出的,所以我们可以测试时这样注册response:

DI()->response = 'PhalApi_Response_Explorer';

1.14.5 扩展你的返回格式

当你的项目需要返回其他格式时,如返回XML,则可以先这样实现你的格式类:

class MyResponse_XML extends PhalApi_Response {protected function formatResult($result) {//TODO:把数组$result格式化成XML ...}
}

随后,也是简单重新注册一下即可:

DI()->response = 'MyResponse_XML';

1.14.6 各状态码产生的时机

1.14.7 更好地建议

很多时候,很多业务场景,客户端在完成一个接口请求并获取到所需要的数据后,需要进行不同的处理的。

  • 就登录来说,当登录失败时,可能需要知道:
  • 是否用户名不存在?
  • 是否密码错误?
  • 是否已被系统屏蔽?
  • 是否密码错误次数超过了最大的重试次数?
  • ...

显然,这里也有一个返回状态码,更准备来说,是业务操作状态码。并且,此类的状态依接口不同而不同,很难做到统一。

SO?

我们建议的是,项目接口在业务数据data里面统一再定义一个状态码,通常为code字段,完整路径即: data.code ,同时为0时表示操作成功,非0时为不同的失败场景。如上面的登录:

  • code = 0 登录成功
  • code = 1 用户名不存在
  • code = 2 密码错误
  • code = 3 系统已屏蔽此账号
  • code = 4 密码错误次数超过了最大的重试次数
  • ...

最后,客户端在获取到接口返回的数据后,先统一判断ret是否正常请求并正常返回,即ret = 200;若是,则再各自判断操作状态码code是否为0,如果不为0,则提示相应的文案并进行相应的引导,如果为0,则走正常流程!

1.14.8 领域特定设计与Fiat标准

在《RESTful Web APIs》一书中提及到,标准可以划归到4个分类,分别是:fiat标准、个人标准、公司标准以及开放标准。

显然,我们这里推荐的是 JSON + ret-data-msg 返回格式既不是个人标准,也不是公司标准(就笔者观察的范筹而言,未发现某个公司定义了此格式)。而且,也不属于开放标准,因为也还没达到此程度。更多的,它是fiat标准。
我们很容易发现,身边的应用、系统以及周围项目都在使用诸如此类的返回结构格式,如一些AJAX的接口。

当然,我们可希望可以消除语义上的鸿沟,以便在后台接口开发上有一个很好地共识。

同时,JSON + ret-data-msg 返回格式也是一种领域特定的格式,它更多是为app多端获取业务数据而制作的规范。虽然它不是很完美,不具备自描述消息,也没有资源链接的能力,但我们认为它是一种恰到好处的格式。
在基于JSON通用格式的基础上,加以 ret-data-msg 的约束,它很好地具备了统一性,可能门槛低,容易理解。

//接口请求格式
http://dev.phalapi.com/demo/?service=User.GetBaseInfo&user_id=帐号ID//返回结果格式
 1 {
 2     "ret": 200,
 3     "data": {
 4         "code": 0,    //状态码,0表示正常获取,1表示用户不存在
 5         "msg": "",
 6         "info": {      //用户信息
 7             "id": "1",    //用户ID
 8             "name": "dogstar",   //帐号
 9             "note": "oschina"   //来源
10         }
11     },
12     "msg": ""
13 }

原地址:http://blog.csdn.net/baple/article/details/52925772

 

 

转载于:https://www.cnblogs.com/cuculus/articles/6961820.html

(转) 服务接口统一返回的格式相关推荐

  1. 微服务架构之公共模块式中创建API接口统一返回结果ApiResult

    微服务架构之API接口统一返回结果ApiResult 一.创建公共模块common步骤 二.在api中新建一个ApiCode枚举和ApiResult 三.ApiCode与ApiResult编码如下 四 ...

  2. Java设计API 接口统一返回格式

    前言 在移动互联网,分布式.微服务盛行的今天,现在项目绝大部分都采用的微服务框架,前后端分离方式. 一般系统的大致整体架构图如下: 本篇关注点为API接口,所以架构图有所不同 接口交互 前端和后端进行 ...

  3. rss spring 接口_spring 接口支持返回多种格式

    1. 简介 本文介绍使用SpringMVC的后端服务如何通过配置来支持多种返回值类型(xml,json,html,excel) 这里的代码使用的是springboot,下载地址:https://git ...

  4. 后台接口统一返回类型-ResponseBodyAdvice

    思路 1.自定义一个注解@ResponseResult用于在方法或者类上面标注,标识这个接口需要包装数据 2.拦截请求.判断此请求是否被@ResponseResult注解标注 3.实现接口Respon ...

  5. SSM8==纯注解SSM项目:实现单表CRUD、事务、自定义异常和统一异常处理、RESTFUL风格接口、统一返回值格式(状态码、内容、消息)、JSON传参、axios、vue.js、elementUI

    环境:IDEA2021+JDK8+MAVEN3.8+TOMCAT7插件 前端:axios.vue.js.elementUI 后端:见POM.XML相关依赖,主要有数据库MySQL5.7 ,数据源Dru ...

  6. 基于Qt的音乐播放器(三)通过酷狗音乐的api接口,返回json格式歌曲信息(播放地址,歌词,图片)

    2020博客之星年度总评选进行中:请为74号的狗子投上宝贵的一票! 我的投票地址:点击为我投票 文章目录 前言 1.获取歌曲搜索列表api接口 2.获取单个歌曲详细信息包括歌词 3.总结 前言 首先说 ...

  7. 浅谈后端接口统一及原理

    背景 目前鉴于前后端分离开发的流行,现在需要对后端接口返回json数据格式,做统一规范处理 特性要求 要求后端接口统一返回以下格式 {"code": "SUC0000&q ...

  8. Spring Boot 无侵入式 实现 API 接口统一 JSON 格式返回

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 无侵入式 统一返回JSON格式 其实本没有没打算写这篇博客 ...

  9. Spring Boot 无侵入式 实现API接口统一JSON格式返回

    作者 | 小魏小魏我们去那里呀 来源 | blog.csdn.net/qq_34347620/article/details/102239179 无侵入式 统一返回JSON格式 其实本没有没打算写这篇 ...

最新文章

  1. python下载pip脚本显示file_generateScriptFile.py脚本使用过程中遇到的问题及解决
  2. 3-8 译码器设计实验--VHDL
  3. IPv6 HSRP协议
  4. SpringMVC整合百度富文本编辑器
  5. 房价必然上涨的N个原因
  6. 极坐标t1t2几何意义_关于极坐标
  7. argmin函数解析
  8. 瑞星杀毒软件卸载方法
  9. 为何会频繁收到垃圾短信?使用这3种方法,跟垃圾短信说再见
  10. 卡内基梅隆大学计算机专业介绍,卡内基梅隆大学计算机专业介绍 全美大学计算机专业榜首...
  11. Python test1
  12. U盘启动安装CentOS Linux系统
  13. android activity 实际,如何整合Zxing条形码扫描器而不安装实际的zxing应用程序(无法解析符号:.android.CaptureActivity)?...
  14. 国际结算模拟试题及答案
  15. 推荐使用:易企在线客服升级版
  16. SAP CO 成本的分配
  17. 架构师必备:云原生数据湖体系
  18. jsp成绩分析管理系统myeclipse编程java语言sqlserver数据库
  19. 网络机房搬迁的实施与经验
  20. SDN系统方法 | 8. 网络虚拟化

热门文章

  1. 登录mysql出现/var/lib/mysql/mysql.sock不存在
  2. BZOJ 1114 Number theory(莫比乌斯反演+预处理)
  3. 开涛spring3(2.1) - IoC基础
  4. 数据类型,运算符和表达式03 - 零基础入门学习C语言04
  5. cache老化时间的思考--以nat为例
  6. strtok和sscanf
  7. 现代教育技术课后作业(五)
  8. 爱国者D5移动电源改造
  9. 退出系统并跳转到登录界面 JS代码
  10. Still unable to dial persistent://blog.csdn.net:80 after 3 attempts