---
# System prepended metadata

title: 第三次
tags: [課程]

---

# 第三次
###### tags: `課程`

:::info
### 今天要幹嘛
- [ ] 吃飯
- [ ] 檢查進度
- [ ] 給一點新東西
- [ ] 討論下次吃甚麼 & 時間
:::



### HTTP Methods
> 方法！

每一份 HTTP request 還會有個 **Method** 屬性，用來表達此次 request 的意圖

- GET
  - 取得資料
  - 通常**沒有Body**，額外資訊在 URL 的 query string 上（這也是為什麼 query string 也稱為 Get parameter）
- POST
  - 對此資源更新資料
  - 要更新的資料放在 Body 裡
- PUT
  - 更新“部分”資料
  - 一樣，要更新的東西放在 Body 裡
- DELETE
  - 刪除資料
- HEAD
  - 只取得 Header
- ...

HTTP Method 不是強制要遵守的！你要全部用 `GET` 或更反人類的全部用 `DELETE` 也可以。
但是為了自己與同事的頭髮著想還是遵守一下這個規範吧。

> 方法屬性(Method Properties)
在請求方法中，HTML設計Safe與Idempotent兩種特性。有時候，在設計API時，我們會拘泥於語意的含意，因為有些請求的並不是只有單純CURD的形式；而利用這兩種特性，便可以幫助我們去思考API究竟要用何種形式的請求方法較為恰當。

- 安全方法 (Safe Methods)
    GET、HEAD 為安全方法。

  - SAFE代表的含意為「是否安全」，所謂的安全便是「在請求的過程中，是否有任何資源的改動(新增、修改、移除)」。

  - 合理的使用安全方法並不會對Server造成危害、資源損失或運作異常；然而，安全方法的定義僅僅是規範的標準，HTML的規範無法強制規定程式設計師使用請求方法的方式，若是使用具有危險因子的設計也會讓Server暴露在危險之中。

- 非安全方法 (Unsafe Methods)
    POST、PUT、DELETE 為非安全方法。

  - 非安全方法並不是在「網頁資訊安全」上不安全，而是指這樣子的請求將會造成Server的狀態改變(State Change)。而區分安全方法與非安全方法是為了避免網頁爬蟲和網頁快取的執行下，誤觸了改變伺服器狀態的請求，造成並非我們所預見的結果。

- 淺在危害實作 (Potentially Harmful Implementation)
    - 再一次提到，雖然HTML在請求方法有完整的規範，但規範僅僅是規範，無法避免網頁工程師在開發中使用具有風險的實作。

> 例如：
Http://blog.com/artical/001?action=delete
以上的範例所描述的行為是，以GET刪除某筆文章。這樣的實作違反了HTML的規範，即GET在請求的過程中，不能有資源的改變。以上的設計雖然在程式撰寫上方便，卻帶來了以下隱憂。

> 例如：
Google Search 的爬蟲會遍歷網站所有的連結與頁面，若是以GET設計新增、修改、刪除等URL，將會造成Google的爬蟲程式造訪刪除的功能，造成網站資料誤刪的情形。
若是程式開發人員以DELETE實作刪除動作，網頁爬蟲程式將會自動略過請求，因為網頁爬蟲程式並不會造訪非安全方法下的任何請求。

- 冪等方法 (Idempotent Methods)
  - 若擁有這個特性，則代表這筆請求就算重複操作，也會產生相同的結果。換句話說，如果在網路狀態不佳的環境，就算重複執行也不會有問題。

  - GET、HEAD、PUT、DELETE是IDEMPOTENT，代表不管重複幾次都是相同的請求。

  - POST與PATCH則「非」IDEMPOTENT。POST再執行一遍便會重新新增一筆資料。PATCH則是不保證重複新增資料的可能性，比如說：更新modified time。

  - 而區分兩種方法的目的在於，當客戶端接收回應前如果發生錯誤，無法確認請求是否被伺服器正確執行的情況下。符合冪等方法規則的請求能夠重複送出，並且有相同的結果。

- 可快取方法 (Cacheable Methods)
    GET、HEAD、POST為可快取方法

  - 可快取方法代表可允許客戶端將內容保存下來，在未來重複造訪網站時可以重複利用，減少請求回應的時間，降低伺服器在處理頁面時的寬頻消耗，增加網頁運作效能。

> 例如：網頁加載所需的CSS、js、img等檔案以GET傳輸，客戶端將會保存這些內容，加快二次造訪時頁面的顯示速度。
但在絕大部分的實作中，可快取方法只在GET與HEAD中實現。

[更多細節](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods)

#### In Express

在 Express 的 Router 中對於同一個 URL 可以讓不同的 Method 導到不同的地方
```javascript=
router.route('/my-blog/article/:id')
    .get((req, res)=> {
        controller.getArticle(req.param.id);
    })
    .put((req, res)=> {
        controller.updateArticle(req.body, req.param.id);
    })
    .delete((req, res)=> {
        controller.deleteArticle(req.param.id);
    });
```

### Status Code
> 用來表達現在的狀態（Host 給 Client）
> 像是最常見的：404 Not Found!

 一套使用簡短的代碼來表達一個 HTTP 請求是否完成的方法
 像是：
 - 2xx 表達成功
   - `200` OK
 - 3xx 重新導向
   - `302` Found (像是登入後把你導到其他頁面)
 - 4xx Cline 端的問題
   - `404` Not Found
   - `418` I'm a teapot cannot brew coffe
 - 5xx Server 端的問題
   - `500` Internal server error

> 彩蛋很重要 不能打錯 [name=球球]
 
