瑞吉外卖-day09

YangeIT大约 21 分钟瑞吉外卖瑞吉外卖优化前后端分离开发YapiSwagger项目部署

瑞吉外卖-day09

课程内容

  • 前后端分离开发
  • Yapi/ApiFox
  • Swagger
  • 项目部署

前言

问题

  1. 当前项目中,前端代码和后端代码混合在一起,是存在问题的,存在什么问题呢?
image-20210831232554721
image-20210831232554721

主要存在以下几点问题:

  1. 开发人员同时负责前端和后端代码开发,分工不明确
  2. 开发效率低
  3. 前后端代码混合在一个工程中,不便于管理
  4. 对开发人员要求高(既会前端,又会后端),人员招聘困难‘

解决方式

为了解决上述提到的问题,现在比较主流的开发方式,就是前后端分离开发,前端人员开发前端的代码,后端开发人员开发服务端的业务功能,分工明确,各司其职。我们本章节,就是需要将之前的项目进行优化改造,变成前后端分离开发的项目。

1. 前后端分离开发

1.1 介绍 🍐

问题

  1. 前后端分离开发的好处是什么?

前后端分离开发,就是在项目开发过程中,对于前端代码的开发由专门的前端开发人员负责,后端代码则由后端开发人员负责,这样可以做到分工明确、各司其职,提高开发效率,前后端代码并行开发,可以加快项目开发进度。

目前,已经被越来越多的公司所采用,成为当前项目开发的主流开发方式。

前后端分离开发后,从工程结构上也会发生变化,即前后端代码不再混合在同一个 maven 工程中,而是分为 前端工程后端工程

image-20210901082121874
image-20210901082121874

前后端分离之后,不仅工程结构变化,后期项目上线部署时,与之前也不同:

前后对比

  1. 之前: 前后端代码都混合在一起,我们只需要将前端和后端的代码统一打成 jar 包,直接运行就可以了。

  2. 现在: 拆分为前后端分离的项目后,最终部署时,后端工程会打成一个 jar 包,运行在 Tomcat 中(springboot 内嵌的 tomcat)。前端工程的静态资源,会直接部署在 Nginx 中进行访问。

1.2 开发流程 🍐

问题

  1. 前后端程序员如何配合来开发一个项目?

流程

image-20210901084945348 image-20210901085057990

  1. : 这里所说的接口不是我们之前在 service, mapper 层定义的 interface; 这里的接口(API 接口)就是一个 http 的请求地址,主要就是去定义:请求路径、请求方式、请求参数、响应数据等内容。(具体接口文档描述的信息, 如上图) 👈
  2. : 依据定义好的接口信息,前端人员开发前端的代码,服务端人员开发服务端的接口; 在开发中前后端都需要进行测试,后端需要通过对应的工具来进行接口的测试,前端需要根据接口定义的参数进行 Mock 数据模拟测试。
  3. : 当前后端都开发完毕并且自测通过之后,就可以进行前后端的联调测试了,在这一阶段主要就是校验接口的参数格式。
  4. : 前后端联调测试通过之后,就可以将项目部署到测试服务器,进行自动化测试了。

1.3 前端技术栈 🚀

问题

  1. 前端开发使用哪些开发工具和框架?
  • Visual Studio Code (简称 VsCode)
  • Hbuilder

2. Yapi/ApiFox

2.1 介绍

问题

  1. Yapi是什么,有什么作用?
image-20210901110936381
image-20210901110936381

YApi 是高效、易用、功能强大的 api 管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API,YApi 还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理。

YApi 让接口开发更简单高效,让接口的管理更具可读性、可维护性,让团队协作更合理。

源码地址: https://github.com/YMFE/yapiopen in new window

官方文档: https://hellosean1025.github.io/yapi/open in new window

要使用 YApiYApi 使用教程open in new window,项目组需要自己进行部署,因此也可以使用 Apifox[1]Apifox 使用教程open in new window

3. Swagger

3.1 介绍

问题

  1. Swagger是什么,有什么作用?

介绍

官网:https://swagger.io/open in new window

image-20210901160434736
image-20210901160434736

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。功能主要包含以下几点:

  • A. 使得前后端分离开发更加方便,有利于团队协作
  • B. 接口文档在线自动生成,降低后端开发人员编写接口文档的负担
  • C. 接口功能测试

使用 Swagger 只需要按照它的规范去定义接口及接口相关的信息,再通过 Swagger 衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。

