iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
0

撇開微服務這個架構, 其實一般在開發應用, 多少都會有呼叫對方或是被對方呼叫 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
畫面如下
swagger ui

basic-error-controller 這個先不用管

http://localhost:8080/swagger-ui.html#/Book 這個就是我們開發的 API

點開來看呢, 你可以很方便看到我們寫的 API 說明
API 說明

今天我們要新增一本書
新增書本1
可以很方便知道 新增完的 Http code 及回覆的資料 跟各屬性的說明與資料型態

那我們的 Request 要送什麼在更下面一點

你也可以看到要送資料到 request 的 body,並且知道格式跟型態
點一下 Example Value 的內容框...他會把範例放到左邊的 Value 欄位
也還是有屬性的說明可以看喔

當你填好資料後按送出...Try it out
直接在頁面上知道你的測試資料是不是對的
記得把 bookid 拿掉...那是資料庫產生的,
實際上在寫的時候我常會分 CresteDto UpdateDto 新增跟更新的欄位常會有點差異

好了測試成功....

是不是很方便呢?

修改的時候也可以順手把程式改一下
省得再去找文件, 再開 word, 再找改的地方, 修正成最新 這樣煩人的文件維護工作了


上一篇
Day 04 - 增加 Rest Repositories 讓 Spring Data 直接升級為 RestAPI
下一篇
Day 06 - 將 Swagger 規格說明匯出成 PDF 文件
系列文
30天從零開始 使用 Spring Boot 跟 Spring Cloud 建構完整微服務架構35

尚未有邦友留言

立即登入留言