使用Node.js和Express編寫您的第一個API:連接數(shù)據(jù)庫

使用Node.js和Express編寫您的第一個API:連接數(shù)據(jù)庫

使用 Node.JSexpress 構(gòu)建 REST API:連接數(shù)據(jù)庫

在第一個教程“了解 restful API”中,我們了解了 REST 架構(gòu)是什么、http 請求方法和響應(yīng)是什么,以及如何了解 RESTful API 端點。在第二個教程“如何設(shè)置 Express API 服務(wù)器”中,我們學(xué)習(xí)了如何使用 Node 的內(nèi)置 http 模塊和 Express 框架構(gòu)建服務(wù)器,以及如何將我們創(chuàng)建的應(yīng)用程序路由到不同的 URL 端點。

目前,當(dāng) API 端點被 GET 請求命中時,我們使用靜態(tài)數(shù)據(jù)以 json 源的形式顯示用戶信息。在本教程中,我們將設(shè)置一個 mysql 數(shù)據(jù)庫來存儲所有數(shù)據(jù),從 node.js 應(yīng)用程序連接到數(shù)據(jù)庫,并允許 API 使用 GET、POST、PUT,和 delete 方法創(chuàng)建完整的 API。

安裝

到目前為止,我們還沒有使用數(shù)據(jù)庫來存儲或操作任何數(shù)據(jù),因此我們將設(shè)置一個。本教程將使用 MySQL,如果您的計算機上已安裝 MySQL,則可以繼續(xù)下一步。

如果您沒有安裝 MySQL,您可以下載適用于 macoswindows 的 MAMP,它提供免費的本地服務(wù)器環(huán)境和數(shù)據(jù)庫。下載完成后,打開程序并單擊啟動服務(wù)器啟動 MySQL。

除了設(shè)置 MySQL 本身之外,我們還需要 GUI 軟件來查看數(shù)據(jù)庫和表。對于 Mac,請下載 SequelPro,對于 Windows,請下載 SQLyog。下載并運行 MySQL 后,您可以使用 SequelPro 或 SQLyog 在端口 3306 上使用用戶名 root 和密碼 root 連接到 localhost。

在此處設(shè)置完所有內(nèi)容后,我們就可以繼續(xù)為 API 設(shè)置數(shù)據(jù)庫。

設(shè)置數(shù)據(jù)庫

在數(shù)據(jù)庫查看軟件中,添加一個新數(shù)據(jù)庫并將其命名為 api。確保 MySQL 正在運行,否則您將無法連接到 localhost。

創(chuàng)建 api 數(shù)據(jù)庫后,移入該數(shù)據(jù)庫并運行以下查詢來創(chuàng)建新表。

