30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

瘋狂的技術宅 前端先鋒

每日前端夜話0x70每日前端夜話,陪你聊前端。
每天晚上18:00準時推送。
正文共:3220 字
預計閱讀時間: 8 分鐘
翻譯:瘋狂的技術宅
來源:freecodecamp




30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

Node.js 對初學者來說可能是令人望而卻步的,其靈活的結構和缺乏嚴格的規範使它看起來很複雜。

本教程是 Node.js,Express 框架和 MongoDB 的快速指南,重點介紹基本的 REST 路由和基本的數據庫交互。你將構建一個簡單的 API 框架模版,然後可以將其用作任何應用。

本教程適用於:你應該對 REST API 和 CRUD 操作有基本的瞭解,還有基本的 JavaScript 知識。我用的是 ES6(主要是箭頭函數),但並不是很複雜。

在本教程中,我們將爲創建一個網絡筆記應用的後端骨架 —— 類似於Google Keep,能夠執行所有的四個CRUD操作:創建、讀取、更新和刪除。

配置


如果你沒有安裝Node,請參閱此處【https://howtonode.org/how-to-install-nodejs】。

創建一個新目錄,運行 npm init,然後按照提示操作,把你的應用程序命名爲“notable”(或者你可能喜歡的其他名字)。


1npm init

一旦完成,在你的目錄中會有一個 package.json 文件。你可以開始安裝項目所需的依賴項了。

我們將使用 Express 作爲自己的框架,MongoDB 作爲數據庫,還有一個名爲 body-parser 的包來幫助處理 JSON 請求。


1npm install --save express [email protected] body-parser

我還強烈建議將 Nodemon 安裝爲 dev 依賴項。這是一個非常簡單的小包,可在文件被更改時自動重啓服務器。

如果你運行:


1npm install --save-dev nodemon

然後將以下腳本添加到 package.json:


1// package.json
2  "scripts": {
3    "dev": "nodemon server.js"
4  },

完整的 package.json 應如下所示:


 1// package.json
 2{
 3  "name": "notable",
 4  "version": "1.0.0",
 5  "description": "",
 6  "main": "server.js",
 7  "scripts": {
 8    "dev": "nodemon server.js"
 9  },
10  "author": "",
11  "license": "ISC",
12  "dependencies": {
13    "body-parser": "^1.15.2",
14    "express": "^4.14.0",
15    "mongodb": "^2.2.16"
16  },
17  "devDependencies": {
18    "nodemon": "^1.11.0"
19  }
20}

現在,你可以創建 server.js 文件並構建 API 了。

我們的服務器


首先導入 server.js 中的所有依賴項。


1// server.js
2const express        = require('express');
3const MongoClient    = require('mongodb').MongoClient;
4const bodyParser     = require('body-parser');
5const app            = express();

我們將使用 MongoClient 與數據庫進行交互。還會將應用初始化爲 Express 框架的實例。

最後一件事就是告訴你的程序開始監聽請求。

你可以指定一個端口,並像這樣開始監聽:


1// server.js
2const port = 8000;
3app.listen(port, () => {
4  console.log('We are live on ' + port);
5});

現在,如果你運行 npm run dev(或 node server.js,如果你沒有安裝 Nodemon 的話),應該在終端中看到“We are live on port 8000”的提示。

你的服務器已經啓動了。但它現在還什麼也做不了。

接下來讓我們解決這個問題。

CRUD 路由


對於本例,你要構建4條路由; 創建筆記,閱讀筆記,更新筆記和刪除筆記。

這將使你瞭解如何使用 Node 構建幾乎所有的基本路由。

但是,要測試你的API,還需要模仿客戶端發出請求。爲此,我們將使用名爲 Postman 的優秀應用。它允許你使用自定義的頭和參數進行簡單的 HTTP 請求。

安裝Postman,讓我們開始設置路由。

項目結構


大多數 Node.js 教程(以及許多真實的案例)都將所有路由放在一個很大的 routes.js 文件中。這讓我有點不舒服。相比之下,將文件拆到爲單獨的文件夾可以提高可讀性,並使大型應用更易於管理。

