这才是后端API该有的样子

news2024/12/26 11:16:36

一般系统大致架构如下:

有些小伙伴会说,这个架构太简单太low了吧,什么网关、缓存、消息中间件都没有。

需要说明的是,因为我们主题是API接口(tbAPI,pinduoduo API接口调用)所以聚焦这一点上就行。

接口交互

    前端和后端进行交互,前端按照约定请求URL路径,并传入相关参数,后端服务器接收请求,进行业务处理,返回数据给前端。

针对URL路径的restful风格,以及传入参数的公共请求头的要求,如:app_version,api_version,device等,这里就不介绍了,小伙伴们可以自行去了解,也比较简单。

后端返回给前端我们一般用JSON体方式,定义如下:

{    #返回状态码    code:integer,    #返回信息描述    message:string,    #返回值    data:object}

CODE状态码

    code返回状态码,一般小伙伴们是在开发的时候需要什么,就添加什么。

如接口要返回用户权限异常,我们加一个状态码为101吧,下一次又要加一个数据参数异常,就加一个102的状态码。这样虽然能够照常满足业务,但状态码太凌乱了。另外,搜索公众号Linux就该这样学后台回复“猴子”,获取一份惊喜礼包。

我们应该可以参考HTTP请求返回的状态码:下面是常见的HTTP状态码:

200 - 请求成功301 - 资源(网页等)被永久转移到其它URL404 - 请求的资源(网页等)不存在500 - 内部服务器错误
 

我们可以参考这样的设计,这样的好处就把错误类型归类到某个区间内,如果区间不够,可以设计成4位数。

#1000~1999 区间表示参数错误#2000~2999 区间表示用户错误#3000~3999 区间表示接口异常

这样前端开发人员在得到返回值后,根据状态码就可以知道,大概什么错误,再根据message相关的信息描述,可以快速定位。

Message

这个字段相对理解比较简单,就是发生错误时,如何友好的进行提示。一般的设计是和code状态码一起设计,如:

再在枚举中定义,状态码:

状态码和信息就会一一对应,比较好维护。

Data

返回数据体JSON格式,根据不同的业务又不同的JSON体。

我们要设计一个返回体类Result

控制层Controller

我们会在controller层处理业务请求,并返回给前端,以order订单为例

我们看到在获得order对象之后,我们是用的Result构造方法进行包装赋值,然后进行返回。小伙伴们有没有发现,构造方法这样的包装是不是很麻烦,我们可以优化一下。

美观美化

我们可以在Result类中,加入静态方法,一看就懂

那我们来改造一下Controller:

代码是不是比较简洁了,也美观了。

优雅优化

上面我们看到在Result类中增加了静态方法,使得业务处理代码简洁了。但小伙伴们有没有发现这样有几个问题:

1、每个方法的返回都是Result封装对象,没有业务含义

2、在业务代码中,成功的时候我们调用Result.success,异常错误调用Result.failure。是不是很多余

3、上面的代码,判断id是否为null,其实我们可以使用validate做校验,没有必要在方法体中做判断。

我们最好的方式直接返回真实业务对象,最好不要改变之前的业务方式,如下图:

这个和我们平时的代码是一样的,非常直观,直接返回order对象,这样是不是很完美。那实现方案是什么呢?

实现方案

小伙伴们怎么去实现是不是有点思路,在这个过程中,我们需要做几个事情

1、自定义一个注解@ResponseResult,表示这个接口返回的值需要包装一下

2、拦截请求,判断此请求是否需要被@ResponseResult注解

3、核心步骤就是实现接口ResponseBodyAdvice和@ControllerAdvice,判断是否需要包装返回值,如果需要,就把Controller接口的返回值进行重写。

注解类

用来标记方法的返回值,是否需要包装

拦截器

拦截请求,是否此请求返回的值需要包装,其实就是运行的时候,解析@ResponseResult注解

此代码核心思想,就是获取此请求,是否需要返回值包装,设置一个属性标记。

 

重写返回体

上面代码就是判断是否需要返回值包装,如果需要就直接包装。这里我们只处理了正常成功的包装,如果方法体报异常怎么办?处理异常也比较简单,只要判断body是否为异常类。

重写Controller

    在控制器类上或者方法体上加上自定义注解@ResponseResult,这样就ok了,简单吧。到此返回的设计思路完成,是不是又简洁,又优雅。

    这个方案还有没有别的优化空间,当然是有的。如:每次请求都要反射一下,获取请求的方法是否需要包装,其实可以做个缓存,不需要每次都需要解析。

当然整体思路了解,小伙伴们就可以在此基础上面再自行扩展。PS:欢迎在留言区留下你的观点,一起讨论提高。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/431352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java FileChannel文件的读写实例

一、概述: 文件通道FileChannel是用于读取,写入,文件的通道。FileChannel只能被InputStream、OutputStream、RandomAccessFile创建。使用fileChannel.transferTo()可以极大的提高文件的复制效率,他们读和写直接建立了通道&#x…

【Leetcode刷题】链表的中间结点和合并两个有序链表

生命如同寓言,其价值不在与长短,而在与内容。 ——塞涅卡 目录 一.链表的中间结点 1.快慢指针 二.合并两个有序链表 1.尾插法 一.链表的中间结点 给你单链表的头结点 head ,请你找出并返回链表的中间结…

Java——对象克隆(复制)

假如想复制一个简单变量。很简单: int apples 5; int pears apples; 不仅int类型,其它七种原始数据类型(boolean,char,byte,short,float,double.long)同样适用于该类情况。 但是如果你复制的是一个对象,情况就复杂了。 假设说我是一个b…

windows安装scoop

scoop介绍 Scoop是一款适用于Windows平台的命令行软件(包)管理工具。简单来说,就是可以通过命令行工具(PowerShell、CMD等)实现软件(包)的安装管理等需求,通过简单的一行代码实现软…

博客上几种新职业的工作指南

© 2019 Conmajia 我不是在嘲讽谁,真的😅 看了不少博客,发现了一些共同点。我觉得可以把这些博主分类一下,形成几种新的职业。 1. 超文本抄书匠Hypertext Copier Job description 拥有悠久历史的手打大师,大段抄录…

2023-04-16 算法面试中常见的栈和队列问题

栈和队列 1 栈的基础应用:20.括号匹配 class Solution {public boolean isValid(String s) {Stack<Character> stack new Stack<>();for (int i 0; i < s.length(); i) {char c s.charAt(i);if (c ( || c [ || c {) {stack.push(c);} else {// 还有字符…

【Linux】进程间通信 -- 命名管道

前言 在管道的通信中&#xff0c;除了匿名管道&#xff0c;还有一个命名管道。 匿名管道只支持具有“亲戚关系”的进程间通信&#xff0c;而命名管道就可以支持不同的&#xff0c;任意的进程通信。 那就下来就开始我们今天的学习。 文章目录 前言一. 命名管道二. 命名管道的应用…

快速了解数据仓库建模

快速了解数据仓库建模 1、什么是OLTP和OLAP&#xff1f;2、为什么不在业务系统做数据分析呢&#xff1f;3、什么是数据库建模&#xff1f;4、关系建模。5、维度建模。5.1 事实表5.2 维度表 6、 数据仓库分层。6.1、 数仓分层结构6.2、 为什么需要对数据仓库分层&#xff1f; 1、…

Linux网络服务之DHCP篇

目录一、了解DHCP服务1.1DHCP定义1.2DHCP好处1.3DHCP的分配方式二、DHCP工作过程三. 使用DHCP动态配置主机地址一、了解DHCP服务 1.1DHCP定义 DHCP&#xff08;动态主机配置协议&#xff09;是一个局域网的网络协议。指的是由服务器控制一段IP地址范围&#xff0c;客户机登录…

基于SDM450 兼容st7701s不同id屏幕

authordaisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 sdm450 P326 在高通的 SDM450 中&#xff0c;有两种屏幕初始化代码&#xff0c;分别称为 "lk" 和 "kernel" 代码&#xff0c; "lk" 代码是用于在内核中初始化屏幕的代码。它通常在内核…

【Linux】进程间通信 -- 匿名管道的应用

前言 上篇博客初步学习了匿名管道的周边知识和使用&#xff0c;本篇文章将基于这些知识&#xff0c;实现一下进程间通信 话不多说&#xff0c;马上开始今天的内容 文章目录 前言一. 大体框架二. 分配任务三. 创建控制模块四. 开始通信五. 关闭程序六. 完整代码结束语 一. 大体框…

每日一题 leetcode1026 2023-4-18

1026. 节点与其祖先之间的最大差值 力扣题目链接 给定二叉树的根节点 root&#xff0c;找出存在于 不同 节点 A 和 B 之间的最大值 V&#xff0c;其中 V |A.val - B.val|&#xff0c;且 A 是 B 的祖先。 &#xff08;如果 A 的任何子节点之一为 B&#xff0c;或者 A 的任何…

【CSS】使用 z-index 属性值控制定位盒子的堆叠顺序 ( 多个盒子堆叠次序问题 | z-index 属性值简介 | 控制盒子堆叠次序 )

文章目录一、多个盒子堆叠次序问题二、z-index 属性值简介三、控制盒子堆叠次序一、多个盒子堆叠次序问题 在 网页布局 中 , 如果 多个盒子都设置 绝对定位 , 那么这些盒子会堆叠在一起 ; 设置了定位样式的盒子会压住标准流盒子 , 如果有多个设置定位的盒子 , 后面的盒子会压住…

数组篇刷题总结

二分查找&#xff1a; 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target …

【brtc】视频下行弱网对抗优化

百度云 音视频实时通信五个部分 1 RTC基础 需要云端服务器参与大量边缘服务器参与采集、前处理(图像处理)、压缩编码音频 3 A 回声消除、增益健全的六大指标 </

nodejs扫描文件夹搜索包含关键词文件,可灵活配置

代码放在在末尾 文件说明&#xff1a; 关键代码&#xff1a;search.js 搜索结果&#xff1a;searchResult.txt 搜索日志&#xff1a;search.log 注&#xff1a;只保留一次的&#xff0c;需要多次自行修改logFile配置即可&#xff1b; 使用方式&#xff1a; 将代码放到需要…

c/c++:一维数组,初始化数组,循环打印数组,计算数组存储空间,数组元素个数,数组逆序算法

c/c:一维数组&#xff0c;初始化数组&#xff0c;循环打印数组&#xff0c;计算数组存储空间&#xff0c;数组元素个数&#xff0c;数组逆序算法 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;此时学会c的话&#xff0c; …

一文讲解系统性能分析之|iowait是什么?

我们对系统性能进行优化时&#xff0c;一般会使用 top 命令来查看系统负载和系统中各个进程的运行情况&#xff0c;从而找出影响系统性能的因素。如下图所示&#xff1a; top top 命令会输出很多系统相关的信息&#xff0c;如&#xff1a;系统负载、系统中的进程数、CPU使用率…

联诚发携多款创新产品及解决方案惊艳亮相ISLE 2023展!

这里写自定义目录标题4月7日-9日&#xff0c;ISLE 2023国际智慧显示及系统集成展览会在深圳国际会展中心&#xff08;宝安新馆&#xff09;隆重举行。来自全球各地1000余家企业参与展出&#xff0c;展出面积达8万㎡&#xff0c;吸引了众多业内专家、企业家以及广大观众前来观看…

《攻防演练》在没有基础安全能力的情况下如何做好蓝队防守

目的&#xff1a; 1、净化企业或机构的网络环境、强化网络安全意识&#xff1b; 2、防攻击、防破坏、防泄密、防重大网络安全故障&#xff1b; 3、检验企业关键基础设施的安全防护能力&#xff1b; 4、提升关键基础设施的网络安全防范能力和水平。 现状&#xff1a; 那么问…