这才是后端API该有的样子

一般系统大致架构如下:

有些小伙伴会说,这个架构太简单太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:欢迎在留言区留下你的观点,一起讨论提高。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令·ping

Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”、不能打开网页时会说“你先ping网关地址192.168.1.1试试”。它通过发送ICMP ECHO_REQUEST数据包到网络主机&#xff08…

【小程序】django笔记2

templates路径除了在settings中的templates的DIR[]中申明还有什么别的方法? 已知,django底层根据app注册顺序查找各app文件中的templates文件夹,在其中搜索目标模版文件。 已知,app注册在settings中的INSTAll-APPS里。 已知&#…

C++ 缺省参数 函数重载 引用

缺省参数,我们先看一下什么是缺省参数 首先,这个是我们的需要传参的函数,这里我们传入 1 然后就输出 a 下面我们就看一下缺省参数 我们现在看main函数里面调用fun函数,这里会输出多少呢? OK 这里我们分别输出了0 和 1…

【2023】cookie是什么?有什么用?一篇文章彻底搞懂cookie

一个不大不小的问题 假设服务器有一个接口,通过请求这个接口,可以添加一个管理员 但是,不是任何人都有权力做这种操作的 那么服务器如何知道请求接口的人是有权力的呢? 答案是:只有登录过的管理员才能做这种操作 …

SpringCloud之OpenFeign介绍案例+相关面试题

概述 OpenFeign是一个声明式的WEB服务客户端,它使WEB服务客户端变得更加容易。具有可插拔的注解支持,SpringCloud中添加了SpringMVC注解的支持。SpringCloud中集成了Ribbon和Eureka,以及SpringCloud LoadBalance,以便在使用Feign时…

pyest+appium实现APP自动化测试,思路全总结在这里

目录 01、appium环境搭建 2、搭建pythonpytestappium环境 3、安装pycharm搭建项目编写脚本 4、执行测试 绵薄之力 01、appium环境搭建 安装nodejs http://nodejs.cn/ 为什么要安装nodejs? 因为appium这个工具的服务端是由nodejs语言开发的 安装jdk&#xf…

mysql数据库简介

1.什么是数据库:数据仓库。访问必须只能用SQL语句来访问。数据库也是一个文件的系统。 2.数据库的作用:存储数据的作用。开发任何的应用,都有数据库。 3.关系型的数据库:数据库中保存的都是实体与实体之间的关系。 4.常见的数据库…

2023接口自动化测试,完整入门篇

1. 什么是接口测试 顾名思义,接口测试是对系统或组件之间的接口进行测试,主要是校验数据的交换,传递和控制管理过程,以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型,测试类型又主…

stata绘图指令

stata绘图指令 – 潘登同学的stata笔记 文章目录 stata绘图指令 -- 潘登同学的stata笔记 绘图概览韦恩图折线图连线图线性拟合图直方图 函数图添加特殊字符和文字 绘图概览 Stata 提供的图形种类: twoway 二维图scatter 散点图line 折线图area 区域图lfit 线性拟合…

基于单片机的温室大棚环境监测系统设计

温室大棚对北方反季节蔬菜的种植具有重要意义。据了解全国各地温室大棚使用集中,但是大棚环境调控方式落后、管理落后、生产效率比较低。针对此问题本文提出了一种基于STM32单片机智能温室大棚控制系统方案,实现环境参数的自动检测,以达到智能…

2023年股票代持行业研究报告

第一章 股票代持概述 1.1 基本概念 股票代持,或称委托持股,是指实际出资人与名义出资人达成以下约定:名义出资人作为名义股东,在股东名册等公司工商登记信息上出现,而实际上由实际出资人出资并享有投资权益。 股票代…

Segment Anything论文详解(SAM)

论文名称:Segment Anything 论文地址:https://arxiv.org/abs/2304.02643 开源地址:https://github.com/facebookresearch/segment-anything demo地址:Segment Anything | Meta AI 主要贡献:开发一个可提示的图像分…

图片存储方案-七牛云存储

1.引语 在实际开发中,我们会有很多处理不同功能的服务器。例如: 应用服务器:负责部署我们的应用 数据库服务器:运行我们的数据库 文件服务器:负责存储用户上传文件的服务器 分服务器处理的目的是让服务器各司其职…

设计模式简述

设计模式(简述) 设计模式的分类 ​ 根据目的可以分为创建型、结构性和行为型三类: 创建型模型:创建对象结构性模型:处理类或对象的组合行为型模式:用于描述对类或对象怎样交互和怎么分派职责 ​ 根据范围可以分为类模式和对象…

nvm-windows的安装使用及踩坑指南

nvm是node的一款版本管理工具,可以简单操作node版本的切换、安装、查看。常规来说,开发中安装一个node版本就够了,但是最近在开发中有的老项目或者一些特定的项目需要来回切换node的版本,不可能手动去卸载掉之前的node版本&#x…

013:Mapbox GL添加marker

第013个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中添加marker。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共70行)相关API参考:专栏目标示例效果 配置方式 1)查看基础设置:https://xiaozhu…

算法时间复杂度计算

目录 1.时间复杂度计算 1.1 时间复杂度例题 1.1.1例题 1.1.2例题 1.1.3例题 1.1.4例题 1.2时间复杂度leetcode例题 1.时间复杂度计算 首先,我们需要了解时间复杂度是什么:算法的时间复杂度是指算法在编写成可执行程序后,运行时需要耗费…

使用 Floyd Warshall 检测负循环

我们得到了一个有向图。我们需要计算图形是否有负循环。负循环是循环的总和为负的循环。 在图形的各种应用中都可以找到负权重。例如,如果我们沿着这条路走,我们可能会得到一些好处,而不是为一条路付出代价。 例子:

Linux中的read/write和recv/send的区别,并使用recv/send实现简单的聊天功能

Linux中的read/write和recv/send的区别 r e a d / w r i t e read/write read/write的用法 r e c v / s e n d recv/send recv/send的用法 L i n u x Linux Linux中的 r e a d / w r i t e read/write read/write和 r e c v / s e n d recv/send recv/send的区别下面是一个使用…

Three.js教程:第一个3D场景

推荐:将 NSDT场景编辑器加入你3D工具链 其他工具系列: NSDT简石数字孪生 下面的代码完整展示了通过three.js引擎创建的一个三维场景,在场景中绘制并渲染了一个立方体的效果,为了大家更好的宏观了解three.js引擎, 尽量使…