前后端分离
按照现在的趋势,前后端分离几乎已经是业界对开发和部署方式所达成的一种共识。所谓的前后端分离,并不是传统行业中的按部门划分,一部分人只做前端(HTML/CSS/JavaScript等等),另一部分人只做后端(或者叫服务端),因为这种方式是不工作的:比如很多团队采取了后端的模板技术(JSP, FreeMarker, ERB等等),前端的开发和调试需要一个后台Web容器的支持,从而无法将前后端开发和部署做到真正的分离。
通常,前后端分别有着自己的开发流程,构建工具,测试等。做前端的谁也不会想要用Maven或者Gradle作为构建工具,同样的道理,做后端的谁也不会想要用Grunt或者Gulp作为构建工具。前后端仅仅通过接口来协作,这个接口可能是JSON格式的RESTFul的接口,也可能是XML的,重点是后台只负责数据的提供和计算,而完全不处理展现。而前端则负责拿到数据,组织数据并展现的工作。这样结构清晰,关注点分离,前后端会变得相对独立并松耦合。但是这种想法依然还是很理想化,前后端集成往往还是一个很头痛的问题。比如在最后需要集成的时候,我们才发现最开始商量好的数据结构发生了变化,而且这种变化往往是在所难免的,这样就会增加大量的集成时间。
归根结底,还是前端或者后端感知到变化的时间周期太长,不能“及时协商,尽早解决”,最终导致集中爆发。怎么解决这个问题呢?我们需要提前协商好一些契约,并将这些契约作为可以被测试的中间产品,然后前后端都通过自动化测试来检验这些契约,一旦契约发生变化,测试就会失败。这样,每个失败的测试都会驱动双方再次协商,有效的缩短了反馈周期,并且降低集成风险。具体的实践方式,请参加我同事的一篇博文,“前后端分离了,然后呢?”http://icodeit.org/2015/06/whats-next-after-separate-frontend-and-backend/。
不过,仅仅靠纪律是不够的,还需要通过工具的辅助来提高效率。下面,我们就来看一下,一个API设计工具——Swagger,将如何帮助我们更好的实现“前后端分离”。
两款更符合前后分离的
swagger-bootstrap-ui:https://gitee.com/xiaoym/swagger-bootstrap-ui
swagger-mg-ui:https://gitee.com/zyplayer/swagger-mg-ui
封装swagger依赖,方便使用
pom核心依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.open.capacity</groupId>
<artifactId>inner-intergration</artifactId>
<version>2.0.1</version>
</parent>
<artifactId>swagger-spring-boot-starter</artifactId>
<description>API文档支撑</description>
<properties>
<swagger.version>2.9.2</swagger.version>
<swagger.m.version>1.0.6</swagger.m.version>
</properties>
<dependencies>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>com.zyplayer</groupId>
<artifactId>swagger-mg-ui</artifactId>
<version>${swagger.m.version}</version>
</dependency>
</dependencies>
</project>
使用方法
<!-- swagger -->
<dependency>
<groupId>com.open.capacity</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</dependency>
SwaggerConfig 自动形成swagger文档核心代码
以认证中心代码为例
认证中心代码
@Component
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Bean
public Docket createRestApi() {
ParameterBuilder tokenPar = new ParameterBuilder();
List<Parameter> pars = new ArrayList<>();
tokenPar.name("Authorization").description("令牌").
modelRef(new ModelRef("string")).
parameterType("header").required(false).build();
ParameterBuilder clientPar = new ParameterBuilder();
clientPar.name("client_id").description("应用ID").
modelRef(new ModelRef("string")).
parameterType("header").required(false).build();
ParameterBuilder secretPar = new ParameterBuilder();
secretPar.name("client_secret").description("应用密钥").
modelRef(new ModelRef("string")).
parameterType("header").required(false).build();
pars.add(tokenPar.build());
pars.add(clientPar.build());
pars.add(secretPar.build());
return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()
// .apis(RequestHandlerSelectors.basePackage("com.open.capacity"))
.apis(RequestHandlerSelectors.any())
.paths( input ->
PathSelectors.regex("/oauth/client.*").apply(input) ||
PathSelectors.regex("/oauth/user.*").apply(input) ||
PathSelectors.regex("/oauth/get.*").apply(input) ||
PathSelectors.regex("/oauth/userinfo.*").apply(input) ||
PathSelectors.regex("/oauth/remove.*").apply(input) ||
PathSelectors.regex("/oauth/refresh/token.*").apply(input)||
PathSelectors.regex("/oauth/token/list.*").apply(input)||
PathSelectors.regex("/clients.*").apply(input)||
PathSelectors.regex("/services.*").apply(input)||
PathSelectors.regex("/redis.*").apply(input)
)
// .paths(PathSelectors.any())
.build().globalOperationParameters(pars);
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder().title("认证中心swagger接口文档").description("认证中心swagger接口文档").version("1.0").build();
}
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/");
resolver.setSuffix(".html");
return resolver;
}
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// super.addResourceHandlers(registry);
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
访问网关swagger-ui
http://127.0.0.1:9200/swagger-ui.html
image
访问认证中心swagger-ui
http://127.0.0.1:8000/doc.html(http://127.0.0.1:8000/api-auth/doc.html)
注意查看认证中心代码
image
如果有上下文路径
## 接口地址 http://127.0.0.1:8000/api-auth/doc.html
image
image
访问用户中心swagger-ui
image
企业微服务开放平台 ,历经多家公司生产考验
- 基于layui前后端分离的企业级微服务架构
- 兼容spring cloud netflix & spring cloud alibaba
- 优化Spring Security内部实现,实现API调用的统一出口和权限认证授权中心
- 提供完善的企业微服务流量监控,日志监控能力
- 提供完善的压力测试方案
- 提供完善的微服务部署方案
项目演示地址
http://59.110.164.254:8066/login.html 用户名/密码:admin/admin
项目监控地址
http://47.98.236.203:3000 用户名/密码:admin/1q2w3e4r