畢業前夕,Simple Twitter 專案心得回顧

William Tsou
15 min readOct 3, 2021

前端 Repo: https://github.com/WilliamTsou818/simple-twitter-frontend

後端 Repo: https://github.com/WilliamTsou818/twitter-api-2020

Live Demo: https://williamtsou818.github.io/simple-twitter-frontend/

使用者測試帳號: user1@example.com / 12345678

組員:Avery (後端) / PINPIN (前端) / Hugh (前端) / WilliamTsou (後端、我)

專案介紹

本次的專案 Simple Twitter 是按照 User story 與 UI / UX 設計稿,採取四人一組、前後分離的方式開發。這是 Alphacamp 學期三的學生畢業必經的里程碑,必須自行尋找組員,並在兩週的期限內和隊友協力完成模仿 Twitter 設計的社群網站。

開發的過程主要分為兩個階段,分別是第一階段的指定功能,必須完成 Alphacamp 要求的 User story 和通過所有測試項目才算過關;第二階段則是挑戰功能,Alphacamp 會在開發期間的最後一個週末公布詳細的規格,必須使用從來沒學過的工具,在短時間內實作全新的功能。

在本次的專案中,後端主要透過 Node.js 環境搭配 Express 框架,依據 RESTful 的風格設計 API 給前端的組員使用;前端則使用 Vue 框架開發前端伺服器,提供使用者流暢的畫面體驗。

使用者可以在這項仿 Twitter 的網站中:

  • 註冊、登入帳號
  • 編輯個人帳戶、大頭貼、背景橫幅和自我介紹…等資料
  • 發推文、回覆推文、按讚
  • 追隨其他使用者
  • 查看自己或其他使用者的推文、回覆過的推文、按讚的推文及追隨清單
  • 加入公開聊天室
  • 與其他使用者私訊聊天

團隊溝通的工具

Discord:主要的開發交流、討論與開會工具

我們在 discord 的伺服器建立多個文字頻道,有的用來放置會議紀錄、User story 和 UI / UX 設計稿等專案開發期間經常使用的靜態檔案;也另外建立了兩個頻道,讓前、後端可以在開發時透過文字頻道和另一名組員溝通、交流。

而需要前、後端一起開會、討論串接問題,或著是 DEBUG 的時候,也可以直接進入語言頻道對話交流,或是分享自己的螢幕畫面,直接看著程式碼來討論會更有效率。

此外,我們也利用 discord 的 webhook 綁定 github repo,設定成只要有人發 PR,或建立新的 issue 時,discord 機器人就會自動發送訊息提醒其他人,在多人協作時非常方便。

從結果來看,我認為 discord 確實是個不錯的選擇,僅僅使用一個工具,就滿足了我們日常開發上的交流、開會、儲存紀錄資料、 github PR 通知和分享畫面一起 DEBUG…等需求。

Apiary :主要 API 文件

由於 Apiary 的編輯格式和 Markdown 非常相似,雖然整體功能比較陽春,但已經足以應付這次的專案,而且也支援 Mock server 的功能,可以在後端尚未部署 API 到正式伺服器時,前端可以先透過 Mock server 取得假資料。

另外,Apiary 上規範的 API 回傳格式,也是後端實作 API 的重要依據,以免當初討論好的格式,在實作時卻遺忘了某些細節,結果回傳內容和前端預期的不同,導致前後端串接產生問題。

Trello:管理專案開發進度

為了知道彼此目前的開發狀況,我們這組採用 Trello 看板的方式管理專案進度,互相可以透過 Trello 知道對方正在處理什麼問題或開發那些功能。不同的看板代表功能的開發狀況,例如某功能開發完畢,可以將那張票移到對應的列表中,並且在票的詳細內容附上 PR 的連結,tag 另一位組員審閱。

雖然在開發初期,Trello 可以很方便的讓我們知道其他組員的狀況,後端也可以在前端回報錯誤時,透過開票後自行認領的方式,知道對方目前正在修正什麼錯誤,以免浪費時間在處理同一個問題。

不過,到了開發中期,在隊友 Avery 的建議下,我們在前、後端的 github 上開始使用 issue 去記錄待修正的 BUG,也串接了 discord 機器人,只要有新的 issue 或 PR 就可以即時通知。因此就比較少使用 Trello 的票去提醒另一位隊友審閱 PR,或是認領修正錯誤的票了。

團隊分工

