聚會時間公告: 因應COSCUP 2011, Kalug 8月份休會一次

七月 21, 2017

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 減少 node_modules 大小來加速部署 Node.js 專案

yarn-kitten-full 相信 Node.js 開發者現在大部分都在使用 Yarn 了吧?如果還不知道或無法體會 Yarn 帶來的好處可以參考之前寫的一篇『用 Yarn 取代 Npm 管理 JavaScript 套件版本』,帶你體會 yarn install vs npm install 的速度差異。本篇最主要會介紹在部署 Node.js 專案都需要把 node_modules 壓縮一起丟到遠端伺服器 (假設你不是用 Docker 部署),這時候來聊聊怎麼減少 node_modules 大小。

傳統 npm 作法

Yarn 尚未出來時,可以透過 npm prune --production 的方式來將 devDependencies 內的套件全部清除
$ npm install
$ .... 處理其他事情
$ npm prune --production
$ .... 最後將 node_modeuls 打包

yarn 作法

原本我是把 yarn 搭配 npm prune --production,在早期的 yarn 版本似乎不會有問題,但是發現最新版本 npm prune 會把非 devDependencies 內的套件也一併清除,雖然 yarn 沒有提供 prune 指令,但是有個 flag 可以使用,效果跟 npm prune 一樣,就是加上 --production 這樣就可以降低不少大小,所以部署流程會變成底下
$ yarn install
先是安裝全部套件 (像是 babel-cli),接著透過 babel 轉換程式碼,最後在下底下指令
$ yarn install --production
這時候就會把 babel 相關套件全部移除,最後將 node_modules 打包就可以了。

結論

除了上述過程外,在 CI/CD 流程內,務必設定 yarn 快取目錄在專案內。
$ yarn config set cache-folder .yarn-cache
跑完部屬流程後,可以把 .yarn-cachenode_modules 同時打包,等到下次跑 CI/CD 時會加速不少喔。

» Node.js 8 搭配 npm 5 速度

yarn-kitten-full 這個月 Node.js 釋出 8.0 版本,搭配的就是 npm v5.0.0 版本,上一篇寫到如何透過 Yarn 指令移除 devDependencies 內的 Package 套件,減少 node_modules 大小,有網友提到那 npm 5 的速度為何?其實筆者已經好久沒有用 npm 了,但是有人提問,我就立馬來測試看看 npm vs yarn 的速度,詳細數據可以參考此專案說明。測試方法如下

設定環境

底下是測試環境版本
  • node version: v8.0.0
  • npm verison: 5.0.0
  • yarn verison: 0.24.6

初次安裝 (沒有任何快取)

先把 node_modules 刪除,及系統相關 Cache 目錄都移除
$ npm cache verify
$ rm -rf ~/.npm/_cacache/
$ time npm install
npm 花費時間: 1m43.370s
$ yarn cache clean
$ time yarn install
yarn 花費時間: 1m1.707s

保留系統快取目錄

執行完第一次安裝後,我們把 node_modules 移除後再安裝一次試試看
$ rm -rf node_moduels
$ time npm install
npm 花費時間: 0m38.819s
$ rm -rf node_moduels
$ time yarn install
yarn 花費時間: 0m24.219s

保留系統快取目錄及 node_modules

最後保留 node_modules 目錄,再執行一次安裝
$ time npm install
npm 花費時間: 0m11.216s
$ time yarn install
yarn 花費時間: 0m0.954s

結論

大家可以發現,雖然 npm 改進不少速度,但是 Yarn 還是優勝許多,這邊可以總結,已經在使用 yarn 的,可以繼續使用,尚未使用 yarn 的開發者,可以嘗試使用看看。另外 npm 5 現在執行 npm install –save 會預設產生出 package-lock.json 跟 yarn 產生的 yarn.lock 是類似的東西,除非專案內已經有 npm-shrinkwrap.json,否則 npm 會自動幫專案產生喔。詳細情形可以看 Replace metadata + fetch + cache code。npm cache 指令可以看此文件

七月 10, 2016

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 用一行指令加速 npm install