[詳細列表](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status)
[nyan](https://http.cat/)

#### Express
```javascript=
req.status(404).send('Page Not Found! QQ');
```

### RESTful API
> 不是一套標準，而是一種風格

將每一個 http request 視為一個 "動詞+名詞" 的指令
動詞的部分由 http Method 來提供，在需要更多自定義動詞的情況下需要自己訂一套固定的表達法，在 URL裡
名詞的部分為 URL，URL 內只應該表達一個“東西”

因此每一個請求都是對某個“物件”做某個“操作”

```
this=> GET /player?id=123
this=> GET /player/123
this=> DELETE /player/123
this=> GET /player/1/item/48763
this=> GET /player/1/item/48763/_COMSUME

not => GET /get_player/123
not => GET /del_player?id=123
```

[Mopcon 共筆--RESTful](https://hackmd.io/gUGu05hES1GMbdrny70iyQ?view#%E4%BB%80%E9%BA%BC%E6%98%AFREST)

### mongodb Query

- 查詢
    1. ``db.users.find()``  #查詢users集合中所有資料
    2. ``db.users.find({“name”:”feng”})``    #查詢users集合中符合name=feng的所有資料
    3. ``db.users.findOne()``                #查詢users集合中的第一筆資料
    4. ``db.users.findOne({“name”:”feng”})``    #查詢users集合中name=feng的第一筆資料

- 排序
    1. ``db.collection.find({}).sort({ "key1" : -1 ,"key2" : 1 })``  1代表升冪排列，-1代表降冪



[官方文件](https://docs.mongodb.com/manual/tutorial/query-documents/)

[小工具](https://dotblogs.com.tw/grayyin/2020/06/01/133724)

### GitHub

> GitHub 是什麼？
簡單來說，GitHub 就是一個提供存取 Git 的站點、遠端數據庫，可以將自己寫好的專案分享上傳。
但要注意的是！Git 跟 GitHub 兩個完全是不一樣的東西唷！

- Git 被作為工具，讓我們執行檔案的管理並提交到儲存庫；而 GitHub 則是一個網站，本體是一個 Git Server ，提供除了基本的存取站點，也提供一些社群功能。

- GitHub 是一個由 GitHub 公司所建立的網站，同時提供付費帳戶與免費帳戶，讓使用著可以在這個 Git Server 建立自己的數據庫，並存取保管中的代碼。而相較於其他的 Git Server ，GitHub 還有一個特點是它類似於一個社群網頁，擁有追蹤（ Fallow ）、按讚（ Star ）其他使用者、數據庫有誰參與並追蹤最新版本，也有評論並提供複製（ Fork ）專案給予其他人的專案建議，而其他人同樣也可以回饋給你的專案。

>除此之外，提醒 GitHub 的 G 跟 Ｈ 都是大寫英文喔！

#### 設定屬於自己的 GitHub 空間！
>了解 GitHub 是什麼以後，接下來就動手將我們的專案 Push 上去吧～

1. 註冊 GitHub
    - 到 GitHub 官網註冊會員。

    - 註冊完後，點擊 Profile ，可以進入個人的 GitHub 頁面。

2. 在 GitHub 建立新的數據庫
    - 當要上傳檔案時，我們需要在 GitHub 開新的專案。

    - 可以點選右上角會員頭貼的下拉選單，選擇「Your Repositiories」後進入頁面，再點選 「 New 」新增專案。

    - 或是旁邊的 + 號也可以選擇 「New repository」

    - 之後就會進入到 Creat a new repository 的頁面：

    - 填寫專案名稱、選擇存取權限、按下 Creat repository 完成新增專案。

> 頁面說明
creat a new repository on the command line - 適用於全新開始
push an existing repository from the command line - 上傳現存專案

## Some References
> 沒事就看看吧
- [express API doc](https://expressjs.com/en/4x/api.html)
- history
  - [http 發展歷史](https://segmentfault.com/a/1190000023312905)
  - [瀏覽器 大戰](https://www.mozilla.org/zh-TW/firefox/browsers/browser-history/)
  - [[Code Rush] --瀏覽器大戰紀錄片](https://www.youtube.com/watch?v=VoLUvE-ny1k)
- [OSI layer(ithome)](https://ithelp.ithome.com.tw/articles/10000021)
- [sitcon2019 共筆: 網路 / HTTP / RESTful 觀念及實做](https://hackmd.io/@SITCON/camp2019-the-net#)
- [Mopcon2020 共筆: 優雅的 API 設計 - 後端工程師必修的設計模式](https://hackmd.io/gUGu05hES1GMbdrny70iyQ)
- [Medium: 「筆記」- 何謂 HTTP 傳輸協定](https://medium.com/pierceshih/%E7%AD%86%E8%A8%98-%E4%BD%95%E8%AC%82-http-%E5%82%B3%E8%BC%B8%E5%8D%94%E5%AE%9A-1d9b5be3fd24)
- [鳥哥的 linux 私房蔡(詳細的網路描述)](http://linux.vbird.org/linux_server/0110network_basic.php#whatisnetwork)
- [DNS blog](https://medium.com/%E5%BE%8C%E7%AB%AF%E6%96%B0%E6%89%8B%E6%9D%91/%E5%9F%9F%E5%90%8D%E7%B3%BB%E7%B5%B1-dns-101-7c9fc6a1b8e6)
- [優質文章列](https://ithelp.ithome.com.tw/users/20116003/ironman/2935?page=2)
- 我看不懂
	- [syscall & TCP/IP](https://developer.ibm.com/technologies/systems/articles/au-tcpsystemcalls/)
- [自學RESTful API](https://hackmd.io/@monkenWu/Sk9Q5VoV4/https%3A%2F%2Fhackmd.io%2F%40gen6UjQISdy0QDN62cYPYQ%2FH1yxwXyNN?type=book)