CREATE TABLE `users` (   `id`       int(11)     unsigned NOT NULL AUTO_INCREMENT,   `name`     varchar(30) DEFAULT '',   `email`    varchar(50) DEFAULT '',   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

此 SQL 查詢將創(chuàng)建 users 表的結(jié)構(gòu)。每個用戶都會有一個自動遞增的 ID、姓名和電子郵件地址。

我們還可以通過運行 INSERT 查詢,使用當(dāng)前通過靜態(tài) JSON 數(shù)組顯示的相同數(shù)據(jù)填充數(shù)據(jù)庫。

INSERT INTO users (name, email)       VALUES ('Richard Hendricks', 'richard@piedpiper.com'),              ('Bertram Gilfoyle',  'gilfoyle@piedpiper.com'); 

id字段不需要輸入,因為它是自動遞增的。此時,我們已經(jīng)有了表的結(jié)構(gòu)以及一些可以使用的示例數(shù)據(jù)。

連接到 MySQL

回到我們的應(yīng)用程序,我們必須從 Node.js 連接到 MySQL 才能開始處理數(shù)據(jù)。之前,我們安裝了 mysql npm 模塊,現(xiàn)在我們要使用它。

創(chuàng)建一個名為data的新目錄并創(chuàng)建一個config.js文件。

我們首先需要 data/config.js 中的 mysql 模塊。

const mysql = require('mysql'); 

讓我們創(chuàng)建一個 config 對象,其中包含主機、用戶、密碼和數(shù)據(jù)庫。這應(yīng)該引用我們制作的api數(shù)據(jù)庫并使用默認的localhost設(shè)置。

// Set database connection credentials const config = {     host: 'localhost',     user: 'root',     password: 'root',     database: 'api', }; 

為了提高效率,我們將創(chuàng)建一個 MySQL 池,它允許我們一次使用多個連接,而不必手動打開和關(guān)閉多個連接。

// Create a MySQL pool const pool = mysql.createPool(config); 

最后,我們將導(dǎo)出 MySQL 池,以便應(yīng)用程序可以使用它。

// Export the pool module.exports = pool; 

您可以在我們的 github 存儲庫中查看完整的數(shù)據(jù)庫配置文件。

現(xiàn)在我們正在連接到 MySQL 并且設(shè)置已完成,我們可以繼續(xù)通過 API 與數(shù)據(jù)庫進行交互。

從 MySQL 獲取 API 數(shù)據(jù)

目前,我們的 routes.js 文件正在手動創(chuàng)建用戶的 JSON 數(shù)組,如下所示。

const users = [{ ... 

由于我們不再使用靜態(tài)數(shù)據(jù),因此我們可以刪除整個數(shù)組并將其替換為指向 MySQL 池的鏈接。

// Load the MySQL pool connection const pool = require('../data/config'); 

以前,/users 路徑的 GET 發(fā)送靜態(tài) users 數(shù)據(jù)。我們更新后的代碼將改為在數(shù)據(jù)庫中查詢該數(shù)據(jù)。我們將使用 SQL 查詢 select 來自 users 表,如下所示。

SELECT * FROM users 

這是我們新的 /users 獲取路由的樣子,使用 pool.query() 方法。

// Display all users app.get('/users', (request, response) => {     pool.query('SELECT * FROM users', (error, result) => {         if (error) throw error;          response.send(result);     }); }); 

在這里,我們運行 SELECT 查詢,然后通過 /users 端點將結(jié)果以 JSON 形式發(fā)送到客戶端。如果您重新啟動服務(wù)器并導(dǎo)航到 /users 頁面,您將看到與以前相同的數(shù)據(jù),但現(xiàn)在它是動態(tài)的。

使用 URL 參數(shù)

到目前為止,我們的端點都是靜態(tài)路徑 – / root 或 /users – 但是當(dāng)我們只想查看有關(guān)特定用戶的數(shù)據(jù)時該怎么辦?我們需要使用可變端點。

對于我們的用戶,我們可能希望根據(jù)每個用戶的唯一 ID 檢索有關(guān)每個用戶的信息。為此,我們將使用冒號 (:) 來表示它是一個路由參數(shù)。

// Display a single user by ID app.get('/users/:id', (request, response) => {         ...     }); }); 

我們可以使用 request.params 屬性檢索此路徑的參數(shù)。由于我們的名稱為 id,因此我們將這樣引用它。

const id = request.params.id; 

現(xiàn)在,我們將在 SELECT 語句中添加 WHERE 子句,以僅獲取具有指定 id 的結(jié)果。

我們將使用 ? 作為占位符以避免 SQL 注入,并將 id 作為參數(shù)傳遞,而不是構(gòu)建一個連接字符串,這會降低安全性。

pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => {     if (error) throw error;      response.send(result); }); 

我們個人用戶資源的完整代碼現(xiàn)在如下所示:

// Display a single user by ID app.get('/users/:id', (request, response) => {     const id = request.params.id;      pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => {         if (error) throw error;          response.send(result);     }); }); 

現(xiàn)在您可以重新啟動服務(wù)器并導(dǎo)航到 https://localhost/users/2 以僅查看 Gilfoyle 的信息。如果出現(xiàn) Cannot GET /users/2 之類的錯誤,則說明您需要重新啟動服務(wù)器。

訪問此 URL 應(yīng)返回一個結(jié)果。

[{     id: 2,     name: "Bertram Gilfoyle",     email: "gilfoyle@piedpiper.com" }] 

如果您看到的是這樣的內(nèi)容,那么恭喜您:您已成功設(shè)置動態(tài)路由參數(shù)!

發(fā)送 POST 請求

到目前為止,我們所做的一切都使用了 GET 請求。這些請求是安全的,這意味著它們不會改變服務(wù)器的狀態(tài)。我們只是查看 JSON 數(shù)據(jù)。

現(xiàn)在我們將開始通過使用 POST 請求添加新數(shù)據(jù)來使 API 真正動態(tài)化。

我之前在理解 REST 文章中提到,我們不會在 URL 中使用 add 或 delete 等動詞來執(zhí)行操作。為了向數(shù)據(jù)庫添加新用戶,我們將 POST 到我們查看它們的同一 URL,但只需為其設(shè)置一個單獨的路由。

// Add a new user app.post('/users', (request, response) => {     ... }); 

請注意,我們現(xiàn)在使用 app.post() 而不是 app.get()。

由于我們是創(chuàng)建而不是讀取,因此我們將在此處使用 INSERT 查詢,就像我們在數(shù)據(jù)庫初始化時所做的那樣。我們將整個 request.body 發(fā)送到 SQL 查詢。

pool.query('INSERT INTO users SET ?', request.body, (error, result) => {     if (error) throw error; 

我們還將指定響應(yīng)的狀態(tài)為 201,它代表 Created。為了獲取最后插入的項目的 id,我們將使用 insertId 屬性。

response.status(201).send(`User added with ID: ${result.insertId}`); 

我們的整個 POST 接收代碼將如下所示。

// Add a new user app.post('/users', (request, response) => {     pool.query('INSERT INTO users SET ?', request.body, (error, result) => {         if (error) throw error;          response.status(201).send(`User added with ID: ${result.insertId}`);     }); }); 

現(xiàn)在我們可以通過發(fā)送一個 POST 請求了。大多數(shù)情況下,當(dāng)您發(fā)送 POST 請求時,您是通過 Web 表單執(zhí)行的。我們將在本文末尾學(xué)習(xí)如何進行設(shè)置,但發(fā)送測試 POST 的最快、最簡單的方法是使用 cURL,使用 -d (–data) 標(biāo)志。

我們將運行 curl -d,后跟包含所有鍵/值對和請求端點的查詢字符串。

curl -d "name=Dinesh Chugtai&email=dinesh@piedpiper.com" http://localhost:3002/users 

發(fā)送此請求后,您應(yīng)該會從服務(wù)器收到響應(yīng)。

User added with ID: 3 

如果您導(dǎo)航到 http://localhost/users,您將看到添加到列表中的最新條目。

發(fā)送 PUT 請求

POST 對于添加新用戶很有用,但我們希望使用 PUT 來修改現(xiàn)有用戶。 PUT 是冪等的,這意味著您可以多次發(fā)送相同的請求,并且只會執(zhí)行一個操作。這與 POST 不同,因為如果我們多次發(fā)送新用戶請求,它會不斷創(chuàng)建新用戶。

對于我們的 API,我們將設(shè)置 PUT 以便能夠處理編輯單個用戶,因此這次我們將使用 :id 路由參數(shù)。

讓我們創(chuàng)建一個 UPDATE 查詢,并確保它僅適用于帶有 WHERE 子句的請求 ID。我們使用兩個 ? 占位符,我們傳遞的值將按順序排列。

// Update an existing user app.put('/users/:id', (request, response) => {     const id = request.params.id;      pool.query('UPDATE users SET ? WHERE id = ?', [request.body, id], (error, result) => {         if (error) throw error;          response.send('User updated successfully.');     }); }); 

在我們的測試中,我們將編輯用戶 2 并將電子郵件地址從 gilfoyle@piedpiper.com 更新為 bertram@piedpiper.com。我們可以再次使用 cURL,并使用 [-X (–request)] 標(biāo)志來明確指定我們要通過其發(fā)送 PUT 請求。

curl -X PUT -d "name=Bertram Gilfoyle" -d "email=bertram@piedpiper.com" http://localhost:3002/users/2 

請確保在發(fā)送請求之前重新啟動服務(wù)器,否則您將收到 Cannot PUT /users/2 錯誤。

你應(yīng)該看到這個:

User updated successfully. 

現(xiàn)在應(yīng)該更新 ID 為 2 的用戶數(shù)據(jù)。

發(fā)送刪除請求

我們完成 API 的 CRUD 功能的最后一個任務(wù)是選擇從數(shù)據(jù)庫中刪除用戶。此請求將使用 DELETE SQL 查詢和 WHERE,并且它將刪除由路由參數(shù)指定的單個用戶。

// Delete a user app.delete('/users/:id', (request, response) => {     const id = request.params.id;      pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => {         if (error) throw error;          response.send('User deleted.');     }); }); 

我們可以再次使用 -X 和 cURL 來發(fā)送刪除。讓我們刪除我們創(chuàng)建的最新用戶。

curl -X DELETE http://localhost:3002/users/3 

您將看到成功消息。

User deleted. 

導(dǎo)航到 http://localhost:3002,您會看到現(xiàn)在只有兩個用戶。

恭喜!至此,API就完成了。訪問 GitHub 存儲庫以查看 routes.js 的完整代碼。

通過request模塊發(fā)送請求

在本文的開頭,我們安裝了四個依賴項,其中之一是 request 模塊。您可以創(chuàng)建一個包含所有數(shù)據(jù)的新文件并將其發(fā)送,而不是使用 cURL 請求。我將創(chuàng)建一個名為 post.js 的文件,該文件將通過 POST 創(chuàng)建一個新用戶。

const request = require('request');  const json = {     "name": "Dinesh Chugtai",     "email": "dinesh@piedpiper.com", };  request.post({     url: 'http://localhost:3002/users',     body: json,     json: true, }, function (error, response, body) {     console.log(body); }); 

我們可以在服務(wù)器運行時在新的終端窗口中使用 node post.js 來調(diào)用它,它與使用 cURL 具有相同的效果。如果 cURL 出現(xiàn)問題,request 模塊很有用,因為我們可以查看錯誤、響應(yīng)和正文。

通過 Web 表單發(fā)送請求

通常,POST 和其他改變服務(wù)器狀態(tài)的 HTTP 方法是使用 html 表單發(fā)送的。在這個非常簡單的示例中,我們可以在任何地方創(chuàng)建一個 index.html 文件,并為姓名和電子郵件地址創(chuàng)建一個字段。表單的操作將指向資源,在本例中為 http//localhost:3002/users,我們將方法指定為 post。

創(chuàng)建index.html并向其中添加以下代碼:

        <meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Node.js Express REST API</title>

在瀏覽器中打開此靜態(tài) HTML 文件,填寫該文件,然后在服務(wù)器在終端中運行時發(fā)送它。您應(yīng)該會看到 添加了 ID 為 4 的用戶的響應(yīng),并且您應(yīng)該能夠查看新的用戶列表。

結(jié)論

在本教程中,我們學(xué)習(xí)了如何將 Express 服務(wù)器連接到 MySQL 數(shù)據(jù)庫,并設(shè)置與路徑和動態(tài)路由的 GET、POST、PUT 和 DELETE 方法相對應(yīng)的路由參數(shù)。我們還學(xué)習(xí)了如何使用 cURL、Node.js request 模塊和 HTML 表單向 API 服務(wù)器發(fā)送 HTTP 請求。

此時,您應(yīng)該非常了解 RESTful API 的工作原理,并且您現(xiàn)在可以使用 Express 和 MySQL 在 Node.js 中創(chuàng)建自己的成熟 API!

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊7 分享