在分享培训了swagger对于API的设计以后,有一些人问我说:你看,如今我们前端使用web_API作为mock data在进行测试,后端也有mock 测试。而后咱们再进行联调,这之中确定会出现一些误差。有没有一种方案是:前端不用写mock数据测试,从一开始,就由后端提供一个在线运行的服务,以此减小后期联调的工做量! 答案是:能够!css
固然,在最开始,因为我近期在作API网关的一些工做,我直接简单粗暴的,将swagger的API文档,导入了网关,由网关作了一个mock服务提供。额,如今想来很不负责哈(由于我在作那一块的内容,图省事儿,并无过多去想当时那个项目的现状),后来想了想,那个项目并不须要专门搭建网关去作这么个服务,而且因为它的架构设计,若是再增长网关服务,会额外增添一些工做量和难度。而后,我看了看笔记,再溜了一圈swagger的网站,得出的解决方案为:html
1,利用codegen当即生成可运行的工程前端
2,直接将服务注册到Dubbo,以供前端使用java
备注:公司对于Dubbo这块内容很熟悉了,我主要介绍一下从swagger的API文档,生成可部署工程的过程(其实,这中间还有不少须要进行我的总结,好比嵌入式服务器Jetty,还有我解决一些问题的过程思考和思路总结)!git
这个特别简单,真的特别简单,简单得不能再简单。(固然,我用百度,或者说查到的中文资料,关于从API生成到工程,几乎为零。不过,好在后期集成swagger的还很多,虽然比较复杂)github
首先,是看swagger官方对于codegen是怎么说的:https://swagger.io/docs/swagger-tools/#installation-11 web
而后,再看看具体的命令怎么写:https://github.com/swagger-api/swagger-codegen/wiki/Server-stub-generator-HOWTOspring
最后,看看对于swagger editor示例中的API,在各类语言下生成的工程示例:https://github.com/swagger-api/swagger-codegen 备注:具体的语言示例路径为:https://github.com/swagger-api/swagger-codegen/tree/master/samples/server/petstorejson
实例:好比说我用swagger编辑了一个basic API,那么生成JAX-RS(Jersey)的工程命令以下:后端
java -jar J:\swagger-codegen-cli-2.2.1.jar generate -i "C:\Users\10283_000\Desktop\API lifecycle\Basic.json" -l jaxrs -o jaxrs/jersey2
简单粗暴,而后,运行方式为,在工程的Pom.xml同路径下,执行:mvn jetty:run
而后,没你啥事儿了,开始用吧! 这是一个运行状态的服务,你有两种方式,能够把这个服务变成一个mock service,第一:也就是比较省事儿的,直接在编辑API文档的时候,给设置一个example值; 第二:在这个工程中,设置其指定返回值
这个过程,对于我我的来讲,要反思的内容,有点多,额!!!我感受,颇有必要给贴一下代码,再次强调,我只执行了一行命令,别的,我什么都没有作:看看主要的几个点吧(以JAX-RS:Jersey为例):
这是整个项目工程的结构图,全部的代码均是自动生成。开发人员,只须要专一于我用红圈画起来的类的实现就OK了! 其余的一些公共问题,好比说跨域,JSON,异常等,已经被简单处理过。若是要求不是特别高,特别严密,那么直接使用是彻底能够的! 再,展现一下关键的类(额,用的swagger API 是我第一次学的时候导出的JSON文件,并非很完善,吐槽不要太过度)
API接口类:
package io.swagger.api;
import io.swagger.model.*;
import io.swagger.api.ResourcesApiService;
import io.swagger.api.factories.ResourcesApiServiceFactory;
import io.swagger.annotations.ApiParam;
import io.swagger.jaxrs.*;
import io.swagger.model.Build;
import java.util.List;
import io.swagger.api.NotFoundException;
import java.io.InputStream;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.*;
@Path("/resources")
@Consumes({ "application/json" })
@Produces({ "application/json" })
@io.swagger.annotations.Api(description = "the resources API")
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaJerseyServerCodegen", date = "2017-08-21T09:59:53.975+08:00")
public class ResourcesApi {
private final ResourcesApiService delegate = ResourcesApiServiceFactory.getResourcesApi();
@POST
@Path("/api/tb-build")
@io.swagger.annotations.ApiOperation(value = "", notes = "新增一个建筑", response = void.class, tags={ "建筑", })
@io.swagger.annotations.ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 200, message = "新增建筑成功!", response = void.class),
@io.swagger.annotations.ApiResponse(code = 404, message = "找不到API服务", response = void.class),
@io.swagger.annotations.ApiResponse(code = 200, message = "未知错误", response = void.class) })
public Response addBuild(@ApiParam(value = "Pet object that needs to be added to the store" ,required=true) Build body
,@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.addBuild(body,securityContext);
}
@GET
@Path("/api/tb-build")
@io.swagger.annotations.ApiOperation(value = "", notes = "获取全部的建筑信息", response = void.class, tags={ "建筑", })
@io.swagger.annotations.ApiResponses(value = {
@io.swagger.annotations.ApiResponse(code = 200, message = "操做成功", response = void.class),
@io.swagger.annotations.ApiResponse(code = 404, message = "找不到API服务", response = void.class),
@io.swagger.annotations.ApiResponse(code = 200, message = "未知错误", response = void.class) })
public Response getBuild(@ApiParam(value = "Status values that need to be considered for filter",required=true) @QueryParam("buildId") String buildId
,@Context SecurityContext securityContext)
throws NotFoundException {
return delegate.getBuild(buildId,securityContext);
}
}
APIService类:
package io.swagger.api;
import io.swagger.api.*;
import io.swagger.model.*;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import io.swagger.model.Build;
import java.util.List;
import io.swagger.api.NotFoundException;
import java.io.InputStream;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaJerseyServerCodegen", date = "2017-08-21T09:59:53.975+08:00")
public abstract class ResourcesApiService {
public abstract Response addBuild(Build body,SecurityContext securityContext) throws NotFoundException;
public abstract Response getBuild(String buildId,SecurityContext securityContext) throws NotFoundException;
}
APIServiceImpl类:
package io.swagger.api.impl;
import io.swagger.api.*;
import io.swagger.model.*;
import io.swagger.model.Build;
import java.util.List;
import io.swagger.api.NotFoundException;
import java.io.InputStream;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
@javax.annotation.Generated(value = "class io.swagger.codegen.languages.JavaJerseyServerCodegen", date = "2017-08-21T09:59:53.975+08:00")
public class ResourcesApiServiceImpl extends ResourcesApiService {
@Override
public Response addBuild(Build body, SecurityContext securityContext) throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
@Override
public Response getBuild(String buildId, SecurityContext securityContext) throws NotFoundException {
// do some magic!
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK, "magic!")).build();
}
}
其实,我很不想说这一点的,由于写这个集成的有不少,我也看了不少,我之因此写它,是由于我感受我找到的这种方式,是相对比较简单的。代码写完后,集成swagger作基本的文档处理,其实特别简单,简单到只有两步:
第一:在pom文件中,添加依赖(版本的话,你随意)
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.5.0</version>
</dependency>
<bean class="springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration" id="swagger2Config"/>
<mvc:resources location="classpath:/META-INF/resources/" mapping="swagger-ui.html"/>
<mvc:resources location="classpath:/META-INF/resources/webjars/" mapping="/webjars/**"/>
第三步:经过使用swagger的API注解,增添一些额外的注释说明
其实,这些东西,都挺容易的。但中间也遇到了一些问题,也包括由于本身主要所在项目是java EE体系的,本身就主要关心、解决java EE这边可能会面临的问题,但对于公司其余项目,相对来讲,并不那么上心。这个态度,真是很low啊!
接下来,会总结一些在这个过程之中的一些思惟方式,以及遇到的一些问题和解决过程、解决方案!