Npm-logo.svg 不久之前寫過一篇 提升 npm install 安裝速度,但是發現速度還是沒有變快,在 DevOps 的流程花在 npm install 的時間非常冗長,造成每次測試或 Deploy 都要花大量時間等待,且吃掉很多機器的資源,本篇要提供一個小技巧改善 npm install 安裝時間,其實簡單來說就是 cache 第一次安裝好的 node_modules 目錄,之後每次安裝就拿 cache 目錄來新增或減少 packages 即可。

一行指令

底下一行指令請加入測試流程內,讓 CI Server 專注在測試
$ tar xf ../nm_cache.tar && \
  npm prune && \
  npm install && \
  tar cf ../nm_cache.tar node_modules
步驟很簡單,先拿上一次備份的 node_modules,再透過 npm prune 移除不必要的 package,再透過 npm install 安裝新的 package,最後一樣打包給下一次測試使用。這指令非常好用,不管你是不是用 npm@3 都很需要這指令加速 npm install。底下是我隨意拿一個 open source 專案來測試,先假設沒有 cache 機制。
$ rm -rf ~/.npm && rm -rf node_modules && time npm install

real    2m7.751s
user    1m8.704s
sys 0m19.272s
如果導入 cache 機制
$ time (tar xf ../nm_cache.tar && npm prune && rm -rf ~/.npm && npm install && tar cf ../nm_cache.tar node_modules)

> labs-web@0.0.1 postinstall /Users/mtk10671/git/labs-web
> node node_modules/fbjs-scripts/node/check-dev-engines.js package.json

real    0m32.370s
user    0m19.884s
sys 0m13.582s
從 2 分 7 秒變成 32 秒,大約提升了 4 倍,大家可以嘗試看看,這招在 Deploy 跟測試非常有感覺。

五月 22, 2016

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» ScaleDrone Websocket 平台從 Node.js 轉換到 Golang

Go-brown-side.sh 又看到一間網路平台公司從 Node.js 跳到 Golang 了。ScaleDrone 是一間提供了 websocket 服務的公司,讓 web 可以透過 ScaleDrone 即時將訊息傳播到各種瀏覽器,但是今天看到 ScaleDrone 即將把後端平台使用的語言從 Node.js 轉換到 Golang,為什麼要轉語言呢,官方提到大量的 Websocket 連線,讓伺服器記憶體快吃不消了,然而 ScaleDrone 用 Go 語言來實際測試,發現記憶體不但沒有增加,反而還降低了 response 及 connections 時間。底下是針對 Node.js vs Go 語言轉換比較。

Performance 效能

Node.js 使用了 event-driven, non-blocking I/O 模型,一種說法是程式設計師不需要考慮 concurrency,另一種說法是 JavaScript 及 Node.js 在 concurrency 是有效能限制的。ScaleDrone 實際拿了 Websocket 來做實驗,發現 Golang 在 Websocket 表現上足足快了 Node.js 三倍,當然這不代表 Node.js 是不好的語言,只是為了證明,如果針對 websocket 長期考量來說,Golang 會是一個比較好的選擇。

Ease of use 使用上

相信寫 JavaScript 再來寫 Node.js 會是非常簡單,學一套語言前後端都可以適用,Node.js 語言讓程式設計師可以快速進入開發,所以也不用考慮 concurrency 狀況,然而在 Golang 則是提供另外一種 elegant patterns,讓你在寫 concurrency 語法時,需要考慮實際情境。

Ecosystem 生態

不得不說在語言生態上 Node.js 還是贏過 Golang 許多,一個套件可能在 Node.js 上找到好多個不同的作者寫的,但是在 Golang 上可能連一個都沒有。在文件上 Node.js 靠的是 Readme,而 golang 則是靠 godoc,在沒有大量的 example 的狀態下,其實從 Readme 來看都是不好上手的,另外如果第一次接觸 golang,其實 godoc 看起來不是很友善。

Conclusion 結論

每種語言都各有優缺點,並非說 Node.js 就是不好的語言,該 Blog 有說到,如果您還沒有處理過數千或數百萬的 concurrent connections 的話,會推薦使用 Node.js,反之則就是推薦 Golang。最後 Golang 有兩個套件專門主理 WebSocket,一個是 x/net/websocket 另一個是 gorilla/websocket,前者是 Golang 內建的套件,但是並非有很多功能,後者是 third party package 提供了更多 WebSocket 功能,如果要用在 Production 上,請使用後者,最後寫 Golang 可以使用 pprof tool 來追蹤記憶體變化。本篇翻譯自原文出處