雖然我們現在做的不是大型應用,但仍然可以這樣做。創建以下目錄:一個 app 文件夾,裏面有一個routes文件夾,routes 裏面有 index.js 和 note_routes.js 文件。


1mkdir app
2cd app
3mkdir routes
4cd routes
5touch index.js
6touch note_routes.js

對於你的簡單小程序來說,這些目錄可能看起來有些過分,但從一開始就做好總是有意義的。

你的第一個路由


讓我們從 CRUD 中的 C 開始。你將會如何創建一個筆記?

那麼,在你開始之前,必須先要打好基礎。在Express中,路由包含在一個函數中,該函數將 Express 實例和數據庫作爲參數。

像這樣:


1// routes/note_routes.js
2module.exports = function(app, db) {
3};

然後,你可以通過 index.js 導出此函數:


1// routes/index.js
2const noteRoutes = require('./note_routes');
3module.exports = function(app, db) {
4  noteRoutes(app, db);
5  // Other route groups could go here, in the future
6};

然後導入它以便在 server.js 中使用:


 1// server.js
 2const express        = require('express');
 3const MongoClient    = require('mongodb').MongoClient;
 4const bodyParser     = require('body-parser');
 5const app            = express();
 6const port = 8000;
 7require('./app/routes')(app, {});
 8app.listen(port, () => {
 9  console.log('We are live on ' + port);
10});

請注意,由於還沒有設置數據庫,因此只需傳入一個空對象。

好的,現在你可以製作自己的 CREATE 路由了。

語法很簡單:


1// note_routes.js
2module.exports = function(app, db) {
3  app.post('/notes', (req, res) => {
4    // You'll create your note here.
5    res.send('Hello')
6  });
7};

當應用程序收到對 '/ notes' 路徑的 post 請求時,它將執行回調內的代碼 —— request 對象(包含請求的參數或JSON)和 response 對象。

你可以使用 Postman 將 POST 請求發送到 localhost:8000/notes 來測試。
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

你應該得到回覆:'Hello'。

太好了!你創建了第一個真正的路由。

下一步是在你的請求中添加一些參數並在 API 中處理它們,最後添加到你的數據庫中。

請求參數


在 Postman 中,在選擇 x-www-form-urlencoded 單選按鈕後,轉到 Body 選項卡並添加一些鍵值對。

這會將編碼後的表單數據添加到你的請求中,你可以使用 API 處理該請求。

30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]
你可以去嘗試更多的設置項。

現在在你的 note_routes.js 中,讓我們輸出 body 的內容。


1// note_routes.js
2module.exports = function(app, db) {
3  app.post('/notes', (req, res) => {
4    console.log(req.body)
5    res.send('Hello')
6  });
7};

用 Postman 發送請求,你會看到……undefined。

不幸的是,Express 無法自行處理 URL 編碼的表單。雖然你確實安裝了這個 body-parser 包……


 1// server.
 2const express        = require('express');
 3const MongoClient    = require('mongodb').MongoClient;
 4const bodyParser     = require('body-parser');
 5const app            = express();
 6const port = 8000;
 7app.use(bodyParser.urlencoded({ extended: true }));
 8require('./app/routes')(app, {});
 9app.listen(port, () => {
10  console.log('We are live on ' + port);
11});

Now you should see the body as an object in the terminal.
現在你應該將 body 視爲終端中的對象。


1{ title: 'My Note Title', body: 'What a great note.' }

第一個路由的最後一步:設置數據庫,然後添加數據。

最簡單方法是通過 mLab 設置 Mongo 數據庫的:它是最小的而且是免費的,設置的速度非常快。

創建帳戶和 MongoDB 部署後,將用戶的用戶名和密碼添加到數據庫:
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

然後複製這裏第二個 URL:
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

在項目根目錄的目錄配置中,創建一個db.js文件。


1mkdir config 
2cd config
3touch db.js