我們團隊是由兩名前端、兩名後端組成的前後分離開發小組,因此除了在討論 API 格式、測試前後端串接以及錯誤回報時,絕大多數時候都是前、後端兩名組員各自協調彼此的工作內容。

在基本功能階段,我們先將工作內容拆分成兩大項,一個人統一負責所有的資料庫 model、專案基本環境和 passport 套件的 JWT 驗證策略設置;另一個人則負責大部分的 API 路由設計和開發。

之所以會採用這樣的分工方式,是希望盡可能避免 conflict 的情況,所以待一個人統一建好專案環境和使用到的套件後,另一個人就可以直接下載套件和套用資料欄位的設定,將衝突降至最低。

而 API 開發則依據 Controller 分工,以這次的專案來說,我們拆分成了 users, tweets, followships 及 admins 四個部分的路由模組,並且盡可能讓每個路由模組統一由一個人負責,避免後端兩個人修改同一個檔案時,容易造成 conflict 的情況。

到了挑戰功能階段,我們則將開發內容拆分成一人負責所有 Socket.IO 的事件邏輯撰寫,另一人則是 Socket.IO 的伺服器、使用者認證 middleware 設置和聊天室相關的 API 開發。

至於錯誤修正的部分,通常我們會在前端回報時,如果有一方目前手上沒有開發任務,就會主動去協助 DEBUG,比較沒有硬性規定,算是靠著後端兩人的默契。

從結果來看,後端在這兩個星期的開發過程中,幾乎沒有出現任何 conflict 的情況,可見這樣的分工方式確實有達到最初希望避免 conflict 的目的。

總結一下,身為後端的我在這次專案中主要負責

  1. 撰寫使用者、後台相關的 API ( 共 14 條路由 )
  2. 撰寫後端的 API 分工文件 ( 依據測試檔詳列所需的基本 API 和前端需求的其他 API )
  3. 撰寫 Socket.IO 公開聊天室、私人訊息的相關事件 ( 連線、加入房間、傳送訊息、離開房間、未讀通知…等 )
  4. 協助部分的錯誤修正,例如修改資料撈取的邏輯、補上遺漏的回傳內容
  5. 團隊 discord 頻道、Trello 看板等溝通工具的基本建置與維護

團隊溝通與分工的檢討

優點:

我們前後端各自的溝通工具都是使用 discord,不僅可以直接看到彼此的討論內容和開發狀況,一旦有文字不易溝通的情況,也可以直接進入語音頻道分享畫面,會比文字描述遇到的狀況更有效率,因此在 debug 和串接溝通上,個人覺得是我們團隊做得不錯的地方。

在後端的分工方面,透過路由模組去分工,由同一個人撰寫一支 API 的 Controller, Service 到 Route ,確實可以盡可能避免 conflict 的情況發生,因為很少有同一個檔案會同時被兩個人修改。

在開發過程中,我和另一位後端隊友 Avery 也會不時的回報目前的進度,以及是否有遇到難題導致開發受阻,彼此都很清楚對方正在做什麼事,如果發生意想不到的困難需要求救時,也可以比較快進入狀況,讓我們解決問題的效率非常高。

自己可改善的地方:

雖然前、後端各自非常清楚自己的另一位隊友進度為何,但由於是第一次前後分離的多人協作開發,後端不太清楚前端的 Vue 框架,也不清楚前端的分工方式;反過來說,前端很可能也是類似的情況,不太清楚後端的 MySQL 資料庫如何運作以及分工方式。

所以在整個專案過程中,前、後端應該都是單純抱持著對彼此的信任在開發。雖然從結果來看是好的,但經過這次前後分離的開發經驗後,我認為自己還是得更深入了解前端在前後分離的開發模式,會比較好了解對方的狀況,甚至可以在對方陷入難題時,也一起加入討論幫忙。

專案開發

後端整體開發:

(1) TDD 與 Git Flow

在 Git Flow 方面,由於專案的規模不大,而且我們選擇了不易發生衝突的分工方式,所以決定只分成 master, feature 與 hotfix 三層分支。

每次開發新功能的時候都從 master 切出一個新的 feature 並且加上功能來命名分支;master 則在遠端 repo 設定保護條件,所有分支都必須由另一個協作者審核過 PR 之後才可以合併至 master ;hotfix 則用來處理急需修正的 BUG。