五月 8, 2015

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» Node.js Mocha 延遲測試

687474703a2f2f662e636c2e6c792f6974656d732f336c316b306e32413155334d3149314c323130702f53637265656e25323053686f74253230323031322d30322d32342532306174253230322e32312e3433253230504d2e706e67

如果大家有在寫 Node.js Express Framework,一定對 Mocha Unit Testing 不陌生,各位工程師不要太相信自己寫的程式碼,產品上線前,務必要把 Unit Test 寫完整,如果是要 Code Refactor,那測試的重要性更是大。網站架構越來越大,功能越來越多,每寫一個新功能,都會產生 side effect,造成其他程式或邏輯出錯,這時候就需要 Unit Test 來驗證邏輯的正確性。使用 Express 寫 API 我個人會建議使用 Supertest + Should.js 來驗證後端程式碼即可,這幾套框架都是由 TJ Holowaychuk 完成。使用 supertest 也可以讓 express 不用 listen port 就可以測試。

在 Express 內如果有寫 Async 程式,在測試過程中,這時候測試最後會先拿到 response,Async 部分尚未處理完,這時就會驗證失敗,要避免錯誤驗證,解決方式就是在測試過程中使用 delay time,延遲幾秒後才開始測試。底下範例可以在測試內延遲幾秒再繼續測試。

it('enable device mobile if post same data again.', function(done) {
  DeviceMobileRels.scope('deleted').find({
    where: {
      deviceId: deviceId,
      mobileId: mobileId
    }
  }).then(function(mobile){
    should.exist(mobile);
    return request(mcs)
      .post('/xxxxxx/xxxxxxxx')
      .set('Accept', 'application/json')
      .expect(200)
      .expect('Content-Type', /json/);
  }).then(function() {
    // delay 900ms to test
    setTimeout(function () {
      return DeviceMobileRels.find({
        where: {
          deviceId: deviceId,
          mobileId: mobileId
        }
      }).then(function(mobile){
        should.exist(mobile);
        done();
      });
    }, 900);
  });
});

每一個測試時間都必須在 2000ms 內完成,如果測試 delay 時間需要延遲超過兩秒,請務必在最前面補上 this.timeout(1000); 單位是毫秒。

二月 11, 2015

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 您不可不知的 io.js

9950313

io.js 至今已經成立了快三個月,目前也快速推出到 1.2.0 版本了,相信很多人都不太知道為什麼會多一個 io.js 組織,這組織是 fork 自 Joyent’s Node.js 相容於 npm 原始平台。

為什麼 fork Node.js

這就是大家所好奇的地方,iojs 團員皆來自於 Node.js 核心開發團隊,在去年八月,內部成立了 Node Forward 社群組織來試圖改善 Node.js。

A broad community effort to improve Node, JavaScript, and their ecosystem through open collaboration.

然而總是事與願違,底下就是為什麼要 fork Node.js 主因

Some problems require broader ownership and contributorship than have traditionally been applied, while others are so dispersed between tiny projects that they require new collaborative space to grow. Node Forward is a place where the collaboration necessary to solve these issues can take place.

最終因為商標版權的限制下,核心團員才決定直接 fork Node.js,這就是 io.js 的誕生。Isaac Schlueter (核心開發團員之一) 在部落格發表了一篇心得提到為什麼要這麼做,一個關鍵點,就是未來 io.js 還是希望能夠跟 Node.js 專案合併,而不是現在這樣分成兩個專案。

io.js 新變化

io.js 使用 semantic versioning (semver) 釋出 1.0.0 版本,用此版本來區分 Node.js。jQuery 官方部落格也指出使用 semver 的重要性

One of those best practices is semantic versioning, or semver for short. In a practical sense, semver gives developers (and build tools) an idea of the risk involved in moving to a new version of software. Version numbers are in the form of MAJOR.MINOR.PATCH with each of the three components being an integer. In semver, if the MAJOR number changes it indicates there are breaking changes in the API and thus developers need to beware.

最新 V8 Engine

io.js 更新內部 V8 Engine 到 3.31.74.1 版本,讓開發者可以直接使用 JavaScript ES6 新功能,而不需要加上 --harmony 參數

ES6 新功能

底下的新功能都不用加上任何 Flag 就可以正常使用

