用Node.js如何快速构建一个API服务器?

用Node.js如何快速构建一个API服务器?

Node.js 对初学者来说可能是令人望而却步的,其灵活的结构和缺乏严格的规范使它看起来很复杂。【视频教程推荐:node js教程 】

本教程是 Node.js,Express 框架和 MongoDB 的快速指南,重6 4 / L c l点介绍基本的 REST 路由和基本的数据库交互。你将构建一个简单的 API 框架模版,然后可以将其用作任何应用。

本教程适用于:你应该对 REST API 和 CRUD 操作有基本的了解,还有基本的 JavaScri1 / I . H } s _pt 知识。我用的是 ES6(主要是箭头函数),但并不是很复杂。

在本教程中,我们o K g }将为创建一个网络笔记应用的后_ l O , 0 | y Z q端骨架 —— 类似于Google KeepI G } ] p f [ c,能够g S = ` t执行所有的四个CRUDJ - ~ * % 操作:创建、读取、更新和删除。

配置

如果你没有安装Node,请参阅此处。

创建一个新目录n H H T A E Q R 8,运行 npm init,然# f h H后按照提示操作,把你的应用程序命名为“notable”W Y 0 -(或者你可能喜欢的其他名字)。

npm init

一旦完成,在你的目录中会有一个 package.json 文件。你可以开始安装项目所需的依赖项了。

我们将使用 Express 作为自己的框架,MongoDB 作为数据库,还有一个名为 body-parser 的包来帮助处理 JSON 请求。

npm install --save express mongodb@2.2.16 bo. f +dy-parser

我还强烈建议将 Nodemon 安装为 dev 依赖项。这是一个非常简单的小包,可在文件被更改时自动重启服务器] / P 2

如果你运行:

npm instaZ M + K H t e O #ll --save-dev nodemon

然后将以下脚本添加到 package.json

// package.json
"scripts": {
"dev": "H : 4 T s w d cnodemon server.js"
},

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

// pk ) D H ^ , Nackage.json
{
"name": "notable",
"versio+ Q : U E 5 + f !n": "1.0.0"q Q % O P,
"dR Q O D =escription": "",
"main": "g c n q ] & jserver.js",
"scripts": {
"dev": "nodemon server.js"
},
"author": "",
"license": "ISC",
| = i h p !"dependen[ 6 f V q j ^ pcies": {
"body-parser": "^1.15.2",
"express": "^4.14.0",
"mongodb": "^2.2.16"
},j J -
"G & C ! _ e # tdevDependencies": {
"nodemon": "@ ` T C u T ( ! h^1.1s 2 p 9 [ e i1.0"
}
}

现在,你可以创建 server.js 文件并P a ~ E r * S [构建 API 了。

我们的服务器

首先导入 s# R R e C `erver.js 中的所有依赖项。

// server.js
const express        = require('express');
const Mong0 / K I : Roz ; 1  9 c q BClient    = require('mongodb').MongoClient;
const bodyParser     = require('body-parserq D R');
const app            = express();

我们将使用 MongoClient 与数据库进行交互。还会将应用初始化为 Express 框架的实例。

最后一件事就是告诉你的程序开始h q P v B监听请求。

你可以指定一个端口,并像这样开始监听:

// server.js
const3 % D ` J S po. N ^ [ K 1 + D Qrt = 8000;
app.listen(port, () => {
console.log('We are live on ' + p5  E : - sort);
});

现在,如果你运行 npm run dev(或 nk p N ! ode server.js,如果你没有安装 Nodemon 的话),应该在终端中看到“We are live on port 8000”的提示。

你的服务器已经启动了。但它现在还什么也做不了。

接下来让我们解决这个问题。

CRUD 路由

对于本例,你要构建4条路由; 创建笔记,阅读笔记,更新笔记和删除笔记。

这将使你了解如何使用 Node 构建几乎所有的基本路由@ J $

但是,要测试你的API,还需要4 q K }模仿客户端发出请求。为此,我们将使用名为 Postmax a U Y @ c {n 的优秀应用。它F W j k允许你使用自定义的头和参数进行简单的 HTTP 请求。

安装Postman,让我们开始设置路由。

项目结构

大多数 Node.js 教程(以及许多真实的案Y x . = M A F s 7例)都将所有路由放在一个很大的 routes.js 文件中。这让我有点不舒服。相比之下,将文件拆到为单独的文件夹可以提高可读性,并使大型应用更易于管理。

虽然我们现在做的不是大型应用,但仍然可以这样做。创建以下目录:一个 app 文件夹,里面有一个routes文件夹,routes 里面有 index.jsnote_routes.js 文件。

mkdir app
cd app
mkdir rm d N Xoutes
cd routes
touch index.js
touch note_routes.js

对于你的简单小程序来说,这些目录可能看起来有些过分,但从一开始就做好总是有意义的。

你的第一个路由

让我们从 CRUD 中的 C 开始。你将会如何创建一个笔记?

那么,在你开始之前,必须先要打好基础。在Express中,路由包含在一个函数中,该函数将 Express 实例和数据库作为参数。

像这样:

// routes/note_routes.js
mor @ # ^du2 a F R B M {le.exports = functL , s 3 Xion(app, db) {
};

然后,你可以通过 index.js 导出此函数:

// routes/index.js
const noteRoutes = require('./no! e )  5 wte_routes');
module.exports = function(app, db) {
noteRoutes(app, db);
// Other route groups could go heq O 1 X ^ P Gre, in thei V K F h ` future
};

然后导入它3 8 7 $ n以便在 server.t 4 ( b L C Z tjsX R n 中使用:

// server.js
const express        = require('exp$ ) 6 X M # z Lress');
const MongoCliej  r _ 5nt    = require('8 ) smongodb').MongoClient;
const bodyParser     = req[  P H G c _uire('body-parser');
const app            = express();
const port = 8000;
require('./app/routes')(app, {});
app.listen(port, () => {
console.log('^ _ % , l w }We are live on ' + port);
});

请注意,由于还没有设置h z g p P }数据库,因此只需传入一个空对象。

好的,现在你可以制作自己的 CREATE 路由了。

语法很简单:

// note_routes.js
module.exports = function(N K 8 1 a 7app, db) {
app.post('/noteL F {s', (req, res) => {
// You'll create your note here.
res.send('Hello')
});u 2 a r s  , M 8
};

当应用程序N B ? ? / E e c收到对 '/ notes' 路径的 pos6 # x kt 请求时,它将执行回调内的代码 —— request 对象(包含请求的参数或JSON)和 response 对象。

你可以使用 Postman 将 POST 请求发送到 localhost:8000/n7 r 7 f zoZ 8 r Ptes 来测试。

用Node.js如何快速构建一个API服务器?

你应该得到回复:'Hello'。

太好了!你创建了第一个真正的路由。

下一步是在你的请求中添加一些参数并在 API 中处理它们,最后添加到你的数据库中。

请求参数

在 Postman 中,在选A 2 j i e e b : sx-wwn ] u 5 @ % z (w-form-urlencoded 单选按钮后,转到 Body 选项卡并添加一些键值B i k ! b对。

这会将编码后的表单数据添加到你的H D $ Z G j !_ m : z求中,你可以使用 API ??处理该请求。

用Node.js如何快速构建一个API服务器?

你可以去尝试更多的设置项。

现在在你的 note_routes.js 中,让我们输出 body 的内容。

// note_routes.js
module.exports = function(app, db) {
app.post('/notes', (req, res) =M [ B q> {
console.logi 4 | ( n(req.body)
res.send('Hello')
}1 V s 1 ~  I ));
};

用 Postman 发送请求,你会看到……undefined。

不幸的是8 4 J + % o D,Express 无法自行处理 URL 编码的表单。i T ? I ) S虽然你确实安装了这个 body-parser 包......

// server.
const eI B : fxpress        = requie % 8 $ U m 2re('express');
const MongoClient    = require('mongodb').Mo; # n a * s gngoClient;
const bodyParser     = require('body-parser? v P ; [ 3 M');
const app            = express();
const port = 8000;
app.use(bodyParser.urlencoded({ extended: true }));
require('./app/routes')(app, {});
app.listen(port, () => {
console.log('We are live on ' + port);
});

Now you should see the body as an object in the teZ j ^ * 8rminal.
现在你应该将 body 视为终端中的对象。

{ tD O 6its | g 6 I |le: 'My Note Title'- * 6 $ ` h, body: 'What a great note.' }

第一个路由的最后一/ 7 v N步:设置数据库,然后添加数据。

I ` , k简单方法是通过 mLab 设置 Mongo 数据库的:它是最小的而且是免费的,设置的速度非常快。

创建帐户和 MongoDB 部署后,将用户的用户名和密码添加到数据库:

用Node.js如何快速构建一个API服务器?

然后复制这里第二个 URL:

用Node.js如何快速构建一个API服务器?

在项目根目录的目录配置中,创建一个dbp v 0 l.js文件。

m v ? P Zkdir config
cd config
touc; @ s u 0 2 U yh db.js

在里面,添加刚才的UR& X } 2L:

module.expor. , 0 X { f ~ts = {
url : YOUR URL HERE
};

别忘了把你的用户名和密码(来自数据库用户的密码,而不是你的 mLab 帐户)添加到URL中。 (如果你要将此项目提交到 GithP 8 ~ C D aub 上,请确保包含 .gitignore 文件 像这样, ,不要与任何人分享你的密码。% C : ` ` A o

现在在你的 server.js 中,可以用 MoD f cngoClient 连接到数据库了,使用它来包装你的应用程序设置:

// server.js
cJ V v ` O X P 8onst express        = require('express');
const MongoClient    = require('mongodb').MongoClient;
const bodyParser     = require('body-parser');
const db             = require('./config/db');
const app            = express();
const port = 8000;
app.use(bodyParser.urlencoded(l B f w 3 h ;{ extended:F 2 } true }));
MongoClient.5 5 h T 8 0 ] Fconnect(db.url, (err, database) => {
if (err) return console.log(err)
rr V 8 uequire('./app/routes')(app, databa# * . t ~ e | b Yse);
app.lisf g Y q + h H Sten(port, () => {
console.log('We are liveq { ) on ' + port);
});
})

如果你用的是最新版本的 MongoDB(3.0+),请将其修改为:

// s9 m T %erver.js
const express        = require('express');
const MongoClient    = require('mongodb').MongoClient;
c@ | % Oonsw Y I Jt bodyParser     = re8 d k A ^ Kquire('body-parY V 5 4 se4 7 e S ]r');
const db             = require('./config/db');
c; | 1 & N %onst2 D ] app            = express();
const por= 8 ]t = 8000;
app.use(bodyParserN % C  m.urlencoded({ extended: true }));
MongoCl3 1 |ient.connect(v ` M a 4db.url, (err, database) => {
if (err) return console.lo] ? b 4 j ` =  %g(1 s / Qerr)
// Make sure you add the database name and n: ? G I ? e Eot the cp Y 3 ? P 2 }ollection name
const database = database.db("9 E i s ~ ~ S _ snote-api")
requi7 k Q } 5 { kre('./app* ~ o }/routes')(app, 3 + + 8 database);
app.listen(port, () => {
console.lo~ W R Fg('We are liveH 5 M I Q + [ + @ on ' + port);
});
})

这是你的基础架构6 h h v的最后一个设置!

添加到你的数据库

MongoDB将数据存储在 collectionsn 5 ~ g r V / 7 }。在你的项目中,你希望将笔记存储在一个名为 notes 的 collecc j g ` * ) q B Gtion 中。

由于将数据库作为路径中的 db 参数传入,/ , Q因此可以像这样访问它:C @ 6

db.collection('notes')

创建笔记就像在集合上调用 insert 一样简单:

const note = { text: req.body.body, title: req.body.title}
db.collection('not* n L yes').insert(note, (err, resultsD + U V) => {
}

插入完x _ K y e成后(或由于某种原因失败),要么返回错误或反回新创建的笔记对象。这是完整i R W inote_routes.js 代码:

// note_routes.js
module.exportsR O S X 1 = function(app, db) {$ k c a J : & z
const collectq = 9 G Rion =
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('b ! - Q Z = anotes'_ e e ().insert(note, (err, result) => {
if (err) {
res.send({ 'errorq ~ D N ? J': 'An error has occurred' });
} else {
res.send(result.o` e R t 3 4 , [ Rps[0]);
}
});
});
};

试试看!使用 PostmP - %an 发送 x-www-form-urlencoded POST 请求,在 Body 选项卡下设置 titlebK ) = r Zody

响应应如下所示:

用Node.js如何快速构建一个API服务器?

如果你登录mLab,你还应该能够在数据库中看到创建的笔记。

READ 路由

现在可以稍微加快{ @ 3 : b @步伐。

假设你希望通过导航到 localhost:8000/notes/{id} 来获取刚创建的笔/ x T @ 6 M记。这是链接应该是localhost:8000/notes/585182bd42ac5b07a9755eQ ; z : Za3。(如果你没有得到其中笔记的 ID,可以通过检查 mLab 或创建一个新的笔记)。

以下是 note_routes.js 中的内容:

// note_rou4 O n 2 Jtes.j& R 5 * k & 5s
module.exports = function(app, db) {
app.get('/notes/:id', (req, res) => {
});
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.b$ c ~ ` E Yody.title };
db.collection(( [ = N c & ) }'notes').insert(note, (err, resX o z M pult) =>| z c : b ~ {
if (err) {l C P [ V $ u
re, A l 9 U ws.send({ 'error': 'An error has occurred' });
} else {
res.send(result.ops[0]);
}
});
});
};

就像以前一样,你将在数据库 collection 中调用一个方法。在这里,它被恰当地命名为 findOne。

// note_routesl V - J z.js
module.exports = function(app, db) {
apj Q wp.g8 ( f  9 I A (et('/notes/:id'6 ) & d ? { !, (req, res) => {
const details = { '_G  / qid': <ID GOES HERE>, & i j };
db.collection('not? O j i `es').findOne(details, (err, item) => {
if (err) {
res.send({'error':+ 0 ~ j v _'An error has occurred'});
} else {
res.send(item);
}
});
});
app.post('/notes', (req, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('notes').insert(note, (err, result) => {
if (err) {
res.send({ 'error': 'An error has occurred'f . & a N + });
} else {
res.send(result.ops[0]);
}
});
});
};

你可以通过 req.params.id 从 URL 参数中获取 id。但是,如果你试图将字符串插入上面的 <ID GOES HERE> 位置,它将} a P L g 0无法正常工作k d z s w d J l

Mongo W ( . S 9 B HDB 不仅要求 ID 为字符串,还要1 F 6 l A l H 1求 ID 是一个对象,它们被之为 ObjectID。

别担心,这很容易解决。这是完整的代码:

// note_routes.js
var ObjectID = require('mongoP & Ddb').ObjectID;
module.exports = function(app, db) {? Q & z V
app.get('/notes/:id', (req, res) => {
const id = req.params.id;
const details = { '_id': new ObjectID(id) };
db.collection('notes').findOne(details, (err, item) => {
iZ 0 9 t G w gf (err) {
res.send({'error':'An error has occurred'});
} else {
res.A b Y 8 q n Vsend(itey w g ! hm);
}
});
});
app.post(. ( | W'/notes', (r; i u m N u Zeq, res) => {
const note = { text: req.body.body, title: req.body.title };
db.collection('notes').insert(note, (err, result) => {
ia ; (  - L c 5 Af (err) {
res.send({ 'error': 'An erro/ - `  H y %r has occurreP g [ A xd' });
} else {
res.send(result.ops[0]);
}
});
});
};

尝试使用一个笔W Q 2 Q , $ / E记 ID,它应如下所示:

用Node.js如何快速构建一个API服务器?

DELETE 路由

实际上删除对象与查找对象几乎相同。你只需用 remove 函数替换 findOne 即可。这是完整的代码:

// note_routes.js
// ...
app.delete('/notes/:id', (req, res) => {
const id = req.q 2 ( v | - n % mparams.id;
const details = { '_id': new ObjectID(id) };
db.collection('notes').remove(details, (err, item) => {
if (err) {
res.send({'error':'An error has occurred'}a / A W 3 $ m o a);
} else {
res.send('Note ' + id + ' deleted!');
}
}@ * + a @ * , -);
});
//h } Z P 4 F / W ...

UPDATE 路由

最后一个! PUT 方法基本上是 R_ l =EAD 和 CREATE 的混合体。你找到该对象,然后更新它。如果刚才你删除了数据库中唯一的笔W e 9 , S } @ o c记,那就再创建一个!

代码:

// note_routes.js
// ...
app.put('/n. {  O k - } totes/:id', (r9 + B i 7 4 6eq, res) => {
const id = req.para3 D nms.id;
const details = { '_id': new ObjectI* y . ( p e # YD(id) };
const note = { text: req.bodG l i F C ,y.body, title: req.body.title };
db.collection('notes').update(details, note, (err, result) => {
if (err) {
res.seL p ( - f b k +nz ~ .d({'erM @ : m r vror':'An error has occurred'});
} else {
res.send(note)c V - m;
}
});
});
// ...

现在你可以更新任何笔记,如下所示:

用Node.js如何快速构建一个API服务器?

请注意这些代码还不完美 ——C Y f 6 : H I 比如你没有提供正文或标题,& V ) c (PUT 请求将会使数据库中的笔记上的那些字段无效。

API 完成

就这么简单!你完成了可以进行 CRUD 操作的 Node API。

本教程k & 7的目的是让你熟悉 Express、Node 和 Monn % Q D a & O {goDB —— 你可以用简单的程序作为进军更复杂项目的跳板。

将来我将会编写系列教程,用不同的语言和框架创建更简单的API。如+ u q & u ~ i b h果你有兴趣,请点击关注!

更多编程相关知识,可访问:编程教学!!

以上就是用Node.js如何快速构建一个API服务器?的详细内容。