在裏面,添加剛纔的URL:


1module.exports = {
2  url : YOUR URL HERE
3};

別忘了把你的用戶名和密碼(來自數據庫用戶的密碼,而不是你的 mLab 帳戶)添加到URL中。 (如果你要將此項目提交到 Github 上,請確保包含 .gitignore 文件 像這樣, ,不要與任何人分享你的密碼。)

現在在你的 server.js 中,可以用 MongoClient 連接到數據庫了,使用它來包裝你的應用程序設置:


 1// server.js
 2const express        = require('express');
 3const MongoClient    = require('mongodb').MongoClient;
 4const bodyParser     = require('body-parser');
 5const db             = require('./config/db');
 6const app            = express();
 7const port = 8000;
 8app.use(bodyParser.urlencoded({ extended: true }));
 9MongoClient.connect(db.url, (err, database) => {
10  if (err) return console.log(err)
11  require('./app/routes')(app, database);
12  app.listen(port, () => {
13    console.log('We are live on ' + port);
14  });               
15})

如果你用的是最新版本的 MongoDB(3.0+),請將其修改爲:


 1// server.js
 2const express        = require('express');
 3const MongoClient    = require('mongodb').MongoClient;
 4const bodyParser     = require('body-parser');
 5const db             = require('./config/db');
 6const app            = express();
 7const port = 8000;
 8app.use(bodyParser.urlencoded({ extended: true }));
 9MongoClient.connect(db.url, (err, database) => {
10  if (err) return console.log(err)
11
12  // Make sure you add the database name and not the collection name
13  const database = database.db("note-api")
14  require('./app/routes')(app, database);
15  app.listen(port, () => {
16    console.log('We are live on ' + port);
17  });               
18})

這是你的基礎架構的最後一個設置!

添加到你的數據庫


MongoDB將數據存儲在 collections 中。在你的項目中,你希望將筆記存儲在一個名爲 notes 的 collection 中。

由於將數據庫作爲路徑中的 db 參數傳入,因此可以像這樣訪問它:


1db.collection('notes')

創建筆記就像在集合上調用 insert 一樣簡單:


