本次 more time 为读者👬们介绍 Spring Rest Docs,这是一个用代码写接口文档的工具。
先看看效果
和 swagger 不同,swagger 倾向于自动生成,这个还是得写。至于怎么写呢?Spring Rest Docs 的 Github 给出了更加明确的定义:测试驱动的文档。
说到测试驱动,不得不提测试驱动开发 TDD。总之TDD的核心就是:先写测试,后写代码,这样即能保证代码是对的,又敢重构。
那么这个Spring Rest Docs 这个测试驱动的文档是什么意思呢?
写测试,生成文档。
生成文档的前提是测试通过。
流程就是:写测试 -> 写能通过测试的代码 -> 通过测试 -> 生成文档。
问题在 能通过测试的代码 上,这里有两种选择。
- 符合业务需求的正确代码
- 能通过测试的类似Mock代码
如果选择1,那么这份接口文档的交付时间就是正式代码写好之后
如果选择2,那么这个Mock代码就很浪费,因为mockserver 有 wiremock 解决方案,简单的CRUD还有 json-server
之后还有会有 Spring Cloud Contract , 它实现了消费者驱动契约。
如何将这些技术统一起来,形成一个最佳的工作流,是我最近思考的问题。
光就 Spring Rest Docs 来说
方案1:这份文档是用 CI生成的,这份文档会随着测试驱动开发不断丰富,每新写一个 controller 就丰富这个文档,供用户看,是不断变化的。
方案2:感觉是一种反模式,我第一次就是这么用的。先写 controller,无视输入,直接返回一个值,再写好全部测试,有输入输出,最后来生成。这个好处就是可以立刻交付文档,并且因为通过了测试,这一份代码也可以拿去给其他人当mockserver。
本文的小demo并不是涉及复杂逻辑,主要是带领读者👭们看一看这么用。
小王接到了一个任务,写两个接口,一个GET一个POST
GET 算平方
长这样 GET /sqr?x=2
返回 {"ans": 4}
POST 算和
长这样 POST /sum/3 {``"y": 5}
返回 {"ans": 8}
小王说着太简单了,瞬间写好了——测试,用了mockmvc,这样就先不需要实例化 controller 了。
@Test
fun shouldReturn4whenXis2() {
mockMvc.perform(get("/sqr?x=2"))
.andExpect(jsonPath("$.ans", `is`(4)))
}
@Test
fun shouldReturn8whenXis3andYis5() {
val req = """
{
"y": 5
}
""".trimIndent()
mockMvc.perform(post(