在這邊使用我在上的課程 程式導師實驗計畫第四期 所提供的 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 官方說明