Micro Service工具集之Swagger:可測試的樣式化API文檔

在我之前的一篇博文中,介紹了Yammer開發團隊貢獻的開源微服務開發框架DropWizard(http://ningandjiao.iteye.com/blog/1766498),有了服務之後,開發者最關心的事情是什麼呢? 就是有人用你的服務。而開發者使用一個服務之前,首先需要知道的是該服務的API,目前幾乎所有的開放平臺都是把API以文檔的形式放在網站上,如下:
[img]http://dl2.iteye.com/upload/attachment/0089/7729/b9c40c24-aaee-3730-8b09-6599e947b304.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0089/7727/99f38d66-6302-3ed0-b336-3e393590ccfe.png[/img]

不知道有沒有開發人員和我一樣,有時對一些API說明的理解比較模糊,總想着能直接驗證一下自己的理解就好了,而不是需要去項目寫測試代碼來驗證自己的想法。即API文檔應具備直接執行能力。 Swagger就是這樣的一個利器,其實,Swagger本身的目標比上面描述的要大很多:“Swagger is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. ”。但是,本文中只想聊聊如何通過Swagger爲已有項目的生成具備執行能力的樣式化API文檔。

[b]爲已存在的項目添加Swagger(以DropWizard爲例)[/b]
首先,爲項目引入Swagger依賴包
'com.wordnik:swagger-jaxrs_2.9.1:1.3.0'

然後,把Swagger加入DropWizard的Service中:
private void initSwaggerConfig(Environment environment) {
// Swagger Resource
environment.addResource(new ApiListingResourceJSON());

// Swagger providers
environment.addProvider(new ApiDeclarationProvider());
environment.addProvider(new ResourceListingProvider());

// Swagger Scanner, which finds all the resources for @Api Annotations
ScannerFactory.setScanner(new DefaultJaxrsScanner());

// Add the reader, which scans the resources and extracts the resource information
ClassReaders.setReader(new DefaultJaxrsApiReader());

//Config API information. this information will show on the Swagger UI page
SwaggerConfig config = ConfigFactory.config();
config.setApiVersion("0.1");
config.setApiPath("/api/api-docs"); //Swagger UI 默認把API信息顯示在base_path/api-docs下
config.setBasePath("http://localhost:9090/api");
config.setInfo(Option.apply(new ApiInfo("DropWizard Demo Swagger UI",
"This is just a demo to show how to integrate Swagger UI with a dropwizard project.",
null,
"[email protected]",
null,
null)));
}

接着,給開放API的Resource類加上API Annotation,這樣上一步配置的Scanner就能夠掃描到該Resource開放的API了。
@Path("/helloWorld")
@Api(value = "/helloWorld", description = "Greeting API", position = 1)
@Produces(APPLICATION_JSON)
public class HelloWorldResource {
private final String template;
private final String defaultName;
private final AtomicLong counter;

public HelloWorldResource(String template, String defaultName) {
this.template = template;
this.defaultName = defaultName;
this.counter = new AtomicLong();
}

@GET
@Path("/{name}")
@ApiOperation(value = "Greeting by Name",
notes = "Say hello to the people",
response = SayingRepresentation.class,
position = 0)
@ApiResponses(value = {
@ApiResponse(code = 400, message = "No Name Provided")
})
@Produces(APPLICATION_JSON)
@Timed
public SayingRepresentation sayHello(@ApiParam(value = "name for greeting", required = true) @PathParam("name") String name) {
return new SayingRepresentation(counter.incrementAndGet(), String.format(template, name != null ? name : defaultName))
;
}
}

在Swagger Annotation中:
[list]
[*]@API表示一個開放的API,可以通過description簡要描述該API的功能。
[*]在一個@API下,可有多個@ApiOperation,表示針對該API的CRUD操作。在ApiOperation Annotation中可以通過value,notes描述該操作的作用,response描述正常情況下該請求的返回對象類型。
[*]在一個ApiOperation下,可以通過ApiResponses描述該API操作可能出現的異常情況。
[*]@ApiParam用於描述該API操作接受的參數類型
[/list]
再接着,爲項目的Model對象添加Swagger Annotation,這樣Swagger Scanner可以獲取更多關於Model對象的信息。
@ApiModel(value = "A SayingRepresentation is a representation of greeting")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class SayingRepresentation {
private long id;
@ApiModelProperty(value = "greeting content", required = true)
private String content;

public SayingRepresentation(long id, String content) {
this.id = id;
this.content = content;
}

public long getId() {
return id;
}

public String getContent() {
return content;
}
}

通過上面的步驟,項目已經具備了提供Swagger格式的API信息的能力,接下來,我們把這些信息和Swagger UI集成,以非常美觀,實用的方式把這些API信息展示出來。

[b]和Swagger UI的集成[/b]
首先,從github(https://github.com/wordnik/swagger-ui)上下載Swagger-UI, 把該項目dist目錄下的內容拷貝到項目的resources的目錄assets下。
[img]http://dl2.iteye.com/upload/attachment/0089/7721/dd23a10c-05ff-3751-8c44-89116783de99.png[/img]
然後,修改index.html, 把Swagger UI對象中的URL替換爲自己的API路徑。
 window.swaggerUi = new SwaggerUi({
url: "/api/api-docs",
dom_id: "swagger-ui-container",

最後,爲了能訪問到該頁面,還需要在Service的Initialize方法中,添加AssetsBundle,
public void initialize(Bootstrap<HelloWorldConfiguration> bootstrap) {
//指定配置文件的名字
bootstrap.setName("helloWorld");
bootstrap.addBundle(new AssetsBundle("/assets", "/", "index.html"));
}

最後的效果圖:
[img]http://dl2.iteye.com/upload/attachment/0089/7723/7edd8285-7fe7-3392-966d-863ab4ad3db5.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0089/7725/e52b71ab-5c67-3d14-bc3a-ef3b904c2c94.png[/img]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章