011-从零搭建微服务-接口文档(一)

文章介绍了如何使用SpringDoc替换SpringFox作为API文档工具,并展示了如何在SpringCloudGateway中聚合各个微服务的接口文档。通过配置SpringDoc,实现了接口文档的在线查看和测试功能,并提供了详细的配置步骤和代码示例。
摘要由CSDN通过智能技术生成

写在最前

如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

源码地址(后端):https://gitee.com/csps/mingyue-springcloud-learning

源码地址(前端):https://gitee.com/csps/mingyue-springcloud-ui

文档地址:https://gitee.com/csps/mingyue-springcloud-learning/wikis

开胃小菜

如果对接口文档不了解可以先看看下面的一些推荐阅读,简单了解一哈,不过已经不推荐使用了,之前使用 SpringFox 实现的。

首先 SpringFox 停止维护,很多 Bug 也不会修复了,其次 SpringDoc 基于 javadoc 无注解零入侵生成规范的 Openapi 结构体是行业规范,很多工具都支持接入,如:ApifoxPostman等。

SpringFox 与 SpringDoc 注解差异

SwaggerSpringDocJavaDoc
@jApi(name = “xxx”)@Tag(name = “xxx”)java类注释第一行
@Api(description= “xxx”)@Tag(description= “xxx”)java类注释
@ApiOperation@Operationjava方法注释
@ApiIgnore@Hidden
@ApiParam@Parameterjava方法@param参数注释
@ApiImplicitParam@Parameterjava方法@param参数注释
@ApiImplicitParams@Parameters多个@param参数注释
@ApiModel@Schemajava实体类注释
@ApiModelProperty@Schemajava属性注释
@ApiModelProperty(hidden = true)@Schema(accessMode = READ_ONLY)
@ApiResponse@ApiResponsejava方法@return返回值注释

mingyue-gateway

引入依赖

<!-- 接口文档 -->
<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-webflux-ui</artifactId>
</dependency>

SpringDocConfiguration

该类作为 Swagger 接口文档的聚合配置类,统一从网关入口进入 Swagger 文档中心。

@ConditionalOnProperty 注解用来指定如果配置文件中未进行对应属性配置时的默认处理:默认情况下matchIfMissing 为 false,也就是说如果未进行属性配置,则自动配置不生效。如果 matchIfMissing 为 true,则表示如果没有对应的属性配置,则自动配置默认生效。

@Configuration(proxyBeanMethods = false)
public class SpringDocConfiguration {
  
  /**
	 * 当 swagger.enabled = true 向 Bean 容器中注册改对象
	 * @return
	 */
  @Bean
	@Lazy(false)
	@ConditionalOnProperty(name = "swagger.enabled", havingValue = "true", matchIfMissing = true)
	public List<GroupedOpenApi> apis(SwaggerUiConfigParameters swaggerUiConfigParameters,
									 SwaggerDocProperties swaggerProperties) {
		List<GroupedOpenApi> groups = new ArrayList<>();
    // 读取配置服务,添加接口分组,以服务为纬度进行分组
		for (String value : swaggerProperties.getServices().values()) {
			swaggerUiConfigParameters.addGroup(value);
		}
		return groups;
	}
  
  @Data
	@Component
	@ConfigurationProperties("swagger")
	public class SwaggerDocProperties {

		private Map<String, String> services;
  
  }
}

Nacos 添加配置 application-common.yml

swagger:
		# 是否开启接口文档
    enabled: true
    title: MingYue Swagger API
    gateway: http://${GATEWAY_HOST:mingyue-gateway}:${GATEWAY-PORT:9100}
    token-url: ${swagger.gateway}/auth/oauth2/token
    scope: server
    services:
        mingyue-system-biz: system
        mingyue-auth: auth

mingyue-common-doc

mingyue-common-doc 为本章节新增模块,主要用来管理微服务接口文档模块的依赖与配置

引入依赖

<dependencies>
  <!-- 接口文档 v3 -->
  <dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-webmvc-core</artifactId>
  </dependency>
  <!-- 引入 swagger 页面 -->
  <dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-ui</artifactId>
  </dependency>
  <dependency>
    <groupId>io.swagger.core.v3</groupId>
    <artifactId>swagger-annotations</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-commons</artifactId>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <scope>provided</scope>
  </dependency>
