The better api with swagger

背景

RESTful(Representational State Transfer)是目前(最)流行的API设计风格。
当我们的平台的API增加的一定数量时,如何以一种更好的方式来管理维护这些API呢?

WIKI

The better api with swagger_第1张图片
wiki api

The better api with swagger_第2张图片
api content
  1. 增加了程序猿的工作量
  2. 每次修改API参数、请求方式、返回值等都要同步的去修改wiki api文档,通常情况下是没及时更新,后来后来两边就无法对应起来了,这个时候wiki api已经失去了意义。
  3. 没办法优雅的单元测试

swagger

Swagger is a simple yet powerful representation of your RESTful API. With the largest ecosystem of API tooling on the planet, thousands of developers are supporting Swagger in almost every modern programming language and deployment environment. With a Swagger-enabled API, you get interactive documentation, client SDK generation and discoverability.
http://swagger.io/
https://github.com/swagger-api/swagger.io

下面我们举个简单的栗子(spring-boot+swagger):

  1. 加入swagger依赖

    io.springfox
    springfox-swagger2
    2.3.1


    io.springfox
    springfox-swagger-ui
    2.3.1

  2. swagger配置
    @SpringBootApplication
    @EnableAutoConfiguration
    @EnableSwagger2
    @ComponentScan(value = {
    "com.dcf", "com.iqunxing"
    })
    public class ApplicationConfig extends SpringBootServletInitializer {

        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(ApplicationConfig.class);
        }
    
        @Autowired
        private TypeResolver typeResolver;
    
        @Bean
        public Docket petApi() {
            return new Docket(DocumentationType.SWAGGER_2)
             .forCodeGeneration(true)
             .apiInfo(
                     new ApiInfo("rest API接口文档", "客户营销 - 企业官网自助建站", "v0.0.1", null, "[email protected]", null,
                             null))
             .select()
             .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
             .paths(PathSelectors.any())
             .build()
             .pathMapping("/")
             .directModelSubstitute(LocalDate.class, String.class)
             .genericModelSubstitutes(ResponseEntity.class)
             .alternateTypeRules(
                     newRule(typeResolver.resolve(DeferredResult.class,
                             typeResolver.resolve(ResponseEntity.class, WildcardType.class)),
                             typeResolver.resolve(WildcardType.class)))
             .useDefaultResponseMessages(false)
             .globalResponseMessage(
                     RequestMethod.GET,
                     newArrayList(new ResponseMessageBuilder().code(500).message("500 message")
                             .responseModel(new ModelRef("Error")).build()));
     // 如果需要鉴权,请放开以下注释行->
     // .securitySchemes(newArrayList(apiKey()))
     // .securityContexts(newArrayList(securityContext()))
     // <-如果需要鉴权,请放开以上注释行
     // 如果需要全局性参数,请放开以下注释行->
     // .globalOperationParameters(
     // newArrayList(new ParameterBuilder()
     // .name("someGlobalParameter")
     // .description(
     // "Description of someGlobalParameter")
     // .modelRef(new ModelRef("string"))
     // .parameterType("query").required(true).build()));
     // <-如果需要全局性参数,请放开以上注释行
     // 如果需要UrlTemplating,请放开以下注释行->
     // .enableUrlTemplating(true);
     // <-如果需要UrlTemplating,请放开以上注释行
        }
    }
    
  3. controller里增加API说明
    @Api(tags = {
    "企业官网创建编辑"
    })
    @RestController
    @RequestMapping("/services/")
    public class CustomerSiteController {

        @Autowired
        private ICustomerSiteService customerSiteService;
    
        @Autowired
        private IUserService userService;
    
        @ApiOperation(value = "查询企业所有信息 - [MARKETING-CS-CS-01]", response = GetCustomerSiteRsp.class, notes = "[SELECT]dcf_user.user,dcf_customer.site_addition,dcf_customer.site_basic,dcf_customer.site_addition,dcf_customer.site_contact,dcf_customer.site_domain,dcf_customer.site_flash,dcf_customer.site_goods,dcf_customer.site_online_shop")
        @RequestMapping(value = "/getCustomerSite", method = RequestMethod.GET)
        public Response getCustomerSite() {
            String currentUserId = SecurityUtils.getCurrentUserId();
            User currentUser = userService.getUserByPk(currentUserId);
            GetCustomerSiteReq req = new GetCustomerSiteReq();
            req.setCustomerId(currentUser.getCustomerId());
            GetCustomerSiteRsp rsp = customerSiteService.getCustomerSite(req);
            if (StringUtils.equals(RetCodeConst.SUCCESS, rsp.getRetCode())) {
                return Response.success(rsp);
            }
            return Response.fail(null, "查询企业信息失败");
        }
    }
    

大功告成,我们来看下效果吧


swagger api doc

定制后的效果

那么优点就显而易见咯:

  1. 更少的工作量(除配置外)
  2. 和代码同步更新,减少维护成本
  3. 支持单元测试
  4. 文档规范统一

错误之处请包涵并指出,谢谢

你可能感兴趣的:(The better api with swagger)