Swagger2的实战
一、Swagger2的官方文档
二、Swagger2的相关注解的介绍
1、接口相关的描述
@Api的主要属性
一般使用在Controller的类上,表示控制器的描述。
属性 | 描述 | @Deprecated |
---|---|---|
value | 控制器的名称 | false |
tags | 标签 | false |
description | 控制器的描述 | false |
basePath | 接口的根路径 | true |
position | 标签的位置 | true |
produces | 支持的请求类型 | true |
@ApiOperation的主要属性
属性 | 描述 |
---|---|
value | 接口说明 |
notes | 接口发布说明 |
tags | 标签 |
response | 接口返回值类型 |
httpMethod | 接口请求方式 |
@ApiIgnore
Swagger 文档不会显示拥有该注解的接口
@ApiImplicitParams
用于描述接口的非对象参数集。
@ApiImplicitParam
用于描述接口的非对象参数,一般与 @ApiImplicitParams 组合使用。
@ApiImplicitParam 主要属性
属性 | 描述 |
---|---|
paramType | 查询参数类型,实际上就是参数放在那里。取值: path:以地址的形式提交数据,根据 id 查询用户的接口就是这种形式传参。query:Query string 的方式传参。header:以流的形式提交。form:以 Form 表单的形式提交。 |
dataType | 参数的数据类型。取值:Long、String |
name | 参数名称 |
value | 参数的描述 |
required | 是否必须 |
2、Model 相关注解
@ApiModel
可设置接口相关实体的描述。
@ApiModelProperty
可设置实体属性的相关描述。
@ApiModelProperty 主要属性
属性 | 描述 |
---|---|
value | 字段说明 |
name | 重写字段名称 |
dataType | 重写字段类型 |
required | 是否必须 |
example | 举例说明 |
hidden | 是否在swaager中展示时隐藏该字段相关信息 |
allowEmptyValue | 是否允许为空 |
allowableValues | 该字段允许的值,当我们 API 的某个参数为枚举类型时,使用这个属性就可以清楚地告诉 API 使用者该参数所能允许传入的值。 |
三、相关代码的举例
控制层代码举例
package com.im.system.user.controller;
import com.google.common.collect.Maps;
import com.im.common.encryption.HmacUtils;
import com.im.common.http.HttpServletContext;
import com.im.common.spring.session.SessionUtils;
import com.im.system.user.domain.User;
import com.im.system.user.service.UserService;
import io.swagger.annotations.*;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;
/**
* create by wuxuan.chai
* at 2019/10/29 10:39 上午
*
* @since 0.0.0.1-SNAPSHOT
**/
@Api(tags = "用户相关接口", description = "提供用户相关的 Rest API")
@RestController
@RequestMapping(value = "/session", produces = MediaType.APPLICATION_JSON_VALUE)
public class UserController {
private static final String SECTET = "iMessage";
private static final String SIGN = "sign";
@Resource
private UserService userService;
@GetMapping(value = "/sign/")
@ApiOperation("获取登录所需的标识")
public Map<String, String> getSign() {
long timeMillis = System.currentTimeMillis();
String sign = HmacUtils.encryptByHmacSHA1(SECTET, String.valueOf(timeMillis));
HttpServletContext.getRequest().getSession().setAttribute(SIGN, sign);
Map<String, String> signObject = Maps.newHashMap();
signObject.put(SIGN, sign);
return signObject;
}
@ApiOperation("测试session中的sign")
@ApiIgnore
@GetMapping("/test/")
public String fetchSign() {
HttpSession session = HttpServletContext.getRequest().getSession();
return (String) session.getAttribute(SIGN);
}
@ApiOperation("登录接口")
@PostMapping("/login/")
@ApiImplicitParams({
@ApiImplicitParam(name = "user",value = "用户")
})
public String login(@RequestBody User user, HttpServletRequest request) {
User result = userService.login(user, request);
return result == null ? "fail" : "success";
}
@ApiOperation("用户注册接口")
@PostMapping("/register/")
public User register(@RequestBody User user) {
return userService.register(user);
}
@ApiOperation("用户登出接口")
@GetMapping("/logout/")
public void logout(HttpServletRequest request) {
SessionUtils.removeSession(request);
}
}
swagger的效果展示
model层代码举例
package com.im.system.user.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.im.common.domian.Domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.apache.ibatis.type.JdbcType;
import java.util.Date;
/**
* create by wuxuan.chai
* at 2019/10/28 2:42 下午
*
* @since 0.0.0.1-SNAPSHOT
**/
@TableName(value = "t_rbac_user")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("用户类")
public class User extends Domain {
@ApiModelProperty(value = "用户id")
@TableId(value = "id", type = IdType.AUTO)
private long id;
@ApiModelProperty(value = "用户账户")
@TableField(value = "username", jdbcType = JdbcType.VARCHAR)
private String username;
@ApiModelProperty(value = "用户密码")
@TableField(value = "password", jdbcType = JdbcType.VARCHAR)
private String password;
@ApiModelProperty(value = "用户状态")
@TableField(value = "status", jdbcType = JdbcType.VARCHAR)
private UserStatusTypeValue status;
@ApiModelProperty(value = "用户创建时间")
@TableField(value = "create_date", jdbcType = JdbcType.TIMESTAMP)
private Date createDate;
@ApiModelProperty(value = "用户修改时间")
@TableField(value = "update_date", jdbcType = JdbcType.TIMESTAMP)
private Date updateDate;
@ApiModelProperty(value = "用户手机号")
@TableField(value = "cell_num", jdbcType = JdbcType.VARCHAR)
private String cellNum;
@ApiModelProperty(value = "用户邮箱")
@TableField(value = "email", jdbcType = JdbcType.VARCHAR)
private String email;
public static User NullUser() {
return User.builder()
.status(UserStatusTypeValue.nullUser)
.build();
}
}
swagger的效果展示
四、结束语
在之前的开发的项目中,也有用到过swagger,在一开始也选择了swagger作为了我们的api文档工具。但是维护这个工具需要我们所有的开发人员去认真的规范我们的代码,比如养成一个常写注释的习惯,运用swagger的注解去做一些model和controller层的注解。在日常的开发中,这是非常重要的,虽然在短时间内,可能达不到明显的效果,但是时间一长久,你就会发现,完善的api文档,对于开发人员,对于新来的同事,对于我们的测试同学,甚至与我们朝夕相处的前端同学来说,都是巨大的帮助。有了这种api文档工具,对于我这种不喜欢写接口文档的人来说,如果前端开发人员还找我要文档,我会直接大胆的怼回去,这么详细的文档比我写的都详细,你在看不懂,那就没话可说了,这个不仅仅可以看还可以点击<try it out>按钮,进行接口请求,简直不要太方便好吧。
代码的规范上面就做的不好,很多model层的注解都没有写,结果就导致swagger看到的全是英文,没有一点的解释,程序员的即兴式命名,对于当时的程序员来说可能印象深刻,但是时间一久原创估计都不知道某些字段名到底是什么意思了,会造成一定程度的api阅读成本。所以再次希望大家能够约束自己的代码规范,勤于注释,有些时候注释也是写代码的一部分。