ทดลองเขียน firebase cloud function ด้วย golang ด้วยการไปดึง APIs จาก Discogs มาแสดง สามารถกดดูได้ที่นี่ http://aofiee.dev/music/
package albumimport ("encoding/json""errors""io/ioutil""log""net/http""os""strings""github.com/aofiee/album/utils")func sendJSON(v interface{}, w http.ResponseWriter, r *http.Request, status int) {w.WriteHeader(status)w.Header().Set("Access-Control-Allow-Origin", "*")w.Header().Set("Content-Type", "application/json")jsonData, err := json.Marshal(&v)if err != nil {log.Println(err)}w.Write(jsonData)}func SearchAlbums(w http.ResponseWriter, r *http.Request) {var params struct {Artist string `json:"artist_name"`Track string `json:"track"`}if err := json.NewDecoder(r.Body).Decode(¶ms); err != nil {log.Fatal(err)return}if params.Artist == "" && params.Track == "" {var msg struct {Msg string `json:"msg"`}msg.Msg = "please input params."sendJSON(&msg, w, r, http.StatusBadRequest)return}data := getJSON("https://api.discogs.com/database/search?artist=" + params.Artist + "&track=" + params.Track)var result utils.AlbumsJsonjson.Unmarshal(data, &result)sendJSON(showData(&result, w, r), w, r, http.StatusOK)}func showData(result *utils.AlbumsJson, w http.ResponseWriter, r *http.Request) []utils.Results {var rs []utils.Resultsfor _, v := range result.Results {t := trackList(v.ResourceURL)rs = append(rs, utils.Results{Thumb: v.Thumb,Artist: v.Title,Country: v.Country,Year: v.Year,Genres: strings.Join(v.Genre, ","),Tracks: t,})}return rs}func trackList(url string) []utils.TrackAlbum {var t []utils.TrackAlbumdata := getJSON(url)var result utils.TrackJsonjson.Unmarshal(data, &result)for _, v := range result.Tracklist {t = append(t, utils.TrackAlbum{TrackName: v.Title,})}return t}func noRedirect(req *http.Request, via []*http.Request) error {return errors.New("Don't redirect!")}func getJSON(link string) []byte {log.Println(os.Getenv("KEY"))client := &http.Client{CheckRedirect: noRedirect,}discogs := "Discogs key=" + os.Getenv("KEY") + ", secret=" + os.Getenv("SECRET")req, err := http.NewRequest("GET", link, nil)if err != nil {log.Println("err", req)}req.Header.Add("Authorization", discogs)resp, err := client.Do(req)if err != nil {log.Println("error ", err)}defer resp.Body.Close()if body, err := ioutil.ReadAll(resp.Body); err != nil {log.Println("error", err)} else {return body}return []byte{}}
เสร็จแล้วก็มาลองเขียน test ดูบ้าง ม ือใหม่ code ก็คงจะมั่วๆ ยุ่งๆ พยายามเขียนให้ได้ coverage สูงๆอยู่
package albumimport ("encoding/json""net/http""net/http/httptest""strings""testing")func TestSearchAlbums(t *testing.T) {var params struct {Artist string `json:"artist_name"`Track string `json:"track"`}t.Run("SUCCESS_FAIL", func(t *testing.T) {params.Artist = ""params.Track = ""data, _ := json.Marshal(¶ms)payload := strings.NewReader(string(data))req := httptest.NewRequest(http.MethodGet, "/", payload)rr := httptest.NewRecorder()SearchAlbums(rr, req)if status := rr.Code; status != http.StatusBadRequest {t.Errorf("wrong code: got %v want %v", status, http.StatusBadRequest)}if got, want := rr.Body.String(), `{"msg":"please input params."}`; got != want {t.Errorf("HelloWorld = %q, want %q", got, want)}})t.Run("SUCCESS_FULL", func(t *testing.T) {params.Artist = "Bodyslam"params.Track = "งมง าย"data, _ := json.Marshal(¶ms)payload := strings.NewReader(string(data))req := httptest.NewRequest(http.MethodGet, "/", payload)rr := httptest.NewRecorder()SearchAlbums(rr, req)if status := rr.Code; status != http.StatusOK {t.Errorf("wrong code: got %v want %v", status, http.StatusOK)}if got, want := rr.Body.String(), "Bodyslam"; !strings.Contains(got, want) {t.Errorf("HelloWorld = %q, want %q", got, want)}})}
เสร็จแล้วก็สั่ง deploy
gcloud functions deploy SearchAlbums --env-vars-file .env.yaml --runtime go113 --trigger-http --allow-unauthenticated
เป็นอันจบ
Code ตัวอย่างอยู่นี่
https://github.com/aofiee/firebase-golang-example/tree/main/functions/album
Quick Links
Legal Stuff