使用swagger-typescript-api

news2024/11/24 7:09:03

引言

前后端分离大致是这样的

  • 后端:控制层 / 业务层 / 数据操作层
  • 前端:控制层 / 视图层

前后端的控制层,实际上就是前后端接口的对接
前后端分离,实现了更好地解耦合,但也引入了接口对接的过程,这个过程常常是繁琐,容易产生错误的

于是引入了api接口文档,来解决这个事情,如果有一份事先约定好的接口文档,双方都按照这个来,就能实现完美的对接。(但这通常很难实现,无法预先知道需要什么接口,接口的参数,是一个反复修改的过程)

现在后端广泛采用swagger技术,能够在开发时,就能生成接口文档,并能便捷地测试接口

对前端来说,就可以根据后端项目的swagger文档,来设计前端的控制层,也就是通常的根目录下的api文件夹,将对接口的请求封装为功能函数(也是为了与视图层解耦)

// user.ts
export const getUserList = () => request.get('/user/list')

但其实,一个api函数也就是对应的一个后端接口,已经有了接口文档,为什么不能直接生成前端的控制层?

前端控制层函数看似简单,其实做到类型完备,函数提示清晰(参数类型,返回值类型,各种注释),是一个十分繁琐的过程

所以,just relax,这个过程交由swagger-typescript-api来完成吧

swagger-typescript-api

我并不是讲swagger-typescript-api教程,可以去github上看它的所有用法,我只是讲述一下我是如何使用它的

我的项目并不是一个大型前后端分离项目,仅仅是作为练手,用前后端分离的方式自己开发。如果适用于您,您可以往下看

swagger-typescript-api有两种使用方式:命令行 & node脚本程序
优缺点显然:前者方便,后者易定制

我将以命令行的方式

进入我的前端项目中,在shell中输入

npx swagger-typescript-api -p http://localhost:8080/v2/api-docs?group=Manager -o ./src/api --axios --modular --module-name-index 1 --single-http-client
  • http://localhost:8080/v2/api-docs?group=Manager 我的swagger api文档地址
  • -o ./src/api 将生成的文件输出到src下的api目录下
  • --axios 采用axios客户端,默认fetch
  • --modular 分离http client, data constracts, 和routes,否则只会生成一个大文件
    • http client 这里就是axios客户端,对其进行了一定的封装
    • data constracts api接口中,用到的参数,或者返回值类型
  • --module-name-index 1 分离routes,意思是按api路径.split('/')[1]拆分接口文件

比如我有两个controller,UserController和DishController,访问UserController下的api,都是以/admin/user开头的,而访问DishController下的api,是以/admin/dish开头,所以这样做后,也就是按照后端的controller分离api接口文件了

  • --single-http-client 意为只有一个http客户端,稍后解释

于是在api文件夹下,生成了
在这里插入图片描述
这里swagger-typescript-api替我生成了除API.ts外的所有文件

如果直接使用的话,还是不太方便,因为每个controller都是一个http客户端

意味着我需要这么调用接口
new Category().getCategoryList()
new Dish().addDish()
当然,最重要的是,我们还需要对axios进行配置!

  • 比如添加baseUrl,当然它生成的http客户端默认为localhost:8080,但我们通常都会配置为环境变量,以便切换不同环境下的后端
  • 比如添加请求拦截器,向后端请求自动携带token认证信息
  • 比如添加响应拦截器,对产生的http错误,进行捕获和反馈(如show error message,告知unauthorized)

如果没有设置--single-http-client,产生的controller是这样的

class Employee<SecurityDataType = unknown> extends HttpClient<SecurityDataType>{...}

这样,你需要为每个controller的http客户端进行相同的配置,so dity!!!

但是,设置之后,产生controller是这样的

class Employee<SecurityDataType = unknown> {
  http: HttpClient<SecurityDataType>;

  constructor(http: HttpClient<SecurityDataType>) {
    this.http = http;
  }
  ...
}

可以看到,前者是继承,后者是组合,也叫委派

但是,我们仍然需要为每个controller委派相同的http-client,所以我引入了API.ts来解决这个问题(这只是一个简单的示例)

class API<SecurityDataType = unknown> extends HttpClient<SecurityDataType> {
  public category = new Category(this);
  public common = new Common(this);
  public dish = new Dish(this);
  public employee = new Employee(this);
}

export const api = new API({
  paramsSerializer: (params) => qs.stringify(params, { indices: false }),
  baseURL: import.meta.env.VITE_APP_API_URL,
});