新模組

io.js 內建了兩個實驗性新模組

  • smalloc: 讓您透過 allocation/deallocation/copying 存取外部記憶體。
  • v8: 暴露 iojs 中 v8 的 events and interfaces。

更多資料可以直接參考 io.js 版本紀錄.

執行 io.js

執行 io.js 就如同執行 node.js 一樣,只是名稱變了而已

Node.js

$ node app.js

io.js

$ iojs app.js

Node 版本管理

相信大家都是使用 Node version manager (nvm) 工具來管理多個 node 版本,您可以透過底下指令來找到 io.js 版本列表

$ nvm ls-remote v1
    iojs-v1.0.0
    iojs-v1.0.1
    iojs-v1.0.2
    iojs-v1.0.3
    iojs-v1.0.4
    iojs-v1.1.0
    iojs-v1.2.0

個人建議一定要裝上 nvm 工具,此工具可以讓您隨時切換 node 版本,包含 iojs 各版本,確保測試無誤

開始使用 io.js?

這問題很多人一定會問自己,現在要把專案換到 io.js 上了嗎?我個人覺得,舊有專案如果在 Node.js 跑的很順,就不建議切換,如果是新專案,又想跑 JavaScript ES6 Feature,就可以直接嘗試看看跑 io.js 1.2.0 版本。本文翻譯自 Getting to know io.js。如內容有誤,請儘速告知。

二月 9, 2015

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 成立 iojs 台灣群組

9950313

昨天在 node.js 台灣群組討論對岸已經成立 iojs-cn,不多說我們也請官方幫忙成立了 iojs-tw,目前的工作只有兩項,就是負責將[ iojs 官網]翻譯成中文,這部份 @cfsghost 已經送 PR 給官方了,另外就是翻譯官方的 Weekly Notes,iojs 每週五都會發布一篇 iojs 的最新動態,我們就是負責將其中文化,上週五已經翻譯好了請參考如下:

io.js 週報 – 2015.02.06

Atom & nw.js 開始採用 io.js, Linux Tracing .. 等等。

每周五我們都會發布關於 io.js 的最新發展。

回顧整個一月份的社群貢獻,io.js 共有 294 次提交,是 Node 近三年來第三活耀的月份,(2012 年 2 月份有 308 次提交)。随着社群貢獻的成長,預計二月份會有更多產出。

  1. 發布 v1.1.0,詳細資訊請參考更新紀錄
  2. Sam Newman lands 簡化了 Stream 建構方法
  3. 正在進行 加入 Linux Tracing (LTTNG) 的工作
  4. 隨著我們加強在 io.js debugging 工作,Google 分享了部分在 V8 和 Chrome 中應用的追蹤技術
  5. Travis CI 增加了 io.js 的支援
  6. Codeship 支持 io.js
  7. Atom 編輯器轉移到 io.js
  8. nw.js(前身是 node-webkit)轉移到 io.js
  9. Tessel 硬體新產品將支援 io.js
  10. Chris Dickinson 增加了 6 位新的貢獻者,活躍的貢獻者目前共有 23 名
  11. 正在制定穩定兼容性策略,歡迎踴躍參加。
  12. 我們開始接受各大公司的反饋意見。如果您有我們遺漏掉的的公司的聯絡方式,請告知我們。
  13. 下週舉行 Node summit,將會有許多演講和與會者。
  14. 技術委員週會
  15. 網站工作群組會議
  16. 追蹤工作會議

原文:io.js Week of February 6th 2015,作者:@iojs,翻譯 @iojs-tw

如要加入 iojs 翻譯請直接到這裡申請

七月 20, 2014

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» Automating your workflow with Gulp.js

gulp

今年 2014 COSCUP 在 7/19,20 中研院舉辦,由於 JSDC 今年比往年還要晚半年舉辦,所以本來想投在 JSDC 的議程,就先拿到投到 COSCUP 議程。去年 JSDC 講了 Javascript command line tool GruntJS 介紹,講完經過半年,Gulp.js 就出來了,我馬上跳過去嘗試,用過之後,就像變了心的女朋友,回不來了,底下是 Gulp.js Slides。

Automating your workflow with Gulp.js from Bo-Yi Wu

最後提到 Slush.js 這套 streaming scaffolding system,我寫了 html5 template engine generator,產生最簡單的開發環境以及 Gulp.js 設定檔,大家可以透過底下安裝嘗試:

