HTTP API 串接


Posted by fang on 2020-07-10

在這邊使用我在上的課程 程式導師實驗計畫第四期 所提供的 API 資料 書籍管理系統,為了方便對照我就把 API 文件服這貼上在這邊:

Base URL: https://lidemy-book-store.herokuapp.com

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

我先直接附上程式碼,並且在程式中間使用註解的方式進行說明,因為程式碼中有很多重複的步驟,所以會著重在 listBook,剩下的如果前面沒提到的才會再提及

// 需要先 require 會使用到的 library
const request = require('request');
const process = require('process');

// 當程式碼會一直用到同樣的網址,只有後面的路徑不一樣的時候,就可以先把跟網址存起來
const API_ENDPOINT = 'https://lidemy-book-store.herokuapp.com';

// 以下是 function,主程式的判斷在最下面,因為 ES6 語法中會希望程式碼中先有 function 的存在,再由其他程式呼叫它

// 獲取所有書籍
function listBook() {
  request.get(
    // 限制讀取 20 本,這裡是透過字串拼接 Template Literals 的方式撰寫 URL,如果要看相關用法的筆記,下方註 1 有另一篇文章的連結
    `${API_ENDPOINT}/books?_limit=20`,
    function (error, response, body) {
      // 如果報錯的話,顯示錯誤訊息,並且不要執行其他的東西
      if (error) {
        console.log('失敗,錯誤代碼為:', error);
        return;
      }
      // 如果沒有報錯,就將回傳的 body 轉為 object 型態,並且印出來
      // 另外,這邊的程式如果可以對 JSON.parse 做 try...catch 的判斷其實會更好,當初在寫的時候沒有想到,也打算保留現狀提醒自己可以再這樣改進
      const data = JSON.parse(body);
      for (let l = 0; l < data.length; l += 1) {
        console.log(`${data[l].id} ${data[l].name}`);
      }
    },
  );
}

// 獲取單一書籍資訊,因為是獲取單一一本書,所以需要傳入書的 id
function readBook(id) {
  request.get(
    `${API_ENDPOINT}/books/${id}`,
    function (error, response, body) {
      if (error) {
        console.log('失敗,錯誤代碼為:', error);
        return;
      }
      const data = JSON.parse(body);
      console.log(data);
    },
  );
}

function deleteBook(id) {
  request.delete(
    `${API_ENDPOINT}/books/${id}`,
    function (error) {
      if (error) {
        console.log('失敗,錯誤代碼為:', error);
        return;
      }
      console.log('刪除成功');
    },
  );
}

function createBook(content) {
  request.post(
    {
      url: `${API_ENDPOINT}/books`,
      // 將要改的部分用 form 包起來,此用法其是我自己還不是很熟悉,是參照 request 的官方說明去撰寫的,下方註 2 附上網址
      form: {
        name: content,
      },
    },
    function (error) {
      if (error) {
        console.log('失敗,錯誤代碼為:', error);
        return;
      }
      // 這邊因為新增之後沒有要求 server 應該要回傳給我什麼資料,所以如果程式報錯,有跑到這邊就輸出一個新增成功,當然也可以再輸出一個該新增書籍的資訊
      console.log('新增成功');
    },
  );
}

function updateBook(id, content) {
  request.patch(
    {
      url: `${API_ENDPOINT}/books/${id}`,
      form: {
        name: content,
      },
    },
    function (error) {
      if (error) {
        console.log('失敗,錯誤代碼為:', error);
        return;
      }
      console.log('更新成功');
    },
  );
}

// 這邊是主程式(揮揮手),為了讓我們可以在終端機直接輸入資料,讓程式去讀取我的輸入,所以使用 process.argv 的方法,那麼為什麼是抓取 [2] 呢?因為假設我要更新書籍,我會在終端機輸入 'node 檔案名稱.js update 1 新書籍名稱'。

// 此時 process.argv[0] 是 node;[1] 是 檔案名稱.js;[2] 是 update; [3] 是 1;[4] 是 新書籍名稱。

// 一旦搞清楚自己輸入什麼資訊,就知道我的 process.argv[2] 是用來辨別我現在要做什麼樣的操作,而 [3],[4] 則是其他需要輸入的參數

// 一開始我是使用 if...else 來撰寫這邊的主程式,後來參考老師的範例發現用 switch 會更清楚直覺,剩下的其實蠻好懂的,就是要記得加上 default 就完成啦!
switch (process.argv[2]) {
  case 'list':
    listBook();
    break;
  case 'read':
    readBook(process.argv[3]);
    break;
  case 'delete':
    deleteBook(process.argv[3]);
    break;
  case 'create':
    createBook(process.argv[3]);
    break;
  case 'update':
    updateBook(process.argv[3], process.argv[4]);
    break;
  default:
    console.log('輸入內容有錯誤');
}

註 1:字串拼接 Template Literals
註 2:request 官方說明


#API 串接 #request 示範







Related Posts

Vite系列#安裝外部套件 - Vue Axios

Vite系列#安裝外部套件 - Vue Axios

發生 Blocking 了!! 怎麼辦?

發生 Blocking 了!! 怎麼辦?

猜數字

猜數字


Comments