使用Swagger自動產生API文件

11
6 min readJan 1, 2020

--

首先我們先來了解什麼是Swagger,Swagger是一個工具讓你的後端API接口可以更視覺化被呈現,透過Swagger UI工具可以產生HTML && CSS && Javascript產生網頁版的API文件。當然Swagger可不只是只能產生API文件,它也可用來做測試API接口,或是也可以搭配Postman使用等…

Swagger.io官方圖片
我的Swagger範例

為甚麼要用Swagger,以下是我整理覺得可以帶來的好處

  1. 好的開發文件可以讓User知道如何使用API接口
  2. 可以讓前端Developer在接API可以一目瞭然需要去餵什麼參數並會拿回什麼樣的資料,可以大幅讀提升開發效率。
  3. 專案有寫出來的 Code 等同於技術文件,減少額外寫文件及維護文件的成本
  4. 使用線上文件進行測試,透過網頁立即知道 API 返回的結果,節省溝通時間提升效率

那什麼樣的情況下使用Swagger?

  1. 當專案複雜程度到達一定規模時,當前後端需要花大量時間溝通需要什麼樣的資料時候。
  2. 反之,如果專案規模不大或是開發者只有你自己的時候,其實這時候或許導入Swagger就沒有那麼必要。
  3. 如果你的後端要變成OpenAPI,那你是必須要撰寫文件讓使用者可以知道怎麼使用你的API

進入正題~~

在開始進行Swagger撰寫前,你需要準備一份專案,接者把package裝進專案內。

$ npm i swagger-jsdoc swagger-ui-express --save-dev

接者在你的專案的端口處(index.js/app.js)引入

const swaggerJsdoc = require('swagger-jsdoc');const swaggerUi = require('swagger-ui-express');

接者swagger-jsdoc會依照Yaml去自動產生swagger.json妳需要的api文件

const options = {  swaggerDefinition: {
// 這邊會是你的api文件網頁描述
info: { title: 'ec_web_demo API', version: '1.0.0', description: 'Generate ec_web_demo API document with swagger' } },
// 這邊會是你想要產生的api文件檔案,我是直接讓swagger去列出所有controllers
apis: ['./controllers/*.js']};
const specs = swaggerJsdoc(options);

這時候接下來設定endpoint讓swagger-ui-express可以呈現出畫面

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs));

設定就只要這樣~~

$ npm run dev

到http://localhost:3000/api-docs就可以看到你的api文件囉,點進去每一個endpoint可以看你設定細節,至於api文件寫法可以參考Swagger官網https://swagger.io/docs/specification/about/

接者要寫的就是YAML,才可以讓你的文件產生出來

可以大致參考一下我的寫法,寫不好的地方麻煩您跟我說一下🙇‍♂️🙇‍♂️

/*** @swagger* /admin/products/:id:*    put:*      description: Revise Existing Prodcuts*      operationId: replaceProduct*      parameters:*      - name: Bearer_Token*        type: string*        in: header*        required: true*      - name: productId*        in: path*        description: ID of product to return*        required: true*        schema:*          type: integer*          format: int64*      - name: name*        type: string*        in: body*        required: false*      - name: description*        type: string*        in: body*        required: false*      - name: cost*        type: integer*        in: body*        required: false*      - name: price*        type: integer*        in: body*        required: false*      - name: height*        type: integer*        in: body*        required: false*      - name: width*        type: integer*        in: body*        required: false*      - name: length*        type: integer*        in: body*        required: false*      - name: weight*        type: integer*        in: body*        required: false*      - name: material*        type: string*        in: body*        required: false*      - name: CategoryId*        type: integer*        in: body*        required: false*      security:*        - bearerAuth: []*      responses:*         200:*           description: success*         400:*           description: error*/

謝謝大家的觀看~~

--

--