由於 Alphacamp 在本次 Simple Twitter 專案中,有請資深的工程師替我們撰寫自動化測試檔,因此我們在整個開發流程都採用測試驅動開發 (TDD) 的模式, 每完成一支 API 、修改錯誤或重構程式碼時,都必須執行自動化測試,確保開發的功能有符合測試要求,或是重構、DEBUG 時沒有發生改 A 壞 B 的情況,不小心破壞了原本的功能。

另外,我和後端隊友 Avery 都會在每一次的 PR 附上自動化測試檔的執行結果,以及 POSTMAN 本地測試 API 回傳的資料格式是否符合 Apiary 文件上的格式,確保這次的改動不會讓穩定的 master 分支壞掉。

以上圖為例,我開發完未讀訊息的通知功能後 ,在 PR 中附上自動化測試和 POSTMAN 的執行結果,也有說明 POSTMAN 測試的行為與步驟,讓我的隊友 Avery 可以比較容易了解這次改動的目的,以及自動化測試檔並沒有因為這次改動而導致原本通過的測項受到影響。

(2) Issue

原本開發初期我們是使用 Trello 看板,讓前端可以在串接錯誤時開票並且 tag 後端的人進行修正,但後來 Avery 建議大家使用 github 的 Issue,並且搭配 discord 的機器人讓每次有新的 issue 時,就會即時通知頻道裡的人。

前後端改成以這樣的方式溝通錯誤後,因為平時就會在 discord 上交流和討論,往後就不需要特地去確認 Trello 看板是否有新的錯誤回報,只要 discord 有新的通知就可以知道訊息,並且著手修正錯誤了。

基本功能開發:

在 Alphacamp 指定的基本功能開發階段,由於大部分的內容在之前課程就已經接觸過,所以在實作的過程中並沒有遇到太大的困難,我與另一位後端隊友 Avery 大約在專案開跑的第五天就已經完成所有基本功能的 API 開發,並且通過總共 59 項測資。

因為考慮到時間還很充裕,所以我和 Avery 決定開始規劃重構 API 的程式碼,經過討論後由我負責資料格式驗證的部分,由 Avery 負責錯誤處理的部分,並且視情況修正前端回報的錯誤。

在處理資料格式的驗證時,為了把繁雜又難以維護的 if condition 化繁為簡,我決定使用 Joi 套件,因為它可以直接建立 Joi schema 去規範一個物件內應該具備那些屬性和條件,也可以客製化未能通過驗證時,需要回傳的錯誤訊息,讓前端可以直接把訊息顯示在錯誤提示上。

此外,考慮到本次專案需要驗證的資料都是 req.body 這個物件內的屬性,而且以使用者相關的 API 為例,登入、註冊與編輯使用者的 API 其實需要的資料都大同小異,但它們操作的都是同一個資料表。

與其為了針對這些差異去客製化每個路由的格式檢驗,我更希望可以使用具有彈性,卻又能嚴格檢查 req.body 內傳入的資料是否符合格式要求,所以認為 Joi 會是比 express-validator 更適合本專案的選擇。

挑戰功能開發:

接著進入了週末兩天的黑客松階段,我們要在兩天半的時間內,盡可能完成 Alphacamp 提供的三個挑戰功能。

經過前面一週半的合作後,我們在黑客松初期決定把目標放在挑戰二的 Lv3,並且視情況看能不能開發到挑戰三的通知功能。

開發挑戰功能時,和後端隊友 Avery 討論過後,決定由他負責公開聊天室、私人訊息相關的 model 設置,建立 Socket.IO 的伺服器端基本設定以及三支訊息相關的 API;我專注在 Socket.IO 的事件邏輯。另外,我也將使用到的事件與情境整理成表格,讓前後端討論時可以有參考的依據。

由於 Socket.IO 事件不像 API 一樣,可以透過 Apiary 上的 mock server 讓前端先打假資料,幸好 Postman 剛好在 7 / 30 開始支援 Socket.IO 的功能 ,所以後端可以直接透過 Postman 去測試事件是否有正常運作,而不需要另外寫一個小網站去測試。

在黑客松期間是壓力最大,卻也是最充實的時候。因為在這兩天內,不僅需要使用不熟悉的工具,甚至連開發的功能也是從未接觸過的,在觀念邏輯和工具應用都十分生疏的情況下,確實會令人覺得不知所措。

但是,看到自己寫的事件按照預期的方式運作,以及起初百思不得其解的 BUG 終於修正時,那泉湧而來的成就感,讓我知道自己還是能夠在時間壓力下完成預期的項目,而且不怕面對未知的新技術或挑戰。

專案開發的檢討

優點:

