RESTFul API 的 mock server 解決方案

會寫這一篇主要是最近在公司上有遇到我們需要快速迭代與試錯,但在前後端是不一樣的團隊,但在快速迭代的情況下,為了避免不要互相影嚮進度,一個常見的作法就是架設json mock server,也就是設定對應的api 只回應對應的假資料…

這類型的工具也很多,只是最近剛好摸到一個工具覺得是我目前碰過的類似工具之中,最容易上手的,而且可以有GUI可以使用…

Mockoon

這個工具與其它類似工具的主要差異是,它有GUI界面,可以直接在界面上設定要開哪些endpoint與對應的response以後,就可以直接在local 端跑起mock server了。

而且GUI 界面類似於 Postman,所以上手難度很低,稍微摸一下界面就知道它可以做哪些工具了…

Mockoon routes view
reference: https://mockoon.com/docs/latest/gui-cheat-sheet/

其它更多好用的功能像是

  • Proxy configurations

這個是當api request 打進時,mockoon上如果有沒設定的endpoint時,可以指定它轉發到特定的機器。

  • Support openapi/swagger config import

這個顧名思義是可以直接把我們寫的api 文件檔直接丟到mockoon上,這樣對應的endpoints 就被設定好了。

  • Rule based responses

這我覺得也算是蠻客製化的功能,我們可以針對一個endpoint設定多個responses,然後透過一些客製化的規則(rules)來設定mockoon 要回哪個response。

  • Support CLI based runtime

除了gui 界面以外,官方也有支援cli (用npm包的),所以我們可以把local端的mockoon設定檔丟到cloud上的機器,然後就可以在機器上用cli跑起一個對應的mock server。

像是下面一個簡單的 restart.sh 就可以讓重啟linux 上的mockcoon 並且讀取對應的設定檔。

!/bin/bash
 pkill -f "mockoon-cli"
 mockoon-cli start --data mockoon_api_config.json -p 9000 > /dev/null 2>&1 &

透過Restful API傳送檔案

通常如果我們有傳送檔案的需求時,在http的世界裡,我們可以透過restful api定義的兩種content-type來實作:

  • application/x-www-form-urlencoded
  • multipart/form-data

雖然說,之前在工作中也有過一些使用上的經驗,但趁這次工作上又需要碰到,所以來做點筆記。

application/x-www-form-urlencoded

The application/x-www-form-urlencoded content type describes form data that is sent in a single block in the HTTP message body. Unlike the query part of the URL in a GET request, the length of the data is unrestricted.

這裡可以看到,當如果我們需要透過http 傳送單一檔案時,我們可以在body中放入我們需要傳送的檔案;而使用這種方式傳送檔案時,其內容必須遵循以下的encoding rules:

* Control names and values are escaped. Space characters are replaced by `+’, and then reserved characters are escaped as described in [RFC1738], section 2.2: Non-alphanumeric characters are replaced by `%HH’, a percent sign and two hexadecimal digits representing the ASCII code of the character. Line breaks are represented as “CR LF” pairs (i.e., `%0D%0A’).

* The control names/values are listed in the order they appear in the document. The name is separated from the value by `=’ and name/value pairs are separated from each other by `&’.

stackoverflow的這篇文章來看,一般使用這種方式傳送檔案時,平均會增加至少33%的額外流量,所以並不是一個很有效率的方法。

multipart/form-data

In the multipart/form-data content type, the HTTP message body is divided into parts, each containing a discrete section of data.

Each message part requires a header containing information about the data in the part. Each part can contain a different content type; for example, text/plainimage/pngimage/gif, or multipart/mixed. If a parameter specifies multiple files, you must specify the multipart/mixed content type in the part header.

這種類型的content-type,定義了client可以在message body中傳送多個不同的檔案,此外,我們必須為每種檔案設定其檔案類型。

在encoding的部分,這裡被沒有強制使用base64,而是讓客戶端可以指定conding的方式。

根據w3c的文件中提到,multipart 是較適合用來傳送binary file或一些non-ASCII的檔案。

application/octet-stream

通常這種類型的content-type是用來給瀏覽器下載檔案時使用,瀏覽器收到這類型的content-type時,預設就會直接下載到本地端。

但在stackoverflow的這篇文章中有提到,我們其實可以直接透過POST 直接設定content-type 為application/octet-stream,並且在加上以下的header 設定就可以直接指定要傳送的檔案。

Connection: close
Content-Type: application/octet-stream
Content-Length: <content-size>

結論

  • multipart/form-data 已發展多年了,且從文件上來看,在最初定義時就是為了傳送二進制的檔案類型,所以我們若有這方面的需求時,應該盡量使用這個content-type。
  • 如果我們的需求只是傳送單一的小檔案,且又可以使用base64 encoding時,使用application/x-www-form-urlencoded也不失為另一個可考慮的選項。

Reference