1const note = { text: req.body.body, title: req.body.title}
2  db.collection('notes').insert(note, (err, results) => {
3}

插入完成後(或由於某種原因失敗),要麼返回錯誤或反回新創建的筆記對象。這是完整的 note_routes.js 代碼:


 1// note_routes.js
 2module.exports = function(app, db) {
 3  const collection = 
 4  app.post('/notes', (req, res) => {
 5    const note = { text: req.body.body, title: req.body.title };
 6    db.collection('notes').insert(note, (err, result) => {
 7      if (err) { 
 8        res.send({ 'error': 'An error has occurred' }); 
 9      } else {
10        res.send(result.ops[0]);
11      }
12    });
13  });
14};

試試看!使用 Postman 發送 x-www-form-urlencoded POST 請求,在 Body 選項卡下設置 title 和 body。

響應應如下所示:
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

如果你登錄mLab,你還應該能夠在數據庫中看到創建的筆記。

READ 路由


現在可以稍微加快步伐。

假設你希望通過導航到 localhost:8000/notes/{id} 來獲取剛創建的筆記。這是鏈接應該是localhost:8000/notes/585182bd42ac5b07a9755ea3。(如果你沒有得到其中筆記的 ID,可以通過檢查 mLab 或創建一個新的筆記)。

以下是 note_routes.js 中的內容:


 1// note_routes.js
 2module.exports = function(app, db) {
 3  app.get('/notes/:id', (req, res) => {
 4
 5  });
 6  app.post('/notes', (req, res) => {
 7    const note = { text: req.body.body, title: req.body.title };
 8    db.collection('notes').insert(note, (err, result) => {
 9      if (err) { 
10        res.send({ 'error': 'An error has occurred' }); 
11      } else {
12        res.send(result.ops[0]);
13      }
14    });
15  });
16};

就像以前一樣,你將在數據庫 collection 中調用一個方法。在這裏,它被恰當地命名爲 findOne。


 1// note_routes.js
 2module.exports = function(app, db) {
 3  app.get('/notes/:id', (req, res) => {
 4    const details = { '_id': <ID GOES HERE> };
 5    db.collection('notes').findOne(details, (err, item) => {
 6      if (err) {
 7        res.send({'error':'An error has occurred'});
 8      } else {
 9        res.send(item);
10      }
11    });
12  });
13app.post('/notes', (req, res) => {
14    const note = { text: req.body.body, title: req.body.title };
15    db.collection('notes').insert(note, (err, result) => {
16      if (err) { 
17        res.send({ 'error': 'An error has occurred' }); 
18      } else {
19        res.send(result.ops[0]);
20      }
21    });
22  });
23};
24

你可以通過 req.params.id 從 URL 參數中獲取 id。但是,如果你試圖將字符串插入上面的 <ID GOES HERE> 位置,它將無法正常工作。

MongoDB 不僅要求 ID 爲字符串,還要求 ID 是一個對象,它們被之爲 ObjectID。

別擔心,這很容易解決。這是完整的代碼:


 1// note_routes.js
 2var ObjectID = require('mongodb').ObjectID;
 3module.exports = function(app, db) {
 4  app.get('/notes/:id', (req, res) => {
 5    const id = req.params.id;
 6    const details = { '_id': new ObjectID(id) };
 7    db.collection('notes').findOne(details, (err, item) => {
 8      if (err) {
 9        res.send({'error':'An error has occurred'});
10      } else {
11        res.send(item);
12      } 
13    });
14  });
15app.post('/notes', (req, res) => {
16    const note = { text: req.body.body, title: req.body.title };
17    db.collection('notes').insert(note, (err, result) => {
18      if (err) { 
19        res.send({ 'error': 'An error has occurred' }); 
20      } else {
21        res.send(result.ops[0]);
22      }
23    });
24  });
25};

嘗試使用一個筆記 ID,它應如下所示:
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

DELETE 路由


實際上刪除對象與查找對象幾乎相同。你只需用 remove 函數替換 findOne 即可。這是完整的代碼:


 1// note_routes.js
 2// ...
 3  app.delete('/notes/:id', (req, res) => {
 4    const id = req.params.id;
 5    const details = { '_id': new ObjectID(id) };
 6    db.collection('notes').remove(details, (err, item) => {
 7      if (err) {
 8        res.send({'error':'An error has occurred'});
 9      } else {
10        res.send('Note ' + id + ' deleted!');
11      } 
12    });
13  });
14// ...

UPDATE 路由


最後一個! PUT 方法基本上是 READ 和 CREATE 的混合體。你找到該對象,然後更新它。如果剛纔你刪除了數據庫中唯一的筆記,那就再創建一個!

代碼:


 1// note_routes.js
 2// ...
 3  app.put('/notes/:id', (req, res) => {
 4    const id = req.params.id;
 5    const details = { '_id': new ObjectID(id) };
 6    const note = { text: req.body.body, title: req.body.title };
 7    db.collection('notes').update(details, note, (err, result) => {
 8      if (err) {
 9          res.send({'error':'An error has occurred'});
10      } else {
11          res.send(note);
12      } 
13    });
14  });
15// ...

現在你可以更新任何筆記,如下所示:
30分鐘用Node.js構建一個API服務器[每日前端夜話0x70]

請注意這些代碼還不完美 —— 比如你沒有提供正文或標題,PUT 請求將會使數據庫中的筆記上的那些字段無效。

API 完成


就這麼簡單!你完成了可以進行 CRUD 操作的 Node API。

本教程的目的是讓你熟悉 Express、Node 和 MongoDB —— 你可以用簡單的程序作爲進軍更復雜項目的跳板。

將來我將會編寫系列教程,用不同的語言和框架創建更簡單的API。如果你有興趣,請點擊關注!

原文:https://medium.freecodecamp.org/building-a-simple-node-js-api-in-under-30-minutes-a07ea9e390d2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章