$ npm install -g slush bower
$ npm install -g slush-html5-template

產生專案檔案

$ slush html5-template

這套 Slush html5 generator 程式檔來自 html5-template-engine

一月 5, 2014

小惡魔AppleBOY
AppleBOY
is about »

tag cloud

» 在 Chrome 瀏覽器使用 Terminal 終端機

Google Chrome

簡介

不知道大家有無在瀏覽器內直接連上 Terminal 終端機,今天來介紹 DevTools Terminal,這是一套 Chrome extension,它可以讓您在 Chrome 瀏覽器直接使用 Terminal,平常開發程式,一定會常常切換瀏覽器及 Terminal 軟體,現在開發者可以直接在瀏覽器連上 Terminal,並且開始使用 Git, Grunt, wget 甚至 Vim 等指令。

Screenshot from 2014-01-05 20:36:26

為什麼要在瀏覽器內使用 Terminal

在開發網站過程,你一定會用到底下工具:

  • 編輯器 Sublime, Vim 用來撰寫程式
  • 瀏覽器 Chrome 用來 debug 看結果
  • Terminal 終端機用來 update package 等

現在 Terminal 甚至用到 Grunt 等開發工具,每天都在這三種介面切換,是不是很浪費時間,雖然 Chrome 推出了 Workspace 讓開發者可以直接在瀏覽器內寫程式,但是這還不夠阿。所以 DevTools Terminal 幫你完成了這個故事,開發者可以直接用 Chrome 瀏覽器完成上述三件事情。

安裝方式

底下測試環境為 Ubuntu 系統,首先安裝 Chrome extension,完成後,請按下 Ctrl + Shift + I,會開啟 DevTools,會看到多一個 Terminal tab。如果系統並非為 Mac OS,那就必須透過 Node.js Proxy 才可以連上 Terminal。

$ npm install -g devtools-terminal

安裝完成後,開啟新的 Terminal console 並執行底下指令:

$ devtools-terminal

預設會開啟 8080 port,帳號為 admin,如果要改變預設值,請建立新檔案 terminal.js (檔案名稱可以自行更換),內容寫入

exports.config = {
    users: {
        admin: {
            password: "",
            cwd: process.cwd() //working directory
        }
    },
    port: 8080
};

透過指令:

$ devtools-terminal --config terminal.js

可以在 Terminal 介面執行 Grunt,畫面如下

Screenshot from 2014-01-05 21:22:15

總結

Chrome Developer Tools 實在是太強大了,我個人比較期待是否有整合 Compass,現在只有支援 Sass 3.0 版本以上,當然如果能在瀏覽寫程式是很方便,但是有時候開啟 DevTools 時候,記憶體都會被吃的很高,導致 Chrome 當機,所以其實還是要看狀況使用,但是能透過 chrome 來連接其他伺服器 Terminal,此功能對於常使用 console 的開發者是一大福音。

十一月 12, 2013

Yuren's Info Area
yurinfore
is about »

tag cloud

» Mozart - HTML5 音樂指揮家遊戲

今年我們在 Node Knockout 2013 上面做了一個音樂指揮家的遊戲,可以用手機瀏覽器控制電腦瀏覽器播放音樂的節奏,並且實驗性的支持不同電腦發出不同聲部的音樂,就像交響樂團一樣!下面是我們的 DEMO 影片:



製作這個遊戲用到了以下技術:

  • Device Motion event: 用來偵測手機的加速度,[按這邊]偵測你的手機跟瀏覽器有沒有支援
  • WebSocket: 用來把手機的加速度資訊從手機傳到 node.js server 再傳到電腦端的網頁
  • MIDI.js: 播放 midi檔案,據我所知我們應該進行了大量的 patch XD
  • Audio API: 這邊不是我做的所以不是很清楚,不過就我所知有把 midi 音樂切分成不同聲部並且在不同的電腦播放。
  • Canvas: 在電腦端繪出加速度曲線,並且偵測到超過門檻值記錄時間來找到節拍
 晚點我們整理好後會釋出 source code,請拭目以待 :-)

另外如果覺得我們的點子很有趣,請到 [這個網址] 玩遊戲,並且按下左上角的 [VoteKO] 投給我們一票!