api.instance.interceptors.request.use(
  (config) => {
    if (getToken()) {
      config.headers["token"] = getToken();
    }
    return config;
  },
  (error) => {
    console.log(error);
    Promise.reject(error);
  }
);

api.instance.interceptors.response.use(
  (res) => {
    const code = res.data.code;
    const msg = res.data.msg || "系统未知错误,请反馈给管理员";
    if (
      res.request.responseType === "blob" ||
      res.request.responseType === "arraybuffer"
    ) {
      return res;
    }
    if (code !== 1) {
      message.error(msg);
      return Promise.reject(new Error(msg));
    } else {
      return res;
    }
  },
  (error) => {
    console.log("err" + error);
    let { message: msg } = error;
    if (msg === "Network Error") {
      msg = "后端接口连接异常";
    } else if (msg.includes("timeout")) {
      msg = "系统接口请求超时";
    } else if (msg.includes("Request failed with status code")) {
      // 获得异常http状态码
      const statusCode = +msg.substr(msg.length - 3);
      if (statusCode === 401) {
        Modal.confirm({
          title: "系统提示",
          content: "登录状态已过期,请重新登录",
          okText: "确定",
          onOk() {
            removeToken();
            location.href = "/";
          },
        });
        return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
      }
      msg = "系统接口" + statusCode + "异常";
    }
    message.error(msg);
    return Promise.reject(error);
  }
);

进行封装后,我们可以更为优雅地调用api
api.category.getCategoryList()

Is it elegant ?

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

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

相关文章

什么是外贸SOHO建站?新手如何做好推广?

新手外贸SOHO建站教程&#xff1f;海洋建站谷歌SEO优化步骤&#xff1f; 外贸SOHO建站是一种为小型外贸企业和个体经营者提供的网站建设服务&#xff0c;旨在帮助他们在国际市场上建立自己的在线存在&#xff0c;从而拓展业务。海洋建站将深入探讨外贸SOHO建站的含义&#xff…

vue下使用Echarts5绘制基础图表

项目使用Vue3加Echarts5绘制的基本图表&#xff0c;图表自适应浏览器窗口大小 先上图&#xff0c;大屏小屏都可完美展示&#xff0c;纯属练手 一 先上图 1.任意缩放窗口的大小 2.平板 3.电脑 4.饼图 5.折线图 二 后上代码 <script lang"ts"> import {d…

Jwt,Token,Cookie,Session之间的区别

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

ROS学习笔记(6):ros_control

1.ros_control简介 ros_control - ROS Wiki ros_control是为ROS提供的机器人控制包&#xff0c;包含一系列控制器接口、传动装置接口、控制器工具箱等,有效帮助机器人应用功能包快速落地&#xff0c;提高开发效率。 2.ros_control框架 ros_control总体框架&#xff1a; 针对…

【springboot配置项动态刷新】与【yaml文件转换为java对象】

文章目录 一&#xff0c;序言二&#xff0c;准备工作1. pom.xml引入组件2. 配置文件示例 三&#xff0c;自定义配置项动态刷新编码实现1. 定义自定义配置项对象2. 添加注解实现启动时自动注入3. 实现yml文件监听以及文件变化处理 四&#xff0c;yaml文件转换为java对象1. 无法使…

Go 语言初探:从基础到实战

1.Go概述 程序是一段计算机指令的有序组合。程序算法数据结构。任何程序都可以将模块通过三种基本的控制结构&#xff08;顺序、分支、循环&#xff09;进行组合来实现。 Go&#xff08;也称为Golang&#xff09;是一种由Google开发的开源编程语言。设计目标是使编程更简单、…

配置802.1x本地认证,以识别用户身份的示例

组网图形 图1 802.1x本地认证组网图 规格组网需求操作步骤配置注意事项 规格 适用于所有版本、所有形态的AR路由器。 组网需求 PC1(10.10.10.2/30)直接连接到RouterA的Eth2/0/1端口&#xff0c;RouterA的VLANIF10接口IP地址10.10.10.1/30&#xff08;为PC1上的网关IP地址&a…

基于CLIP的图像分类、语义分割和目标检测

OpenAI CLIP模型是一个创造性的突破&#xff1b; 它以与文本相同的方式处理图像。 令人惊讶的是&#xff0c;如果进行大规模训练&#xff0c;效果非常好。 在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 3D…

一维码和二维码图像优化——提高读码率

