發表文章

如何使用 RxJS 處理分頁 API

這篇文章會以 node-github 的 getCommits API 為例,介紹如何使用 RxJS 取得所有分頁的 commits 結果。前言以往在處理分頁的 API,通常都會使用遞回運算,這會讓程式碼的可讀性不佳。有鑒於最近 RxJS 正夯,想說來試著寫寫看,於是就有了這篇分享文章。需求首先,因為 node-github 的 getCommits API 回傳的是一個 Promise 物件,所以需要先使用 RxJS 的 fromPromise 將它轉成 Observable:Rx.Observable .fromPromise(getCommits(...)) 接下來,利用 node-github 提供的 hasNextPagegetNextPage,搭配 RxJS 的 expand 來處理分頁的遞回運算:Rx.Observable ... .expand( (response) => hasNextPage(response) ? Rx.Observable.fromPromise(getNextPage(response)) : Rx.Observable.empty() ); 上述邏輯大概是這樣:如果 getCommits 回傳的結果還有下一頁,就繼續 call getNextPage API如果已經沒有下一頁,則回傳 Observable.empty() 結束 expand 運算最後,透過 reduce 將所有分頁回傳的結果 concat 成一個 Array:Rx.Observable ... ... .reduce( (acc, curr) => acc.concat(curr.data) , []); 整體程式碼大致如下:Rx.Observable .fromPromise(getCommits(...)) .expand( (response) => hasNextPage(response) ? Rx.Observable.fromPromise(getNextPage(response)) : Rx…

AWS Serverless RESTful API

圖片
AWS Serverless RESTful APIs近幾年在雲架構上討論熱度較高的 2 大主題分別是 容器化(Containerize)與 無伺服器(Serverless)架構。本篇文章會帶你瞭解什麼是 AWS 無伺服器架構,以及如何使用 Serverless Framework 這個框架,快速開發 RESTful APIs。大綱什麼是 XaaS?AWS 無伺服器架構Serverless Framework CRUDable Service基礎設施即程式碼什麼是 XaaS?馬雲說過一句話:「過去的一百年,我們把人變成了機器,未來的一百年,我們將會把機器變成人。」人算不如天算,天算就是雲計算。如果要用一句話來定義 XaaS(X as a Service)的話,那就是「萬物皆服務」。舉凡 IaaS(基礎設施及服務)、PaaS(平台即服務)或 SaaS(軟體即服務)等⋯⋯,用一張圖來概括各個 XaaS 的關係:坐在服務窗口後面的人最後都會變成 API。(via @legendtang)— ruanyf (@ruanyf) 2016年8月26日身為程式設計師,我們就是那個負責寫服務來取代人類的存在。所以能夠以最快速度開發出可驗證的服務原型,就成了開發者彼此之間的競爭條件之一,也是本篇文章的目的。AWS 無伺服器架構AWS 是目前雲技術的領頭羊,如果想要用 AWS 來開發 Serverless 的 RESTful APIs,主要會由 3 個核心服務所構成:AWS Lambda(Functions as a Service)Amazon API Gateway(REST API Endpoint as a Service)Amazon DynamoDB(NoSQL DB as a Service)利用 3 個 XaaS 組成一個 BaaS(後端即服務)這裡不會贅述如何操作這些 AWS 服務,如果你已經熟悉這些服務,可以直接前往下一章的 Serverless Framework;如果還不知道它們是怎麼運作的,強烈建議先跑過一遍官方的幾篇教學與實作,理解這 3 個傢伙為什麼這麼酷,也才能理解為什麼接下來要介紹的 Serverless Framework 比它們更酷!無伺服器運算和應用程式Build a Serverless Web ApplicationServerless …

Mock Server&契約測試

圖片
Mock Server&契約測試這篇文章會介紹如何運用 Mock Server 和 Integration Contract Test(契約測試)解決一些在前後端分離的開發環境底下會碰到的問題。大綱如下:什麼是 Mock Server?為什麼需要 Mock Server?如何使用 Mock Server?什麼是契約測試?為什麼需要契約測試?什麼是 Mock Server?下圖是傳統的前後端分離架構:當後端 API 還沒開發完成的時候,前端會需要一個可以暫時回應假資料(mock data)的 mock server,如下圖:等到後端的 API 開發完成之後,前端只需要將 API endpoint 從 mock server 切回 remote server 就可以使用真實資料,如下圖:為什麼需要 Mock Server?一句話,因為有了 Mock Server 之後,前後端就能夠並行開發。如何使用 Mock Server?這裡會介紹兩種方法:Postman Mock ServicePuer Mock ServerPostman Mock ServicePostman 是前後端在開發上很常用到的一款 HTTP Client 應用程式,主要是拿來測試 API,除了有好用的 Collection Test Runner 之外(詳見《基於 Postman 的 API 自動化測試》),其實 Postman 還有提供 Mock Service 的功能,大致流程如下:送出一個 request(R1)儲存 R1 至 Collection(C1)編輯 R1 的 response,儲存成為一個 example(P1)建立一個 C1 的 Mock Server(M1)再次向 M1 送出 R1,即會收到格式為 P1 的 response詳細操作方法請見官方教學文章《Mocking with examples》。但是使用 Postman Mock Service 會碰到一個問題,雖然 Postman 可以同時 mock 多筆 API,但是一個頁面可能會同時存在「需要 mock 的 API」和「後端已經寫好的 API」。Puer Mock Server為了解決上面碰到的問題,找到了這個 open-source 的 mock server:puer-mock。它可以將沒有 mock 的 API …

如何使用 Docker 切換不同的 MongoDB

圖片
在開發前端的時候,常常會碰到想要回到 migration 之前的 MongoDB 資料結構來除錯,如果只使用本地安裝的 MongoDB,操作上會很麻煩,所以這篇文章會說明如何在本機不安裝 MongoDB 的環境下,使用 Docker 準備多份 MongoDB 資料庫。
請確認電腦有安裝 Docker,先準備好要使用的 MongoDB 資料庫備份檔案,大概會是長這樣:


存放的路徑這裡暫定為 ~/Downloads/20170622/hahow/...。
打開 Terminal,下載 MongoDB(這裡以 2.6 版作為示範)的 Docker image:
$ docker pull mongo:2.6 然後開啟一個新的 MongoDB Docker container,container 名字可以透過 --name 自訂:
$ docker run --detach --name mongo_hahow_20170622 --publish 27017:27017 mongo:2.6 使用 docker inspect 取得 container 的 IP,後面會用到:
$ docker inspect mongo_hahow_20170622 | grep IPAddress 前往剛才存放備份資料庫的位置:
$ cd ~/Downloads 開啟並進入一個暫時性質的 Docker container,用途為 restore 資料庫到 mongo_hahow_20170622 的 container:
$ docker run --interactive --tty --rm --volume $PWD:/tmp mongo:2.6 bash 因為 ~/Downloads 被 volume 在 /tmp 底下,所以可以根據對應的路徑前往該資料庫存放的資料夾位置:
$ cd /tmp 使用 mongorestore 恢復備份資料庫到 mongo_hahow_20170622,IP 記得使用上面 docker inspect 查到的 IP:
$ mongorestore --host 172.17.0.2 --db hahow 20170622/hahow 如果順利 restore 完成之後,就可以離開,它會自動刪除這個一次性的 container:
$ exit 之後…

使用 Google Docs 將圖片轉成文字

圖片
像我這種日文不好、需要靠翻譯工具作參考的人,有時候想翻譯雜誌這種長文會很麻煩。

以前會找一些網路上的 OCR 工具,最近才發現原來 Google Docs 就提供這樣的功能!而且還很強大!ヽ(●´∀`●)ノ

以下圖為例,假如我想要翻譯底下那塊專欄的話:

先將文字區塊裁剪成一張圖檔:
上傳圖片到 Google 雲端硬碟點選右鍵 > 選擇開啟工具 > Google 文件
等待它轉換完成之後,就會產生一份帶有文字檔案的 Google 文件:
完成!Google Docs 提供的圖片轉文字功能有以下特色: 語言自動判斷,日文也沒問題 (*´艸`*)橫書&直書自動判斷,這個有點厲害 🌚相較於其它的 OCR 服務,Google Docs 在內容上的判斷準確率很高!
從此翻譯雜誌的效率大幅提升 。:.゚ヽ(*´∀`)ノ゚.:。

如何發送 redux-observable 的 catch error 至 Sentry

我們團隊目前使用 Sentry 這個服務作 error tracking,JavaScript 或 React 的基本安裝方法在 官方文件 都可以找到,這裡就不贅述。同時我們也有在使用 redux-observable 這個 RxJS middleware 來處理帶有副作用的 Redux action。根據 redux-observable 這篇 Error Handling 文件的介紹,一般處理 async 錯誤的寫法大概會是:import { createAction } from 'redux-actions'; import { Observable } from 'rxjs/Observable'; const fetchUserEpic = action$ => action$.ofType(FETCH_USER) .mergeMap(action => Observable.fromPromise(fetch(`/api/users/${action.payload}`)) .map(response => createAction('FETCH_USER_FULFILLED')(response)) .catch(error => Observable.of(createAction('FETCH_USER_REJECTED')(error.message))) ); 但是因為這裡並非正規的錯誤拋出方式,導致 Sentry 無法攔截到。所以根據 Sentry 的這篇 Rich Error Reports with Redux Middleware 文件介紹,我們需要另外為它寫一個 Redux middleware 來處理。策略是利用 redux-actionsFlux Standard Action 特性,將錯誤用 JavaScript 的 Error object 封裝至 action payload:... .catch(error => Observable.of(createAction('FETCH_USER_REJECTED')(new Er…

如何解決 GPG 失效的問題?

我是用 cider 在管理自己的 dotfiles,然後前陣子因為 gnupg 的 formula 剛好一起被更新,導致我的 GPG signature verification 無法順利運作。解決方式:$ brew unlink gnupg && brew link gnupg 如果有跳出某些 conflicting error 的話,可以照著提示解決,例如:Linking /usr/local/Cellar/gnupg/2.1.21... Error: Could not symlink bin/gpg-agent Target /usr/local/bin/gpg-agent is a symlink belonging to gpg-agent. You can unlink it: brew unlink gpg-agent To force the link and overwrite all conflicting files: brew link --overwrite gnupg To list all files that would be deleted: brew link --overwrite --dry-run gnupg 然後再重新 link gnupg 一次:$ brew unlink gnupg && brew link gnupg 最後檢查 Git 能不能順利 commit 和 push,然後確認 GitHub 的 commits 有出現 verified signature 的話,表示順利修復成功。

這個網誌中的熱門文章

DevOps:持續整合&持續交付(Docker、CircleCI、AWS)

Factory pattern 工廠模式

Mock Server&契約測試