1. 程式人生 > 其它 >使用Go語言框架進行web開發筆記

使用Go語言框架進行web開發筆記

前言

關於golang的web開發有不少框架,例如 martini, gin, revel,gorilla等。 之前玩過revel,感覺封裝的太多了,作為一個小應用不需要這麼複雜,而且google得到結果是revel的效率相對較差。gin的benchmark顯示效率是martini的40倍,但是gin比較新所以他的的生態圈相對較少。最終選擇了martini, 有很多middleware可以選擇,其中就包括了websocket,並且背後用的是gorilla websocket這個包。

介面和功能

  1. 一個跳轉到Oauth2登陸授權頁面的連結
  2. 授權完成後,跳回服務的頁面,此時獲得了access_token, 就可以為所欲為了。全部的功能也都集中在這個頁面,最終的介面如下圖所示。

點選連線是用來開啟websocket連線的。開始傳送資料是開始把使用者ID發給服務端,服務端呼叫api開始抓取圖片。停止用於停止本次的抓取服務。已完成數量用於實時返回抓取的圖片數量。

程式大致結構

這裡把Jobs, goroutine #1, #2等作用在全域性是為了在websocket斷開後,下載還能繼續執行。websocket goroutine是連線建立後的作用域,連線斷開後這個goroutine就不存在了。Jobs, NextUrl充當佇列的角色。 Done的作用僅僅是計數。這裡少寫了兩個全域性變數,Quit chan int, IsPreparing bool, 這兩個變數是用來讓前端控制抓取程式是否進行的。

簡單理解就是一個產生任務的for迴圈,一個消費任務的for迴圈,一個用於給client返回計數的for迴圈。這裡不得不感嘆,goroutine channel的設計使得編碼簡單明瞭。

遇到的問題

由於第一次正經使用Go,還是遇到不少問題的。不過需求比較簡單,所以沒有接觸什麼深入的內容。主要集中在強型別帶來的問題。

DB查詢

之前寫過一篇關於database/sql的文章,這次直接用了sqlx這個庫,可以少寫不少程式碼,也少犯錯誤。但是畢竟不如laravel那麼方便,所幸需要寫的sql不多,臨時寫幾個方法就搞定。同時思考,如何實現一個eloquent的api。貌似有難度。

Json處理

強型別決定了Json的處理是個痛。之前寫過一個天氣預報的小程式,用的是map[string]*json.RawMessage

這種對映結構,然後一層一層解開json。當時沒發現這是有問題的,因為如果用RawMessage, 字串的引號"也會被保留,使得字串結果前後多了引號。 這次再次google了一次,發現還是得用map[string]interface{}來對映,然後再用type assertion來一層層的解開json。這是一個痛苦的過程,想起php中的json_decode()不禁淚流滿面。

Stop Goroutine

如何中斷一個goroutine是一個問題,因為需要控制開始停止。谷歌一下很快就有結果。

    go func() {        for {            select {            case <-Quit:
                IsPreparingJobs = false
                return
            default:                // to do something
            }

        }
    }()

這裡設定一個IsPreparingJobs是用於中斷後再次開始這個迴圈。

Testing

Golang提供的測試工具非常方便,go test就能進行所有測試。從martini原始碼中複製了兩個常用方法出來。

func expect(t *testing.T, a interface{}, b interface{}) {    if a != b {
        t.Errorf("Expected %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
    }
}

func refute(t *testing.T, a interface{}, b interface{}) {    if a == b {
        t.Errorf("Did not expect %v (type %v) - Got %v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
    }
}

總結

感覺golang作為web開發工具,在資料格式處理方面,沒有弱型別語言方便。這點node倒是非常好,json轉object非常方便。也許配合Promise,node會比較好用吧。golang也有優勢,goroutine非常好用,官方的庫功能非常全,打包為二進位制可執行檔案使得部署異常容易,強型別語言效率比較高。