</dependencies>

添加配置项

/**
 * SwaggerProperties
 *
 * @author Strive
 * @date 2023/6/22 11:00
 */
@Data
@ConfigurationProperties(prefix = "swagger")
public class SwaggerProperties {

	/**
	 * 是否开启 swagger
	 */
	private Boolean enabled = true;

	/**
	 * 标题
	 **/
	private String title = "";

	/**
	 * 网关
	 */
	private String gateway;

	/**
	 * 服务转发配置
	 */
	private Map<String, String> services;

}

SwaggerAutoConfiguration

该类作为 Swagger 自动配置类,提供给需要接入 Swagger 文档的微服务们~

import com.csp.mingyue.doc.support.SwaggerProperties;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.SpringDocConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpHeaders;

import java.util.ArrayList;
import java.util.List;

/**
 * Swagger 配置
 *
 * @author Strive
 */
@RequiredArgsConstructor
@AutoConfiguration(before = SpringDocConfiguration.class)
@ConditionalOnProperty(name = "swagger.enabled", havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(SwaggerProperties.class)
@ConditionalOnMissingClass("org.springframework.cloud.gateway.config.GatewayAutoConfiguration")
public class SwaggerAutoConfiguration {

	private final SwaggerProperties swaggerProperties;

	private final ServiceInstance serviceInstance;

	@Bean
	public OpenAPI springOpenAPI() {
		OpenAPI openAPI = new OpenAPI().info(new Info().title(swaggerProperties.getTitle()));

		// oauth2.0 password
		openAPI.addSecurityItem(new SecurityRequirement().addList(HttpHeaders.AUTHORIZATION));
		openAPI.schemaRequirement(HttpHeaders.AUTHORIZATION, this.securityScheme());

		// servers 提供调用的接口地址前缀(敲黑板,重点!!!!)
		List<Server> serverList = new ArrayList<>();
		String path = swaggerProperties.getServices().get(serviceInstance.getServiceId());
		serverList.add(new Server().url(swaggerProperties.getGateway() + "/" + path));
		openAPI.servers(serverList);

		return openAPI;
	}

	/**
	 * 全局添加 token
	 * @return SecurityScheme
	 */
	private SecurityScheme securityScheme() {
		SecurityScheme securityScheme = new SecurityScheme();
		// 类型
		securityScheme.setType(SecurityScheme.Type.APIKEY);
		// 请求头的 name
		securityScheme.setName(HttpHeaders.AUTHORIZATION);
		// token 所在位置
		securityScheme.setIn(SecurityScheme.In.HEADER);
		return securityScheme;
	}

}

Nacos 添加配置 mingyue-gateway.yml

这一小节非常重要,我在这儿卡了很久很久,网关一直聚合微服务文档不成功

由于 SpringDoc 不允许自定义分组机制的默认行为来更改生成的路径,因此我们需要在网关配置中添加一个新的路由定义。它将路径重写 /v3/api-docs/{SERVICE_NAME}/{SERVICE_NAME}/v3/api-docs,由另一个负责与 Nacos 发现交互的路由处理。

# 固定路由转发配置 无修改
- id: openapi
  uri: lb://mingyue-gateway
  predicates:
  	- Path=/v3/api-docs/**
  filters:
  	- RewritePath=/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs

如:http://mingyue-gateway:9100/v3/api-docs/system => http://mingyue-gateway:9100/system/v3/api-docs

启动测试

Swagger 地址

swagger-ui: http://mingyue-gateway:9100/swagger-ui.html

api-docs: http://mingyue-gateway:9100/system/v3/api-docs/

进入 swagger-ui 页面,通过 Select a definition 选择服务 system

image-20230622205045693

选择接口,点击 Try it out 测试接口

image-20230622204204586

关闭 Swagger

通过 Nacos 配置 application-common.yml

swagger:
		# 是否开启接口文档
    enabled: false

再次刷新接口文档,出现以下页面 No operations defined in spec!

image-20230622210829429

小结

至此,SpringCloud Gateway 整合 SpringDoc 聚合其他微服务接口文档已经完成啦~

下一节再将还有一些需要完善的补充完整,休息休息~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Strive_MY

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值