### GDSC NYUST x 資訊創客社 <br> ### 軟體開發工具入門讀書會 #### JS & RESTful API課程 <br> #### 2023/10/30 ( Mon ) 19:00 - 21:00 #### 講師:蘇祐民 #### 本次課程影片: <img src="" height="200px"> --- ## JS & RESTful API課程 *YoMin Su* --- ## 課程簡介 ---- ### 簡單的說 1. 了解 JS 與 TS 2. 了解RESTful API的概念 3. 實際在JS或TS上使用RESTful API ---- ### 複雜點講 - 對JS與TS的基本認識 - 學習變數宣告、陣列與物件的使用 - 函數宣告 - JS/TS的物件導向 - 非同步概念 - RESTful API基本概念 - HTTP Method說明 - API的CRUD操作 - 透過JS進行CRUD操作 - 介紹Fetch用法 - 介紹Axios套件 --- ## Part 1 ### JS / TS ---- ### What is JS/TS ? 是一個在1995年隨著瀏覽器一起出現的程式語言,在當時,被當作輔助HTML的一種『膠水語言』,隨著時間的推進,慢慢地出現了豐富的生態系與各種方便好用的套件,也才出現了現今網頁的用JS包起HTML的設計方法! ![](https://hackmd.io/_uploads/Hk1UK6nMa.png =300x) ---- ### JS / TS 哪裡不同 ? TypeScript是JavaScript的嚴格語法超集,出現的原因也很明確,由於JS本身設計上的彈性,使我們在開發時,無法明確知道每個方法本身需要的參數類型與預期的回傳結果,這樣的狀況讓微軟的開發者在設計上,遇到了相當大的困擾,也因此,才會出現TS這個結果,其本身仍是將程式碼編譯回JS,但透過『.d.ts』這樣的型別定義,就能讓開發時減少許多麻煩! ---- ### 簡單解釋 1. 微軟想寫JS 2. 發現JS沒有型別 3. 很難把程式規模寫大 4. 決定改進JS,於是有了TS 5. TS編譯後,就可透過JS運作 6. 不強迫將型別合併,可透過『.d.ts』定義 ---- ### 變數宣告時間 <table> <tr> <td> JavaScript     </td> <td> TypeScript       </td> </tr> <tr> <td> ```javascript= let x = 0; var y = "Hi"; const z = {} ``` </td> <td> ```typescript= interface IPerson { name: string; age: number; } let x: number = 0; var y: string = "Hi"; const z: IPerson = {}; ``` </td> </tr> </table> ---- ### 資料型別(TS) | Type | Description | | ------------- | ---------------- | | number | 數字(整數、小數) | | string | 不定長度字串 | | boolean | 布林值 | | \<type\>[] | 陣列宣告 | | Array\<type\> | 陣列宣告2 | | any | 任意 | ---- ### 陣列 <table> <tr> <td>JavaScript</td> <td> ```javascript= let x = [123, "abc", {}]; ``` </td> </tr> <tr> <td>TypeScript</td> <td> ```typescript= let x: number[] = [123, 456, 789]; let y: Array<string> = ["abc", "def"]; let z: any[] = [123, "abc", {}]; ``` </td> </tr> </table> ---- ### 物件 <table> <tr> <td>JavaScript</td> <td> ```javascript= let x = { name: "YoMin", age: 20, graduate: true }; ``` </td> </tr> <tr> <td>TypeScript</td> <td> ```typescript= let x: {name: string, age: number, graduate: boolean} = { name: "YoMin", age: 20, graudate: true }; ``` </td> </tr> </table> ---- ### 物件型別(TS) ```typescript= //Method 1 type Person = { name: string; age: number; } //Method 2 interface Person { name: string; age: number; } ``` ---- ### 函數 / 方法 JavaScript: ```javascript= //沒有return的話,預設會是undefined function hello(name) { console.log("Hi", name); } const hi = (name) => { console.log("Hello", name); } ``` ---- ### 函數 / 方法 TypeScript: ```typescript= //沒有return的話,預設會是undefined function hello(name: string): void { console.log("Hi", name); } const hi = (name: string): boolean => { console.log("Hello", name); return true; } ``` ---- ### 呼叫函數 JavaScript: ```javascript= hello("YoMin"); //預期輸出 => Hi YoMin hi("Kent"); //預期輸出 => Hello Kent ``` ---- ### 呼叫函數 TypeScript: ```typescript= console.log(hello("YoMin")) //預期輸出1 => Hi YoMin //預期輸出2 => undefined console.log(hi("Kent")) //預期輸出1 => Hello Kent //預期輸出2 => true ``` ---- ### 特別的函數用法 1. Callback時使用的匿名函數 ```javascript= app.get('/', function (req, res, next) { res.send("Hi!"); }); ``` 2. 箭頭函數 ```javascript= const method = () => { console.log("I'm Here!"); } ``` --- ## Part 1 ### OOP ---- ### 首先講講JS原生怎麼搞 ```javascript= function Person(name, age) { this.name = name; this.age = age; const getName = () => this.name; const getAge = () => this.age; const setName = (name) => { this.name = name; } const setAge = (age) => { this.age = age; } return { getName, getAge, setName, setAge } } ``` ---- ### 接著看看TypeScript可以怎麼用 ```typescript= class Person { private name: string; private age: number; constructor(name: string, age: number) { this.name = name; this.age = age; } function hi(): void { console.log("Hi", this.name); } function howOld(): void { console.log(`I'm ${this.age} years old!`); } function setName(name: string): void { this.name = name; } function setAge(age: number): void { this.age = age; } } ``` ---- ### 使用(JS) ```javascript= let yomin = Person("YoMin", 20); yomin.getName(); yomin.getAge(); yomin.setAge(30); yomin.getAge(); ``` ---- ### 使用(TS) ```typescript= let yomin = new Person("YoMin", 20); yomin.getName(); yomin.getAge(); yomin.setAge(30); yomin.getAge(); ``` ---- ### 多型(TS) ```typescript= abstract class Animal { private name: string; private type: string; constructor(name: string, type: string) { this.name = name; this.type = type; } abstract public eat(); } class Dog extends Animal { constructor(name: string, type: string) { super(name, type); } public eat() { console.log("Dog Eat!"); } } class Cat extends Animal { constructor(name: string, type: string) { super(name, type); } public eat() { console.log("Cat Eat!"); } } ``` ---- ### 存取修飾符 - Public - 公開,所有人都可以用 - Private - 不公開,只有自己可以用 - Protected - 半公開,只讓自己的孩子可以用 ---- ### 存取修飾符 宣告 ```typescript= public name: string = "YoMin"; private age: number = 20; protected sex: string = "Male"; ``` --- ## Part 1 ### 非同步 ---- ### 入門 首先要來推薦影片,非常好用的一部 <iframe width="800" height="450" src="https://www.youtube.com/embed/8aGhZQkoFbQ?si=guE-3h3UmjYs0L0T" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> ---- ### 非同步的基本用法 ```javascript= axios.get("/").then((res) => { console.log(res); }) ``` 這是透過Callback的方式處理的,當方法本身是非同步時,會回傳一個Promise物件,本身會有幾種狀態,讓我們來簡單說明 ---- ### Promise 物件 本身會涵蓋三種狀態,狀態說明如下: - Pending (處理中) - 正在執行,還沒有得到結果 - Fulfilled (成功) - 執行成功,正常拿到結果,可以使用 - Rejected (拒絕) - 執行失敗,過程發生錯誤,需處理錯誤 ---- ### 當成功的時候 ```javascript= .then((<parameter>) => { //Something here. }) ``` 成功的結果會作為『匿名箭頭函數的參數』被傳遞進去,而後續的程式碼,將寫在該函數的作用域中 ---- ### 當失敗的時候 ```javascript= .catch((err) => { console.log(err); //Something here }) ``` 失敗的結果一樣會作為函數的參數被傳遞進去,通常會將其顯示在終端上,方便進行除錯。 ---- ### 範例用法 ```javascript= axios.get("/") .then((res) => { console.log(res); }) .catch((err) => { console.log(err); }); ``` ---- ### Callback Hell (波動拳) ![](https://hackmd.io/_uploads/Hk3SOJpGT.png) ---- ### 另一種使用非同步的語法糖 - async - 標記為非同步,會在背境繼續執行 - await - 等待,讓程式等待執行結果出來 ---- ### async / await 實作 ```javascript= async hi() { let result = await someMethod(); console.log(result); } ``` 如果今天是透過TS進行設計的話,沒有正確處理Promise物件時,TS的解析器會直接跳出錯誤,避免不正確的結果被繼續使用下去! --- ## Part 2 ### RESTful API 基本概念 ---- ### 什麼是RESTful API ? - 是一種設計風格,而非是標準 - 通常是與HTTP、URI、XML及HTML一起使用 - 資源是由URI來指定 - 對資源的操作包括取得、建立、修改和刪除,剛好能對應HTTP提供的GET、POST、PUT(PATCH)和DELETE方法。 ---- ### RESTful的特色 - Uniform Interface:統一介面。 - Stateless:無狀態。 - Cacheable:可快取。 - Client-Server:客戶伺服器分離模式,任何一個客戶端與伺服器都是可替換的。 - Layered System:分層的系統,客戶端不知道他聯絡的是不是最終伺服器。 > 源自Wikipedia ---- ### 來看看URL的每個部分 ![](https://hackmd.io/_uploads/HJd5LgpG6.png) ---- ### CRUD 操作 | Methods | Description | | ---------- | ----------- | | GET | 取得資料 | | POST | 新增資料 | | PUT(PATCH) | 更新資料 | | DELETE | 刪除資料 | --- ## Part 3 ### 實際操作 ---- ### 環境準備 1. 可以使用你的瀏覽器(限制較多) 2. 或是使用Node.js 安裝指令: ```bash= sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo mkdir -p /etc/apt/keyrings curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg NODE_MAJOR=20 echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list ``` ---- ### 原生的Fetch ```javascript= fetch("https://www.google.com/") .then((res) => { console.log(res); }); ``` ---- ### 拿到的回應 ![](https://hackmd.io/_uploads/HJSPCg6Ma.png) ---- ### 來看看內容 ```javascript= fetch("https://www.google.com/") .then((res) => { return res.text(); }) .then((data) => { console.log(data); }); ``` ---- ### 全都是HTML呢~ ![](https://hackmd.io/_uploads/S1MmE-pMp.png) ---- ### 如果是JSON呢? ```javascript= fetch("https://www.google.com/") .then((res) => { return res.json(); }) .then((data) => { console.log(data); }); ``` ---- ### 出現了錯誤! 因為在對Google請求後,回應的是網站內容,不是JSON資料 ![](https://hackmd.io/_uploads/SkrIzZpMp.png) ---- ### 改用中央氣象署看看 請註冊他們的帳號,並申請一組自己的API授權碼 ![](https://hackmd.io/_uploads/S1ks7Z6f6.png) ---- ### 課程範例用的路由 > 點我進去:[API說明文件](https://opendata.cwa.gov.tw/dist/opendata-swagger.html?urls.primaryName=openAPI#/%E9%A0%90%E5%A0%B1/get_v1_rest_datastore_F_D0047_091) ![](https://hackmd.io/_uploads/HJkT4Zpza.png) ---- ### 複製到Node.js嘗試看看 ![](https://hackmd.io/_uploads/SJzeHZpz6.png) ---- ### 如果想使用回傳內的資料呢? ![](https://hackmd.io/_uploads/ByNCrZpfp.png) ---- ### 有關fetch的補充說明 - [Fetch MDN](https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API) - [AJAX 與 Fetch API](https://eyesofkids.gitbooks.io/javascript-start-from-es6/content/part4/ajax_fetch.html) ---- ### 接著來看看Axios套件 ---- ### 安裝Axios ```bash= mkdir axios_test cd axios_test yarn init #全部預設即可 yarn add axios node ``` ---- ### 來嘗試看看剛剛的範例 ```javascript= let axios = require('axios'); axios.get('https://www.google.com/') .then((res) => console.log(res)); ``` ![](https://hackmd.io/_uploads/r1aH_b6fT.png) ---- ### 如果要取得資料的話 ```javascript= axios.get('https://www.google.com/') .then((res) => console.log(res.data)); ``` ![](https://hackmd.io/_uploads/BkMdu-pM6.png) ---- ### Axios 與 Fetch 差在哪裡? - 簡化性: axios提供了一個簡易的API,使HTTP請求更容易使用,並自動處理了許多常見的請求和回應工作。 - 攔截器: axios可以使用攔截器在請求和回應的不同階段執行自定義邏輯,這對於添加驗證、日誌記錄等非常有用。 - 預設設定: 您可以設定Global的預設設置,像是基本URL、超時(Timeout)設定等,以減少重複性工作。 - 自動JSON解析: axios會自動解析JSON回應,而使用Fetch需要手動處理。 --- ## Part 4 ### Q&A + 回家作業 ---- ### 有任何問題嗎? ---- ### 回家作業 > TBD ---- ### 學習資源 - [TypeScript 新手指南](https://willh.gitbook.io/typescript-tutorial/) - [MDN Fetch API](https://developer.mozilla.org/zh-TW/docs/Web/API/Fetch_API) - [GitHub: axios](https://github.com/axios/axios) --- # BYE ![](https://hackmd.io/_uploads/rkmSYWTMT.png)
{"title":"JS & Restful API課程","description":"YoMin Su","slideOptions":"{\"transition\":\"concave\",\"allottedMinutes\":100}","contributors":"[{\"id\":\"f8142aa2-66aa-4867-821d-2f1ffff7a7ba\",\"add\":10581,\"del\":28}]"}
    308 views
   Owned this note