Swagger 使用说明

  1. 直接使用 Swagger, 需要按照 Swagger 的规范定义接口, 实际上就是编写 Json 文件,编写起来比较繁琐、并不方便 。
  2. 在项目中使用,我们一般会选择一些现成的框架来简化文档的编写,而这些框架是基于 Swagger 的,如 knife4j。
  3. knife4j 是为 Java MVC 框架集成 Swagger 生成 Api 文档的增强解决方案。
  4. 我们要使用 kinfe4j,需要在 pom.xml 中引入如下依赖即可:
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

3.2 使用方式

问题

  1. Swagger集成步骤?

接下来,我们就将我们的项目集成 ,来自动生成接口文档。

使用 knife4j,主要需要操作以下几步:

1). 导入 knife4j 的 maven 坐标

<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.2</version>
</dependency>

👉 👉 经过上面的集成配置之后,我们的项目集成 Swagger 及 Knife4j 就已经完成了!!! 🎉 🎉

3.3 查看接口文档

问题

  1. Swagger集成后还需要手动书写接口文档吗?

接下来我们可以重新启动项目,访问接口文档,访问链接为: http://localhost:8080/doc.htmlopen in new window

image-20210901200739975
image-20210901200739975

我们可以看到,在所有的 Controller 中提供的所有的业务增删改查的接口,全部都已经自动生成了,我们通过接口文档可以看到请求的 url、请求方式、请求参数、请求实例、响应的参数,响应的示例。 并且呢,我们也可以通过这份在线的接口文档,对接口进行测试。

image-20210901201229838
image-20210901201229838

注意: 由于我们服务端的 Controller 中的业务增删改查的方法,都是必须登录之后才可以访问的,所以,我们在测试时候,也是需要先访问登录接口。登录完成之后,我们可以再访问其他接口进行测试。

我们不仅可以在浏览器浏览生成的接口文档,Knife4j 还支持离线文档,对接口文档进行下载,支持下载的格式有:markdown、html、word、openApi。

image-20210901214706928
image-20210901214706928

3.4 常用注解

3.4.1 问题说明

问题

在上面我们直接访问 Knife4j 的接口文档页面,可以查看到所有的接口文档信息,但是我们发现,这些接口文档分类及接口描述都是 Controller 的类名(驼峰命名转换而来)及方法名,而且在接口文档中,所有的请求参数,响应数据,都没有中文的描述,并不知道里面参数的含义,接口文档的可读性很差。

image-20210901215244539
image-20210901215244539

3.4.2 注解介绍

问题

  1. Swagger有哪些注解?分别有什么作用?

为了解决上述的问题,Swagger 提供了很多的注解,通过这些注解,我们可以更好更清晰的描述我们的接口,包含接口的请求参数、响应数据、数据模型等。核心的注解,主要包含以下几个:

注解位置说明
@Api加载 Controller 类上,表示对类的说明
@ApiModel类(通常是实体类)描述实体类的作用
@ApiModelProperty属性描述实体类的属性
@ApiOperation方法说明方法的用途、作用
@ApiImplicitParams方法表示一组参数说明
@ApiImplicitParam方法用在@ApiImplicitParams 注解中,指定一个请求参数的各个方面的属性

3.4.3 注解测试

1). 实体类

可以通过 @ApiModel , @ApiModelProperty 来描述实体类及属性

@Data
@ApiModel("套餐")
public class Setmeal implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("主键")
    private Long id;

    //分类id
    @ApiModelProperty("分类id")
    private Long categoryId;

    //套餐名称
    @ApiModelProperty("套餐名称")
    private String name;

    //套餐价格
    @ApiModelProperty("套餐价格")
    private BigDecimal price;

    //状态 0:停用 1:启用
    @ApiModelProperty("状态")
    private Integer status;

    //编码
    @ApiModelProperty("套餐编号")
    private String code;

    //描述信息
    @ApiModelProperty("描述信息")
    private String description;

    //图片
    @ApiModelProperty("图片")
    private String image;

    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @TableField(fill = FieldFill.INSERT)
    private Long createUser;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateUser;
}

4. 项目部署

在本章节,我们要做的是项目的部署,包含前端项目的部署,及后端项目的部署。

4.1 部署架构

问题

  1. 项目的部署架构是怎样的?
image-20210901221425159
image-20210901221425159

PC端: 主要是为餐厅的员工及管理员使用的后台管理系统,对分类、菜品、套餐信息进行维护。

