[Week4] JS 實作串接 API(三)


Posted by 生菜 on 2020-07-30

前情提要

本篇從 程式導師作業第四週作業 出發學習 JS 串接 API 實作。
前兩篇記錄於此:
[Week4] JS 實作串接 API(一)
[Week4] JS 實作串接 API(二)

hw3:周遊列國

你的好麻吉小立是一個很愛到處旅遊的人,在前一陣子才靠著便宜的 bug 機票以及特價的商務艙玩遍了許多地方。不過小立一直有個困擾,那就是他希望了解更多跟國家有關的知識,因此他來請你幫忙寫一個搜尋國家資訊的小程式。
這個程式很簡單,只要輸入國家的英文名字,就能夠查詢符合的國家的資訊,會輸出以下幾項:

  1. 國家名稱
  2. 首都
  3. 使用的貨幣名稱
  4. 電話國碼

偷看答案

const request = require('request');
const args = process.argv;
const API_ENDPOINT = 'https://restcountries.eu/rest/v2';

const name = args[2];

if (!name) {
  return console.log('請輸入國家名稱');
}

request(`${API_ENDPOINT}/name/${name}`, (err, res, body) => {
  if (err) {
    return console.log('抓取失敗', err);
  }
  const data = JSON.parse(body);
  if (data.status === 404) {
    return console.log('找不到國家資訊')
  }

  for (let i = 0; i < data.length; i++) {
    console.log('============')
    console.log('國家:' + data[i].name);
    console.log('首都:' + data[i].capital);
    console.log('貨幣:' + data[i].currencies[0].code);
    console.log('國碼:' + data[i].callingCodes[0]);
  }
})

分析思路

  1. 如果沒有輸入名稱 ( args[2] 是空的) ,回傳「請輸入國家名稱」。
    (用 return 連後面也不會跑嗎?)
  2. 先看 err 是否存在,有的話就回傳「抓取失敗」。
  3. data.status 可回傳 HTTP 的狀態碼。(因為 API 中有個 key 就叫 status )。
  4. 把結果印下來。

出錯ㄌ

const data 只會在 request 函式中作用,因此要將最後印下來的作業於其中完成,否則會無法找到 data 。

hw4:探索新世界

參考資料:
【第十五天】突發任務:Twitch API

之前幫秋秋鞋做完那個小程式以後,你會寫程式的消息似乎就傳開了,有一位 Twitch 平台實況主果凍跑來聯繫你,想請你幫忙做個東西。
事情是這樣的,他原本是 LOL 的玩家,但因為某些原因帳號被 ban 掉了,為了維持實況的熱度,需要去找其他遊戲來玩,可是他又不知道哪些遊戲比較熱門,會有比較多人觀看。
因此,他寫請你寫一個小程式,能夠去撈取 Twitch 上面受歡迎的遊戲,他就能夠參考這個列表來決定要實況哪個遊戲。
由於你偶爾也會看他的實況,所以你欣然接受了這個挑戰,準備來串串看真實世界的 API。
請參考 Twitch API v5 的文件,寫一隻程式去呼叫 Twitch API,並拿到「最受歡迎的遊戲列表(Get Top Games)」,並依序印出目前觀看人數跟遊戲名稱。
在這個作業中,你必須自己看懂 Twitch API 的文件,知道怎麼去申請一個 Application 拿到 ClientID,並且在 API 文件當中找到對的那一個 API(Get Top Games),而且務必記得要在 request header 中帶上 ClientID 跟另一個參數 Accept,值是:application/vnd.twitchtv.v5+json。
還有一件事情要提醒大家,Twitch API 有兩個版本,一個是最新版(New Twitch API,代號 Helix),一個是舊版的(Twitch API v5,代號 kraken),我們這次要串接的是舊版的,不要搞錯版本囉。

得到 ClientID

可參考文章:【第十五天】突發任務:Twitch API

如何加入 request header

request({
  method: 'GET',
  url: <url>,
  headers: {
    '參數': 值,
  }
}, function(error,response,body){
  // 其他內容
})

試著得到 body ,及其後

request ({
    method: 'GET',
    url: apiUrl,
    headers: {
        'Client-ID': clientID,
        'Accept': 'application/vnd.twitchtv.v5+json',
    }
}, (err, res, body) => {
    console.log(body)
})

整理得到的 JSON 後得到:

此時要做的事情:

  1. 確認沒有 err
  2. 依序印出遊戲人次和名稱

for...of

參考資料:MDN
for...of 可將陣列的值依序取出:

for (variable of iterable) {
    //statements
}

