# 短網址產生器 - 實作筆記
###### tags: `Node.js` `MongoDB` `Express.js` `Mongoose` `project`
:::warning
:bulb: 本站筆記已同步更新到我的[個人網站](https://simplydevs.netlify.app/)囉! 歡迎參觀與閱讀,體驗不同的視覺感受!
:::
[ToC]
## :memo: 功能
* 輸入原始網址,送出表單後會回傳格式化後的短網址。
* **在伺服器啟動期間**,使用者可以在瀏覽器的網址列,輸入你提供的短網址,瀏覽器就會導向原本的網站
* 短網址輸出格式為 5 碼英數組合
* 使用者可以按 Copy 來複製縮短後的網址
## :memo: 規格
* 使用 MongoDB & Mongoose 完成專案
* 需包括「例外處理」:
* 輸入相同網址時,產生一樣的縮址。
* 若使用者沒有輸入內容,就按下了送出鈕,需要防止表單送出並提示使用者
* 在 package.json 裡設定執行腳本,定義啟動專案的必要指令。
## :memo: <a id="brainstorming"> 思路 </a>
### 短網址的產生
- 建立資料庫,給定每個網址一個專屬id(mongoDB自動生成),對應到一個亂數產生的短網址,存回資料庫成為一筆資料
- 需要一個函式讓id --> short url之間可以轉換:
- 使用POST方法寫入資料
- 使用者傳入原始網址
- 到資料庫中比對:
- 比對到相同的網址,代表該筆資料已經存在,回傳短網址。
- 比對不到相同的網址(資料庫中無此筆資料),另外存成一筆新的資料到資料庫中,再透過function產生短網址。
- 回傳短網址,渲染畫面
- 反向的short url --> id,再由id去對應到原始網址,使短網址放進瀏覽器網址列中也可以成功導向原本的頁面
- 使用GET方法(瀏覽頁面)
- short url傳入資料庫進行比對,抓取符合該筆資料的id
- 如果抓不到該筆資料:error
- 資料庫回傳該筆資料,取出原始網址
- 回傳原始網址,渲染畫面
### 其他功能
- 複製短網址
- 無效網址處理
- 例外情況處理
## :memo: 經驗回顧
### Phase 1: 毫無頭緒
- 剛拿到這個題目的時候完全不知如何下手,於是先到熟悉的縮址網站例如 [reurl.cc](https://reurl.cc/main/tw)或[picsee.io](https://picsee.io/)觀察一下其中的運作和路由設計,同時也查了[geeksforgeeks](https://www.geeksforgeeks.org/how-to-design-a-tiny-url-or-url-shortener/)的相關做法
- 觀察一陣子後慢慢有了想法,其實就是給定每一個網址一組隨機產生的號碼(五位英文數字組合),再把資料寫入資料庫,每次使用者傳入網址後,就從資料庫去找符合的資料。
### Phase 2: 思路拆解
- 有了初步的想法,但是要寫出程式碼還是有點困難,於是先把可能的步驟拆解如上述思路的段落。
### Phase 3: 建立專案
- [設定Express](https://hackmd.io/@Fb1mLcumT_GI60TovN10dQ/BJR_v_K_j)
- [連線資料庫並建立model](https://hackmd.io/@Fb1mLcumT_GI60TovN10dQ/HJu5lkwYo)
### Phase 4: 實作
- 規劃專案資料夾架構
- 規劃路由:透過功能去拆解,例如瀏覽頁面需要GET方法、使用者傳入資料需要POST方法
- 前端頁面設計、切版
### Phase 5: 卡關經驗回顧
- 狀況:設定送出資料並縮址的路由時非常苦惱,不確定條件判斷應該怎麼寫才好;必須滿足基本功能,同時也要處理例外情況。
- 首先重新看一次功能,確認自己理解功能需求,並且先在VS Code中用comment的方式記錄下來
- 確定自己理解功能後,開始思考要用甚麼方法解決,以及邏輯該如何執行
- 想到曾經用過的方法,可是不太熟悉,於是重新讀了一次文件:
- [Array.prototype.find() ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find):找出該陣列中符合該函式條件的第一個數值,回傳第一個數值
- [Array.prototype.some()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some):檢查陣列中是否有符合該函式條件的數值,回傳boolean
- 寫了一陣子還是不太確定,功能似乎還是不齊全,產生的 5 碼英數組合無法成功出現在show頁面,於是回頭複習了一下to-do list的教材,並檢查自己的路由、頁面相關設定,並且重新針對每個變數和attribute的命名檢視了一次,減少混淆
- 反覆的測試、error、找資料、複習教案、看自己以前寫過類似的程式碼,終於完成要求的規格