疯狂的技术宅 前端先锋 前端
每日前端夜话0x70每日前端夜话,陪你聊前端。
天天晚上18:00准时推送。
正文共:3220 字
预计阅读时间: 8 分钟
翻译:疯狂的技术宅
来源:freecodecampnode
Node.js 对初学者来讲多是使人望而却步的,其灵活的结构和缺少严格的规范使它看起来很复杂。git
本教程是 Node.js,Express 框架和 MongoDB 的快速指南,重点介绍基本的 REST 路由和基本的数据库交互。你将构建一个简单的 API 框架模版,而后能够将其用做任何应用。mongodb
本教程适用于:你应该对 REST API 和 CRUD 操做有基本的了解,还有基本的 JavaScript 知识。我用的是 ES6(主要是箭头函数),但并非很复杂。数据库
在本教程中,咱们将为建立一个网络笔记应用的后端骨架 —— 相似于Google Keep,可以执行全部的四个CRUD操做:建立、读取、更新和删除。express
若是你没有安装Node,请参阅此处【https://howtonode.org/how-to-install-nodejs】。npm
建立一个新目录,运行 npm init,而后按照提示操做,把你的应用程序命名为“notable”(或者你可能喜欢的其余名字)。json
1npm init
一旦完成,在你的目录中会有一个 package.json 文件。你能够开始安装项目所需的依赖项了。小程序
咱们将使用 Express 做为本身的框架,MongoDB 做为数据库,还有一个名为 body-parser 的包来帮助处理 JSON 请求。后端
1npm install --save express mongodb@2.2.16 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”的提示。
你的服务器已经启动了。但它如今还什么也作不了。
接下来让咱们解决这个问题。
对于本例,你要构建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 来测试。
你应该获得回复:'Hello'。
太好了!你建立了第一个真正的路由。
下一步是在你的请求中添加一些参数并在 API 中处理它们,最后添加到你的数据库中。
在 Postman 中,在选择 x-www-form-urlencoded 单选按钮后,转到 Body 选项卡并添加一些键值对。
这会将编码后的表单数据添加到你的请求中,你可使用 API 处理该请求。
你能够去尝试更多的设置项。
如今在你的 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 部署后,将用户的用户名和密码添加到数据库:
而后复制这里第二个 URL:
在项目根目录的目录配置中,建立一个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。
响应应以下所示:
若是你登陆mLab,你还应该可以在数据库中看到建立的笔记。
如今能够稍微加快步伐。
假设你但愿经过导航到 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,它应以下所示:
实际上删除对象与查找对象几乎相同。你只需用 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// ...
最后一个! 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// ...
如今你能够更新任何笔记,以下所示:
请注意这些代码还不完美 —— 好比你没有提供正文或标题,PUT 请求将会使数据库中的笔记上的那些字段无效。
就这么简单!你完成了能够进行 CRUD 操做的 Node API。
本教程的目的是让你熟悉 Express、Node 和 MongoDB —— 你能够用简单的程序做为进军更复杂项目的跳板。
未来我将会编写系列教程,用不一样的语言和框架建立更简单的API。若是你有兴趣,请点击关注!
原文:https://medium.freecodecamp.org/building-a-simple-node-js-api-in-under-30-minutes-a07ea9e390d2