移动端: 可以基于微信公众号或小程序实现,我们课上并未实现,这部分的工作是前端开发人员需要开发的。

前端部署服务器: Nginx

后端部署服务器: Tomcat(内嵌)

4.2 环境说明

问题

  1. 前端资源和Java代码是在一个服务器运行吗?

由于我们的服务器数量有限,就使用这三台服务器,具体的软件规划如下:

服务器软件名称
192.168.138.100Nginx(部署前端项目、配置反向代理),MySQL(主从复制的主库)服务器A
192.168.138.101JDK1.8、Git、Maven、jar(项目jar包基于内嵌Tomcat运行)、MySQL(主从复制的从库)服务器B
172.17.2.94Redis(缓存中间件)服务器C

由于我们前面的课程中Nginx、MySQL的主从复制、Redis、JDK、Git、Maven都已经演示过安装及配置了,这里我们就不再演示软件的安装了。

4.3 前端部署

问题

  1. 前端资源部署在什么服务器上?

1). 在服务器A(192.168.138.100)中安装Nginx,将课程资料中的dist目录上传到Nginx的html目录下

image-20210901231943256
image-20210901231943256

将整个dist目录上传至/usr/local/nginx/html目录下

image-20210901231924028
image-20210901231924028

4.4 反向代理配置 🍐

问题

  1. 反向代理,用户能感知最终访问哪台java服务器吗?

前端工程部署完成之后,我们可以正常的访问到系统的登录页面,点击登录按钮,可以看到服务端发起的请求,请求信息如下:

image-20210901234142706
image-20210901234142706

而大家知道,在我们之前开发的工程中,是,那这个时候,在不修改服务端代码的情况下,如何处理该请求呢?

实际上,通过nginx的就可以轻松解决这个问题。

在上述我们配置的nginx.conf中,除了配置了静态资源的加载目录以外,我们还配置了一段反向代理的配置,配置信息如下:

location ^~ /api/ {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://192.168.138.101:8080;
}

这一段配置代表,如果请求当前nginx,并且请求的路径如果是 /api/ 开头,将会被该location处理。而在该location中,主要配置了两块儿信息: rewrite(url重写) 和 proxy_pass(反向代理)。 接下来我们就来解析一下这两项的配置。

1). 路径重写rewrite

rewrite ^/api/(.*)$ /$1 break;

这里写的是一个正则表达式,代表如果请求路径是以 /api/ 开头,后面的请求路径任意,此时将原始的url路径重写为 /$1,这里的$1指代的就是通配符 .* 这一块的内容。比如:

/api/employee/login ------> ^/api/(.*)$ --------> 此时 (.*) 匹配的就是 employee/login ------> 最终重写为/$1 : /employee/login

2). 反向代理

proxy_pass http://192.168.138.101:8080;

路径重写后的请求,将会转发到后端的 http://192.168.138.101:8080open in new window 服务器中。 而这台服务器中,就部署的是我们的后端服务。

4.5 服务端部署 ✏️

问题

  1. 服务端部署需要哪些准备工作?

1). 在服务器B(192.168.138.101)中安装jdk、git、maven、MySQL,使用git clone命令将git远程仓库的代码克隆下来

A. 确认JDK环境

image-20210902002307537
image-20210902002307537

B. 确认Git环境

image-20210902002328883
image-20210902002328883

C. 确认Maven环境

image-20210902002357900
image-20210902002357900

D. 将我们开发完成的代码推送至远程仓库,并在服务器B中克隆下来

#创建java代码存放目录
mkdir -p /usr/local/javaapp

#切换目录
cd /usr/local/javaapp

#克隆代码 , 需要使用自己的远程仓库
git clone https://gitee.com/ChuanZhiBoKe/reggie_take_out.git 
image-20210902004033417
image-20210902004033417

4.6 图片展示问题处理 🍐

在上述的测试中,我们发现菜品的图片无法正常展示。原因是因为,在我们的配置文件中,图片信息依然是从 D:/img 中加载的,但是在Linux服务器中,是不存在D盘的。

image-20210902005957772
image-20210902005957772

1). 修改文件存储目录

将文件存储目录修改为:

reggie:
  path: /usr/local/img/

修改完成之后,需要将变动的代码提交到本地仓库,并推送至远程仓库。

image-20210902010223733
image-20210902010223733


  1. ApiFox 是一款模拟请求的软件,有:API 文档、API 调试、API Mock、API 自动化测试等功能,官网:https://www.apifox.cn/open in new window ↩︎