我的用户Spring Cloud Gateway是基于Webflux的,在我的MicroService开发中,每个Service都有一个带有UI的Swagger ...到目前为止没有问题。现在,我将所有Swagger集中到我的网关中,我发现了大量Zuul网关的示例代码...我认为这可以工作。但是找不到关于spring.cloud.Gateway的任何示例,它基于反应式Webflux接口,具有'springfox:springfox-spring-webflux:3.0.0-SNAPSHOT'依赖关系,我得到了SwaggerUI,但无法集中所有我从其他MicroService获得的Swagger我不知道如何配置SwaggerResourcesProvider ...
我不知道我是否应该做一个自己的MicroService(没有Webflux)来处理所有Swaggers,我认为这不是问题。 问题是WebFlux的问题:-)
也许有人建议我做一个自己的MicroService(这应该可以,但是我不确定这是否是最重要的)。或者有人可以解决我的问题。
答案 0 :(得分:1)
我使用Spring Fox与Spring Fox网关创建了醒目的UI。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
@Primary
@Configuration
public class SwaggerConfig implements SwaggerResourcesProvider {
@Autowired
private RouteLocator routeLocator;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
// I used service names with lowercase hence the toLowerCase.
// Remove the toLowerCase if you use service name with caps as is default with eureka.
routeLocator.getRoutes().subscribe(route -> {
String name = route.getId().split("_")[1];
resources.add(swaggerResource(name, "/" + name.toLowerCase() + "/v3/api-docs", "1.0"));
});
return resources;
}
private SwaggerResource swaggerResource(final String name, final String location,
final String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}
答案 1 :(得分:0)
我遇到了同样的问题,但找不到一个干净的解决方案,因为Swagger
和Webflux
之间还没有集成。
另一方面,我成功设置了一个最小的配置来为swagger创建代理。
首先,您需要创建一个公开Swagger
API和资源的控制器:
@Controller
public class SwaggerController {
private final JsonSerializer jsonSerializer;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerController(JsonSerializer jsonSerializer, SwaggerResourcesProvider swaggerResources) {
this.jsonSerializer = jsonSerializer;
this.swaggerResources = swaggerResources;
}
@RequestMapping({"/swagger-resources/configuration/security"})
@ResponseBody
public ResponseEntity<SecurityConfiguration> securityConfiguration() {
return ResponseEntity.ok(SecurityConfigurationBuilder.builder().build());
}
@RequestMapping({"/swagger-resources/configuration/ui"})
@ResponseBody
public ResponseEntity<UiConfiguration> uiConfiguration() {
return ResponseEntity.ok(UiConfigurationBuilder.builder().build());
}
@RequestMapping({"/swagger-resources"})
@ResponseBody
public ResponseEntity<List<SwaggerResource>> swaggerResources() {
return ResponseEntity.ok(this.swaggerResources.get());
}
@RequestMapping(
value = {"/v2/api-docs"},
method = {RequestMethod.GET},
produces = {"application/json", "application/hal+json"}
)
@ResponseBody
public ResponseEntity<Json> getDocumentation() {
Swagger swagger = new Swagger();
return ResponseEntity.ok(this.jsonSerializer.toJson(swagger));
}
}
接下来,您需要一个swagger配置来从您的微服务创建Swagger资源:
package fr.samse.bravo.rechercheProduit.gateway.config;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import springfox.documentation.spring.web.json.JacksonModuleRegistrar;
import springfox.documentation.spring.web.json.JsonSerializer;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@Configuration
public class SwaggerConfig {
private final GatewayProperties properties;
public SwaggerConfig(GatewayProperties properties) {
this.properties = properties;
}
@Bean
public JsonSerializer jsonSerializer(List<JacksonModuleRegistrar> moduleRegistrars) {
return new JsonSerializer(moduleRegistrars);
}
@Primary
@Bean
@Lazy
public SwaggerResourcesProvider swaggerResourcesProvider() {
return () -> properties.getRoutes().stream()
.map(route -> createResource(route.getId(), getRouteLocation(route), "2.0"))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
// You will certainly need to edit this
private String getRouteLocation(RouteDefinition route) {
return Optional.ofNullable(route.getPredicates().get(0).getArgs().values().toArray()[0])
.map(String::valueOf)
.map(s -> s.replace("*", ""))
.orElse(null);
}
private SwaggerResource createResource(String name, String location, String version) {
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location + "/v2/api-docs");
swaggerResource.setSwaggerVersion(version);
return swaggerResource;
}
}
我认为,如果您使用服务发现服务器,则此解决方案将不起作用,但就我而言,我不需要这样做,因为我有spring.cloud.gateway.routes
的配置:
- id: api-client
uri: lb://client
predicates:
- Path=/api/client/**
这很容易从Eureka或Consul获取服务位置。
让我知道它是否有效。如果有人找到了另一种选择,我很感兴趣。