十月 17, 2012

Yuren's Info Area
yurinfore
is about »

tag cloud

» jscallgraph - Javascript Call Graph 靜態分析

最近用 xmind 追 code 追得很辛苦,跟幾位朋友討論過後,不知不覺就開始寫起了靜態分析用的程式。昨天先用 python 驗證了一下概念,深夜開完會議之後就決定用 node.js 來寫個程式會比起用 python 更為合適。目前已經放上 npm,要安裝只要你已經裝好了 node.js 跟 npm,輸入以下指令就可以安裝了。

$ sudo npm -g install jscallgraph
$ sudo apt-get install graphviz

第二行是安裝 graphviz,主要的用途是拿來產生分析完的圖形用的。使用上很簡單,舉例來說你想要對 Firefox OS 的 system app 裡面的 window_manager.js 作靜態分析,把檔案抓下來,用以下指令產生 dot file

$ jcg window_manager.js WindowManager > window_manager.dot

第一個參數是要分析的檔案,第二個參數是要分析的物件,這邊可以參考一下 window_manager.js 的檔案,裡面宣告了 WindowManager 物件,並且把相關 method 都包裝在裡面。

接下來用 graphviz 的 dot 指令產生 png 圖檔

$ dot -Tpng -o window_manager.png window_manager.dot


這樣就完成了!



Source code 放在 github, 請大家自由取用!另外這程式不是什麼 javascript 都可以分析,有興趣的請送 patch! :D

八月 6, 2011

Yuren's Info Area
yurinfore
is about »

tag cloud

» Mocking Bird - node.js REST API simulation (1)

當團隊決定開發一個使用 web service 的 mobile app 時,我們遇到了一個小問題:mobile app 跟 web service 是同時開發的,當 web service 還沒實作完畢前,mobile app developer 只能暫時先從規格中 implement 跟 web service 銜接的介面。


這聽起來有點瞎子摸象。

不過 Jamie Sa 提供了個有趣的點子:如果我們可以寫個模擬的 REST API service,並且透過 YAML 定義簡單的規格的話,我們就可以利用這個模擬 REST API 比較真實的跟 web service 銜接了 :)



正巧手邊大家正在研究 node.js,不免俗的我們就用了它來實作了初版的 API Simulator,Jamie 把它叫做 mockingBird。這個時候 YAML spec 看起來像這樣:

# APIs in V1
meta:
  version: draft
v1_articles:
  timestamp: '2011-07-19T08:54Z'
  is_end: true
  articles:
    - { article: 1 }
    - { article: 2 }
    - { article: 3 }
  article_count: 3

而用瀏覽器開啟 http://127.0.0.1:8080/v1/articles 則會輸出以下結果:



初版的時候我們用 underline "_" 來分割版本,並且將假資料直接放在 YAML 裡面。而當我們需要模擬取得多筆資料的時候還可以處理,但如果需要類似 http://HOST/article/ARTICLE_ID 這樣的 API 就無法模擬了,目前這樣的寫法也無法模擬 POST method。

做了一連串的 hacking 後,終於完成了一個較有彈性的架構,不過當然還是沒辦法模擬太過於複雜的狀況 :P


MockingBird 會將 JSON 格式的假資料讀取進來,而可以在 YAML 裡面調用 dummy data 以及使用簡單的 Javascript 做計算。

比如說我要模擬 Social network 的 API,

首先要先產生 dummy.json 假資料檔,這邊我用一個 python script 產生 dummy.json。

import uuid
import json
from random import randint, choice
from datetime import datetime, timedelta

firstnames = ['Ericka', 'Amie', 'Annabelle', 'Hugh', 'Carmella']
lastnames = ['Hilts', 'Kowalsky', 'Cincotta', 'Gerken', 'Stults']
devicenames = ['iPad', 'Android', 'Web']
basetime = datetime.today()
lipsum='Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sollicitudin elementum tristique. Nullam gravida bibendum magna viverra gravida. Cras nec mi a est malesuada dictum.'

def gen_id():
    return uuid.uuid1().hex[:24]

def gen_users(num=10):
    users = []
    for i in range(num):
        user = {}
        user['id'] = gen_id()
        user['email'] = 'a%s@example.com' % randint(0,1000000)
        user['nickname'] = "%s %s" % \
                           (choice(firstnames), \
                           choice(lastnames))
        users.append(user)
    return users