結果 ESlint 不建議 for...of ,哈哈哈哈哈。
還是想用可參考: javascript - ESLint提示“無限制的語法迭代器/生成器需要regenerator-runtime”

最終結果

const request = require('request');

const apiUrl = 'https://api.twitch.tv/kraken/games/top';
const clientID = 不給你複製我的ID;

request({
  method: 'GET',
  url: apiUrl,
  headers: {
    'Client-ID': clientID,
    Accept: 'application/vnd.twitchtv.v5+json',
  },
}, (err, res, body) => {
  if (err) return console.log('抓取失敗');
  const data = JSON.parse(body).top;
  for (const i of data) {
    console.log(i.viewers, i.game.name);
  }
  return true;
});

沒什麼關聯但記錄一下:curl 的用法

hw5:簡答題

參考資料:
zoeaeen13 同學的作業
API 到底是什麼? 用白話文帶你認識
HTTP 狀態碼

請以自己的話解釋 API 是什麼?

API 全名為 Application Programming Interface,中文翻譯為「應用程式介面」。簡單來說就是交換資料的管道。

舉例來說好了,今天你進到一家拉麵店,要如何和廚房說你要什麼品項?因為你已經來過很多次了,所以走到拉麵販賣機前點餐,而 這個販賣機就是 API 。你和廚房可以透過販賣機溝通(使用 API),你開店的時候別人也可以從販賣機點餐(提供 API)。

讓我們整理一下:

  • 店面 = 網站或 APP
  • 販賣機 = API
  • 你 = 使用者
  • 廚房 = 資料庫
  • 拉麵 = 資料

請找出三個課程沒教的 HTTP status code 並簡單介紹

status code 表示一個 HTTP 要求是否已經被完成,代表 API 層的執行狀態。
status code 大約分成幾種:

  • 1xx = Informational(資訊)
  • 2xx = Success(成功)
  • 3xx = Redirect(重定向)
  • 4xx = User error(客戶端錯誤)
  • 5xx = Server error(伺服器端錯誤)

以下列出課程沒提到的 HTTP status code:
201 Created:請求成功且新的資源成功被創建,通常用於 POST 或一些 PUT 請求後的回應。
400 Bad Request:此回應意味伺服器因為收到無效語法,而無法理解請求。
403 Forbidden:用戶端並無訪問權限,例如未被授權,所以伺服器拒絕給予應有的回應。不同於 401,伺服端知道用戶端的身份。

假設你現在是個餐廳平台,需要提供 API 給別人串接並提供基本的 CRUD 功能,包括:回傳所有餐廳資料、回傳單一餐廳資料、刪除餐廳、新增餐廳、更改餐廳,你的 API 會長什麼樣子?請提供一份 API 文件。

參考資料:
[Week4] JS 實作串接 API(一)
[Week4] JS 實作串接 API(二)

Base URL: https://v61265.com

說明 Method path 參數 範例
獲取所有餐廳資料 GET /restaurants _limit:限制回傳資料數量 /restaurants?_limit=5
獲取單一餐廳資料 GET /restaurants/:id /restaurant/10
新增餐廳 POST /restaurants name: 店名
刪除餐廳 DELETE /reataurants/:id
更改餐廳資訊 PATCH /restaurants/:id name: 店名

回傳所有餐廳資料

const request = require('request');

request('https://v61265.com/reataurants', (err, res, body) => {
  // 這裡是你要的內容
});

回傳單一餐廳資料

const request = require('request')

request(`https://v61265.com/restaurants/${id}`, (err, res, body) => {
  //這裡是你要的內容
});

增新餐廳

const request = require('request');

request.post( {
  url: 'https://v61265.com/restaurants',
  form: {
    name //新餐廳名稱
  },
}, (err, res, body) => {
  //這裡是你想要的內容
});

刪除餐廳

const request = require('request');

request.delete(`https://v61265.com/restaurants/${id}`, (err, res, body) => {
  //這裡可以加其他東西
});

更改餐廳資訊

const request = require('request');

request.patch( {
  url: `https://v61265.com/restaurants/${id}`,
  form: { name }
}, (err,res,body) => {
  //可以加其他東西
});

最後附上有時間可以回頭看的: [原來後端要知道] 如何寫 API 文件? #Apiary #API Blueprint # Markdown










Related Posts

用 Node.js 快速打造 RESTful API

用 Node.js 快速打造 RESTful API

一個有趣的 styled components bug

一個有趣的 styled components bug

CS50 Hash Table

CS50 Hash Table


Comments