1.算子 1.1 decompose3 &#xff08;彩色图像分割算子&#xff09; 算子&#xff1a;decompose3 ——将三通道图像转换为三个图像函数原型&#xff1a;decompose3(MultiChannelImage : Image1, Image2, Image3 : : ) 功能&#xff1a;将3通道图像转换为具有相同定义域&#…

智慧安防:监控防盗两不误的安防视频监控系统是什么样的?

随着社会的不断发展&#xff0c;安全问题越来越受到人们的关注&#xff0c;特别是对于居住在城市里的人们来说&#xff0c;盗窃问题是影响他们生活质量的重要因素之一。因此&#xff0c;根据市场需求&#xff0c;以监控防盗两不误的智慧监控系统得到了广泛的推广和应用。 一般…

不充不行(同时跑三辆车)

欢迎来到程序小院 不充不行 玩法&#xff1a;点击鼠标左键长按充电桩&#xff0c;别让车落回底线&#xff0c;三辆车同时在跑&#xff0c;要控制三个充电桩的电量&#xff0c;电量为0即为游戏结束&#xff0c;看看你能坚持多少秒哦^^。开始游戏https://www.ormcc.com/play/gam…

迅镭激光与江苏中红外激光研究院达成战略合作意向

11月6日&#xff0c;江苏中红外激光研究院院长沈德元、江苏师范大学物电学院系主任韩彩芹、江苏中红外激光研究院技术副总王飞等领导莅临迅镭激光调研指导并进行合作会谈&#xff0c;迅镭激光董事长颜章健热情接待。双方就成果转化、产业合作、专业人才培养等方面进行深入洽谈&…

Centos7下安装-使用K3S

本文主要内容&#xff1a; 1.安装k3s 2.在idea中&#xff0c;编辑yml文件创建pod 3.在k3d中pod基本操作 4.在k3d中Labeles标签基本操作 5.在k3d中容器的基本操作 &#xff08;k3s的操作与k8s操作不同处在于&#xff0c;k3s每次执行命令&#xff0c;前面需要加上k3s&#xff09;…

猫罐头什么牌子好?2023营养又美味的猫主食罐头推荐!

亲爱的猫咪主人&#xff0c;你是否为你家小猫咪的挑食问题感到困扰&#xff1f;作为一位在宠物店工作了七年&#xff0c;负责喂养三十多只猫咪的店长&#xff0c;我对许多品牌的猫罐头都非常熟悉了。对于猫罐头哪个牌子好这个问题&#xff0c;我想借此机会分享一些见解。 在本…

linux基础:3.linux基础环境开发工具和配置。

linux基础环境开发工具和配置 一.学习yum工具进行软件安装&#xff1a;1.什么是yum&#xff1a;2.查看软件包&#xff1a;3.安装和删除&#xff1a;4.yum生态&#xff1a; 二.vim的使用&#xff1a;一.快速介绍一下vim二.vim正常模式&#xff1a;2-1&#xff1a;命令模式1.光标…

HarmonyOS应用开发-ArkTS基础知识

作者&#xff1a;杨亮Jerry 作为多年的大前端程序开发工作者&#xff0c;就目前的形式&#xff0c;个人浅见&#xff0c;在未来3-5年&#xff0c;移动端依旧是Android系统和iOS系统的天下。不过基于鸿蒙系统的应用开发还是值得我们去花点时间去了解下的&#xff0c;阅读并实践官…

一杯子三变:揭秘vue单页应用(spa)与内容动态加载的奥秘

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、什…

找不到x3daudio1_7.dll怎么办?五种解决方法帮你解决x3daudio1_7.dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“X3DAudio1_7.dll丢失”。这个错误通常会导致音频播放异常或无法正常工作。为了解决这个问题&#xff0c;本文将介绍5种修复X3DAudio1_7.dll丢失的方法&#xff0c;帮助大家快速恢复X3DAudi…

Redis的三种特殊数据类型

文章目录 一、Redis geospatial 地理位置二、Redis Hyperloglog 基数统计的算法三、Redis Bitmaps 位存储&#xff08;0、1&#xff09;总结 一、Redis geospatial 地理位置 1.geoadd&#xff1a;将指定的地理空间位置&#xff08;纬度、经度、名称&#xff09;添加到指定的ke…

vue中 process.env 对象为空对象问题

问题&#xff1a;今天在处理vue项目环境问题的时候&#xff0c;发现直接打印 process 对象和打印 process.env 时 env 对象输出结果是不一样的&#xff0c;如下图所示&#xff1a; 在网上搜索了一番后发现还是有挺多朋友对此感到疑惑的&#xff0c;询问了同事&#xff0c;同…