撇開微服務這個架構, 其實一般在開發應用, 多少都會有呼叫對方或是被對方呼叫 API 的溝通模式,
以前常常會拿到一份過時的 API 規格書....為什麼? 你懂的 寫文件這件事大家都懶XD,
你要工程師每次開發都要去檢查 修改 文件真的是很難的一件事
所以我們來透過 Swagger 來製作線上版 API 規格文件吧~~
首先我們先在 build.gradle 增加
dependencies {
compile 'io.springfox:springfox-swagger2:2.7.0'
compile 'io.springfox:springfox-swagger-ui:2.7.0'
compile 'io.springfox:springfox-data-rest:2.7.0'
}
springfox-swagger2 這是我們主要的套件
springfox-swagger-ui 這個會有個 Html 的頁面讓你操作
springfox-data-rest 一般他只會讀我們自己寫的 API, 加入住個會把 Spring Data Rest 讀出來
再來我們訂製輸入輸出的物件 BookDto.java
package com.example.book;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(description = "書本資料")
public class BookDto {
@ApiModelProperty(value = "序號", required = true)
private Integer bookid;
@ApiModelProperty(value = "書名", required = true)
private String name;
@ApiModelProperty(value = "作者", required = true)
private String author;
}
這些 ApiModel, ApiModelProperty 都是到時候 Swagger 會幫我們輸出在 UI 上可以給對方看的,
所以要好好寫啊, 開發時一併寫好, 有修改的話也是順手調整, 省去大量維護的時間
接下來我們稍稍修改一下我們的 BookController.java
package com.example.book;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(tags = "Book")
@RestController
@RequestMapping(value = "/api")
public class BookController {
@Autowired
private BookRepository bookRepository;
@ApiOperation(value = "取得書本", notes = "列出所有書本")
@ResponseStatus(HttpStatus.OK)
@GetMapping(value = "/v1/book", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public List<Book> getAll() {
return bookRepository.findAll();
}
@ApiOperation(value = "新增書本", notes = "新增書本的內容")
@ApiResponses(value = {@ApiResponse(code = 201, message = "存檔成功")})
@ResponseStatus(HttpStatus.CREATED)
@PostMapping(value = "/v1/book", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public BookDto create(
@ApiParam(required = true, value = "書本內容") @RequestBody BookDto bookDto) {
Book book = new Book();
book.setBookid(bookDto.getBookid());
book.setName(bookDto.getName());
book.setAuthor(bookDto.getAuthor());
book = bookRepository.save(book);
bookDto.setBookid(book.getBookid());
return bookDto;
}
@ApiOperation(value = "取得書本內容", notes = "取得書本內容")
@ApiResponses(value = {@ApiResponse(code = 200, message = "書本資訊")})
@ResponseStatus(HttpStatus.OK)
@GetMapping(value = "/v1/book/{bookid}", produces = MediaType.APPLICATION_JSON_VALUE)
public BookDto get(
@ApiParam(required = true, name = "bookid", value = "書本ID") @PathVariable Integer bookid) {
Book book = bookRepository.findOne(bookid);
BookDto bookDto = new BookDto();
bookDto.setBookid(book.getBookid());
bookDto.setName(book.getName());
bookDto.setAuthor(book.getAuthor());
return bookDto;
}
}
這邊三支 API 都有加上對應的 API 描述
然後我們配置 swagger 的啟動 SwaggerConfig.java
package com.example.book;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.documentation.spring.data.rest.configuration.SpringDataRestConfiguration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@Import(SpringDataRestConfiguration.class)
public class SwaggerConfig {
}
這樣就可以了
那這個 SpringDataRestConfiguration 是要幹嘛的?
剛不是提到 Spring Data Rest 的功能嗎?
除了加上依賴以外, 別忘了還要加上這個才會引入 Spring Data 的 RestAPI 喔~
服務啟動後我們進入 swagger 的 ui
http://localhost:8080/swagger-ui.html
畫面如下
basic-error-controller 這個先不用管
http://localhost:8080/swagger-ui.html#/Book 這個就是我們開發的 API
點開來看呢, 你可以很方便看到我們寫的 API 說明
今天我們要新增一本書
可以很方便知道 新增完的 Http code 及回覆的資料 跟各屬性的說明與資料型態
那我們的 Request 要送什麼在更下面一點
你也可以看到要送資料到 request 的 body,並且知道格式跟型態
點一下 Example Value 的內容框...他會把範例放到左邊的 Value 欄位
也還是有屬性的說明可以看喔
當你填好資料後按送出...Try it out
直接在頁面上知道你的測試資料是不是對的
記得把 bookid 拿掉...那是資料庫產生的,
實際上在寫的時候我常會分 CresteDto UpdateDto 新增跟更新的欄位常會有點差異
好了測試成功....
是不是很方便呢?
修改的時候也可以順手把程式改一下
省得再去找文件, 再開 word, 再找改的地方, 修正成最新 這樣煩人的文件維護工作了
請問到swagger-ui.html會顯示,該如何處理?
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Wed May 26 10:48:08 CST 2021
There was an unexpected error (type=Not Found, status=404).
已解決
新版swagger使用
'io.springfox:springfox-boot-starter:3.0.0'
取代原先的
'io.springfox:springfox-swagger2:2.7.0'
'io.springfox:springfox-swagger-ui:2.7.0'
'io.springfox:springfox-data-rest:2.7.0'
連線網頁則為http://localhost:8080/swagger-ui/index.html#