def gen_comment(users, article_id, timestamp):
    c = {}
    c['id'] = gen_id()
    c['creator_id'] = choice(users)['id']
    c['creation_device_name'] = choice(devicenames)
    c['article_id'] = article_id
    c['timestamp'] = timestamp
    c['text'] = lipsum
    return c

def gen_articles(users, num=20):
    articles = []
    for i in range(num):
        user = choice(users)
        timestamp = basetime+timedelta(0,i*10)
        article = {}
        article['id'] = gen_id()
        article['creator_id'] = user['id']
        article['creation_device_name'] = choice(devicenames)
        article['timestamp'] = timestamp.isoformat()
        article['text'] = lipsum
        article['comment_count'] = randint(0,5)
        article['comments'] = []
        for j in range(article['comment_count']):
            c = gen_comment(users, article['id'], \
                            (timestamp+timedelta(0,j*10)).isoformat())
            article['comments'].append(c)

        articles.append(article)
    return articles

if __name__ == '__main__':
    data = {}
    data['users'] = gen_users()
    data['articles'] = gen_articles(data['users'])
    print json.dumps(data, indent=2)



這個 dummy json 會 load 進去 node.js 的主程式裡面,可以由程式或者是 YAML 裡面使用。現在的 YAML 檔案則是長成這樣:

version: 0
api:
  articles:
    prefix: api
    url: "articles.*"
    http_method: GET
    response:
      timestamp: "timestamp"
      is_end: "true"
      article_count: "dummy['articles'].length"
      articles: "params['limit'] ? dummy['articles'].slice(0,params['limit']) : dummy['articles']"
  article:
    prefix: api
    url: "article/(\w+)$"
    http_method: GET
    response:
      article: "findById(dummy['articles'], match)"
  users:
    prefix: api
    url: "users"
    http_method: GET
    response:
      users: "dummy['users']"
  
  post_article:
    prefix: api
    url: article
    http_method: POST
    response:
      creator_id: "params.creator_id"
      creation_device_name: "params.creation_device_name"
      text: "params.text"
      timestamp: "timestamp"
      comment_count: "0"
      comments: "[]"
      id: "generateId()"
  
  post_comment:
    prefix: api
    url: comment
    http_method: POST
    response:
      creator_id: "params.creator_id"
      creation_device_name: "params.creation_device_name"
      article_id: "params.article_id"
      text: "params.text"
      id: "generateId()"
      

裡面有些關鍵字解釋一下:
  • version: 最後 mockingBird 的網址會是 http://HOST/PREFIX/VERSION/method,如 http://localhost/api/0/articles,用來區分 API 版本用的變數
  • prefix: 可以針對 API 的用途使用不同的 prefix,在這邊我們只用了 "api" 這個 prefix。
  • url: url 的 match pattern
  • http_method: 可以指定要用 POST 或是 GET 的 HTTP Method
  • response: 要回應的 JSON 訊息。
  • dummy: 在 YAML 裡面可以利用 dummy 取得假資料,比如說 dummy['articles'] 就是所有的 articles。
  • params: 使用 GET/POST 的時候丟進來的參數。比如下達了 http://localhost/api/0/articles?limit=2 時,YAML 可以使用參數 params.limit 取得這個 limit 數值,可以參考下面的片段
  • findById: 用 id 來搜尋物件的 method
articles:
    prefix: api
    url: "articles.*"
    http_method: GET
    response:
      timestamp: "timestamp"
      is_end: "true"
      article_count: "dummy['articles'].length"
      articles: "params['limit'] ? dummy['articles'].slice(0,params['limit']) : dummy['articles']"

當用瀏覽器開啟 http://localhost:8080/api/0/articles?limit=1 的時候,就可以獲得以下結果:

如此一來,你的 mobile app 就可以開幹了,而有了這個實體的 SPEC,web service 的 developer 也可以依此為目標,最終做成跟這個相同的 API。

下一篇再來詳細講解怎麼使用這個工具還有 node.js 裡面是怎麼實作的。但重點是:有人有興趣嗎?出個聲吧 :P

六月 19, 2011
» Introduction to Node.js


Very nice and clear introduction of Node.js system.

support:

biggo.com.tw

biggo.sg

A Django site.