第一次體驗多人協作以及前後分離的開發模式,我認為在避免程式碼 conflict 以及收到前端回報的錯誤時,可以迅速鎖定問題並且修正這兩點,表現得還不錯。

另外,在開發 API 時,也可以迅速開發完基本功能並且通過自動化測試,之後如果有任何優化和程式碼重構,也都會執行自動化測試檔和 Postman 測試,確保沒有破壞掉舊有穩定的功能,對自己的改動負責。

自己可改善的地方:

雖然開發初期就和前端一起討論好 API 的回傳格式,但我們還是在開發中後期時,需要依據前端的需求去修改。我認為這樣的情況雖然無可避免,畢竟開發的過程也許會出現新的需求或想要優化的嘗試,但由於我們這組是後端依據 ERD 圖和 User story 預想前端可能需要的資料後,先定義初版的回傳格式給前端參考,所以這樣的情況時常發生。

舉例來說,回傳使用者的私人訊息列表時,後端原先只回傳了每個私訊者以及私訊房間的相關資料,但如果看了設計稿的話,會發現前端還需要渲染該私訊房間的最新訊息,所以後端必須新增 API 回傳的內容以符合前端的需求。

如果可以重來一次的話,除了 ERD 圖之外,我覺得自己應該要搭配 UI / UX 設計稿去思索前端需要什麼資料,而不是只看資料表和 User story。如果有更細緻的功能想像,自己也能在開發初期討論 API 格式時就注意到這些細節,減少進入開發階段時,前後端彼此之間溝通 API 格式的次數,增進開發效率。

另外,在這次的專案中發現撈取資料的 SQL 語法非常重要,如果使用了較無效率的搜尋方式,會拉長前端取得資料的等待時間,進而影響使用者體驗。雖然在這次專案中,學會了過往沒有嘗試過的 Sequelize 語法,解決了許多複雜的撈取邏輯,但未來還是需要持續精進 SQL 語法,因為 ORM 也有它的侷限,要去思考 SQL 優化的方向。

感謝時間

兩週的時間一眨眼就過去了,真的很感謝後端好夥伴 Avery 當初來邀請我,也謝謝前端兩位好隊友 PINPIN 和 Hugh 願意加入我們,作為大學分組報告的邊緣人擔當,很開心終於有人願意把我撿走 XD

小組討論、開會的過程中,可以感受到大家對專案的熱誠與投入,而且大家都能遵守約定好的串接測試與部署時程,也願意抱持著開放的心去討論優化、修正的方向,一起想出合適的對策;因此,即使開發的過程不時遇到一些難題或 BUG,但整體的開發速度和溝通協調卻讓人覺得相當順暢。

週末的黑客松是最累人的時候,彼此都在那兩天熬夜趕工,但還是能夠心平氣和的討論 BUG 或是需要修正的問題,真心感謝大家的包容;其中,我也想特別感謝後端好夥伴 Avery,整個專案開發的過程中,覺得自己比較像是被 Avery 帶領的感覺,無論是重構程式碼和 QA 測試時展現出來的細膩,以及告訴我可以引入 issue 模板、串接 github 和 discord 機器人通知…等,讓我感受到 Avery 作為工程師的經驗和思維,是非常值得我學習的地方。

很感謝 PINPIN 和 Hugh 兩位前端好隊友,前端的作業量這麼重,兩位剛好也在開賽初期打疫苗,卻能夠如期完成包含 RWD 設計、恰到好處的 hover 與動畫效果,以及加上刪除確認 modal …等優化使用者體驗的功能。真的辛苦你們了!你們絕對值得驗收工作坊給予的高評價,希望你們對成品感到滿意,也感謝兩位這段期間的包容!

此外,我也要感謝所有批改過自己作業的助教,尤其是學期三的 Alex 助教,以及這次專案分配到我們小組的 Eugene 助教。感謝 Alex 助教在學期三的作業給予的建議和交流,讓我可以擁有應付 Simple Twitter 專案必備的開發能力以及基礎觀念,也很感謝 Eugene 助教在 Tech hour 給予的滿滿回饋,不僅告訴我們業界對 Junior 後端工程師的技術能力期待,以及黑客松 Socket.IO 的實作建議。

謝謝你們,讓我第一次的多人協作前後分離開發,可以有這麼好的經驗,希望這次合作經驗也能成為你們通往目標的助力!

--

--

William Tsou

紀錄在alphacamp學習的點點滴滴,以及邁向前端工程師的沿途風景