[关闭]
@qinyun 2018-12-14T18:08:26.000000Z 字数 5133 阅读 1268

如何在没有框架和外部库的情况下使用NodeJS?

未分类


作者|Aditya Sridhar
译者|谢丽

NodeJS最常与Express框架一起使用。此外,许多其他外部库也与NodeJS一起使用。这是为了使开发更容易、更快速。在开发任何实际的项目时,如果需要,最好是使用框架和库来加速开发。

虽说如此,在本文中,我将展示如何使用NodeJS构建简单的REST API,而不使用Express框架或任何其他外部库。本文将只使用NodeJS本身提供的那些功能。这是为了展示如何在没有框架和库的情况下使用NodeJS。这也会让你对NodeJS的工作机制有一个更好的理解。

前提

https://nodejs.org安装NodeJS。

代码

本文使用的代码在GitHub(https://github.com/aditya-sridhar/simple-rest-apis-nodejs-without-frameworks)上。

从代码开始

创建文件夹simple-rest-apis-nodejs-without-frameworks,作为我们的NodeJS项目的文件夹。进入该项目文件夹,使用npm init将项目变成一个Node项目,命令如下:

  1. cd simple-rest-apis-nodejs-without-frameworks
  2. npm init

package.json

运行npm init命令会在项目文件夹下创建一个package.json文件。该文件包含关于项目的信息,如项目名称、版本、描述等,还有包。此外,package.json还是你添加Node依赖项的地方。在本文中,我们不会有任何依赖关系,因为我们只使用由NodeJS本身提供的功能。

第一个API

在项目文件夹中创建server.js文件。这将是我们的应用程序的起点。把下列代码复制到server.js文件中:

  1. const hostname = '127.0.0.1';
  2. const port = 3000;
  3. const server = require('./controller.js');
  4. server.listen(port, hostname, () => {
  5. console.log(`Server running at http://${hostname}:${port}/`);
  6. });

实际上,这段代码依赖于一个名为controller.js的文件,我们很快就会添加。这段代码告诉我们,服务器需要在localhost中监听3000端口,服务器的创建是在controller.js中完成的。

controller.js

我们在这个文件中创建服务器并定义我们的REST端点,创建一个名为controller.js的文件。

首先,我们在controller.js中创建一个GET端点:

  1. const http = require('http');
  2. const url = require('url');
  3. module.exports = http.createServer((req, res) => {
  4. var service = require('./service.js');
  5. const reqUrl = url.parse(req.url, true);
  6. // GET Endpoint
  7. if (reqUrl.pathname == '/sample' && req.method === 'GET') {
  8. console.log('Request Type:' +
  9. req.method + ' Endpoint: ' +
  10. reqUrl.pathname);
  11. service.sampleRequest(req, res);
  12. }
  13. });

首先导入http和url模块。这些模块是由NodeJS本身提供的。http模块使我们可以创建Web应用程序。它既支持客户端操作,也支持服务器端操作。

url模块帮助解析URL。代码http.createServer((req, res) => { 使用request as req和response as res创建一个HTTP服务器。module.exports用于把这个文件作为一个模块导出。这就是为什么我们可以在server.js中使用const server = require('./controller.js')导入controller.js,这可以看作是该文件需要service.js,我们稍后会讨论。

代码const reqUrl = url.parse(req.url, true); 获取请求URL并解析,以便我们可以在上面运行一些URL函数。

在这第一个端点中,我们将创建一个GET端点,其URL为/sample。为了进行URL路由,我们将使用if else条件。

代码if (reqUrl.pathname == '/sample' && req.method === 'GET') {会检查请求的URL是否是/sample,也会检查请求类型是否是GET。这个GET请求的逻辑在service.sampleRequest(req, res);中,这是一个在文件service.js中定义的函数。

service.js

这是具体实现API逻辑的地方。创建一个名为的service.js文件,把下面的代码复制到该文件中。

  1. const url = require('url');
  2. exports.sampleRequest = function (req, res) {
  3. const reqUrl = url.parse(req.url, true);
  4. var name = 'World';
  5. if (reqUrl.query.name) {
  6. name = reqUrl.query.name
  7. }
  8. var response = {
  9. "text": "Hello " + name
  10. };
  11. res.statusCode = 200;
  12. res.setHeader('Content-Type', 'application/json');
  13. res.end(JSON.stringify(response));
  14. };

这段代码会检查请求URL是否有一个名为name的参数,并保存在name变量中。如果没有提供这个参数,则默认为字符串World。应答状态设置为200,响应的Content Type是JSON,最后,使用res.end(JSON.stringify(response));返回响应。

由于response变量是一个JSON对象,在返回HTTP响应之前,我们使用JSON.stringify将其转换成字符串。现在,我们可以使用以下命令运行这个应用程序了:

  1. node server.js

测试

要使用postman测试这个端点,可以从这里(https://www.getpostman.com/)下载。在postman中选择GET请求,并输入以下URL:http://localhost:3000/sample?name=aditya,点击发送。

该请求的输出如下:

  1. {
  2. "text": "Hello aditya"
  3. }

现在,输入URL:http://localhost:3000/sample,并点击发送。该请求的输出如下:

  1. {
  2. "text": "Hello World"
  3. }

第二个API

在这一节中,我们将构建第二个API,这是一个POST请求。另外,如果用户点击了某个随机URL,我们需要指出,那是一个无效的路由。我们也会在这里加上该逻辑。

controller.js

把controller.js的代码更新成下面这个样子:

  1. const http = require('http');
  2. const url = require('url');
  3. module.exports = http.createServer((req, res) => {
  4. var service = require('./service.js');
  5. const reqUrl = url.parse(req.url, true);
  6. // GET Endpoint
  7. if (reqUrl.pathname == '/sample' && req.method === 'GET') {
  8. console.log('Request Type:' +
  9. req.method + ' Endpoint: ' +
  10. reqUrl.pathname);
  11. service.sampleRequest(req, res);
  12. // POST Endpoint
  13. } else if (reqUrl.pathname == '/test' && req.method === 'POST') {
  14. console.log('Request Type:' +
  15. req.method + ' Endpoint: ' +
  16. reqUrl.pathname);
  17. service.testRequest(req, res);
  18. } else {
  19. console.log('Request Type:' +
  20. req.method + ' Invalid Endpoint: ' +
  21. reqUrl.pathname);
  22. service.invalidRequest(req, res);
  23. }
  24. });

POST端点的URL为/test。这段代码有一个条件用于检查/test端点。/test端点的逻辑在service.testRequest(req, res);中,该函数是在service.js中定义的。这段代码还有一个针对无效路由的else条件。这段针对无效路由的逻辑在函数`service.invalidRequest(req, res);·中进行处理。

service.js

把下面的代码添加到service.js中。不要删除service.js中已有的代码。把下面的代码加到已有的代码中。

  1. exports.testRequest = function (req, res) {
  2. body = '';
  3. req.on('data', function (chunk) {
  4. body += chunk;
  5. });
  6. req.on('end', function () {
  7. postBody = JSON.parse(body);
  8. var response = {
  9. "text": "Post Request Value is " + postBody.value
  10. };
  11. res.statusCode = 200;
  12. res.setHeader('Content-Type', 'application/json');
  13. res.end(JSON.stringify(response));
  14. });
  15. };

对于POST请求,在调用该端点时需要提供一个输入POST body。在代码中,我们需要从请求获取这个POST body,代码如下所示:

  1. req.on('data', function (chunk) {
  2. body += chunk;
  3. });

请求是以流的方式过来的。这段代码会把接收到的流数据不断地追加到body上。req.on('end', function () { 只有在流接收完成后才会执行,这样就接收到了整个的POST body

代码postBody = JSON.parse(body);会将输入的POST body转换成JSON格式,这样,我们就可以使用其中的值了。在代码中,我们使用了postBody中的value字段。响应的设置和GET请求类似。

无效请求逻辑

把下面这段代码添加到service.js。不要删除service.js中已有的代码。把下面这段代码添加已有的代码下面。

  1. exports.invalidRequest = function (req, res) {
  2. res.statusCode = 404;
  3. res.setHeader('Content-Type', 'text/plain');
  4. res.end('Invalid Request');
  5. };

对于无效请求,响应状态置为404,Content Type置为text。返回的具体内容是Invalid Request。

测试

进到postman。选择请求类型POST,输入下面的URL:http://localhost:3000/test

还是选择Bodyrawapplication/json如图所示。提供下面的输入Post body

  1. {
  2. "value" : "nodejs"
  3. }

在postman中点击发送,API输出如下:

  1. {
  2. "text": "Post Request Value is nodejs"
  3. }

你还可以试下无效请求。在postman中选择GET,并输入URL:http://localhost:3000/test123

该请求的响应应该是Invalid Text。

小结

现在,你已经了解了如何在不使用任何框架或外部库的情况使用NodeJS创建REST API。但在实际的项目中,只要可能,就应该总是使用框架或库,以简化开发,提升开发速度。

英文原文:How to use NodeJS without frameworks and external libraries

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注