Vanilla Node.js REST API示例

A Vanilla Node.js REST API without Frameworks such us Express | Engineering Education (EngEd) Program | Sectionicon-default.png?t=M0H8https://www.section.io/engineering-education/a-raw-nodejs-rest-api-without-frameworks-such-as-express/

Node.js 是一个非常流行的 JavaScript 框架。当用于构建后端服务和 API 时,它最闪耀。Node.js 开发人员经常利用开源框架和库(如Express.js)来开发应用程序。这些库在 NPM 注册表中很容易获得。

每当你使用这样的包时,都会有很多抽象;因此你没有利用 Node.js 的核心功能。您的应用程序的低级逻辑 Node.js 对您隐藏,因为这些包在幕后处理和执行原始 Node.js。

需要注意的一个关键点是这些包使Node.js 成为一种流行的技术。另一方面,您可以选择使用核心 Node.js 来开发您的应用程序。这样,您就可以使用Vanilla Node.js功能。这个博客将教你如何使用没有框架的 vanilla Node.js 来构建简单的 API。

目标

在本指南中,我们将使用 Node.js 本身的功能核心构建一个简单的 REST API。我们只是使用带有HTTP 模块的vanilla Node.js的基本结构来创建和管理服务器。

这意味着我们不会使用 NPM。因此没有与 NPM 相关的依赖项、 no package.json、 nopackage-lock.json和 nonode_module文件夹。

目标是向您展示 Node.js 如何以最纯粹的形式工作,以及如何在没有外部库或框架的情况下使用它。

注意:在处理任何实际项目时,最好使用 Node.js 库和包。这样,您将充分利用现成的代码,使您的开发工作流程更轻松、更快捷。

先决条件

设置一个简单的 HTTP 服务器

在创建 REST API 之前,让我们创建一个简单的HTTP API来提供Hi there语句。

创建一个项目文件夹和一个app.js文件。

  1. 首先要做的是使用方法从 Node.js中拉出HTTP 模块。require()这个模块是 Node.js 的原生模块。您不需要任何额外的包或库来访问它,只需在您的计算机上安装 Node.js 运行时。
const http = require("http");

这样,我们就可以使用必要的方法和功能来设置服务器。

  1. 一旦可用,定义您希望服务器运行的端口,如下所示。
const PORT = process.env.PORT || 5000;
  1. 要创建服务器,您需要createServer从 HTTP 模块调用该方法。即,http.createServer。传递响应和请求以提供您的信息。

然后使用:

  • req.url 设置请求访问路由/URL。
  • req.method.
  • res.writeHead 设置任何响应标头。
  • res.write() 发送响应的实际内容。
  • res.end() 结束响应。
const server = http.createServer(async (req, res) => {
    //set the request route
    if (req.url === "/api" && req.method === "GET") {
        //response headers
        res.writeHead(200, { "Content-Type": "application/json" });
        //set the response
        res.write("Hi there, This is a Vanilla Node.js API");
        //end the response
        res.end();
    }

    // If no route present
    else {
        res.writeHead(404, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ message: "Route not found" }));
    }
});
  1. 调用listen()方法并传入PORT变量。然后添加一条console.log()消息,指示服务器已启动并正在运行。
server.listen(PORT, () => {
    console.log(`server started on port: ${PORT}`);
});
  1. 服务器设置得很好。运行node app.js测试它。这将console.log()在您的命令屏幕上记录消息。

 

  1. 如果您http://localhost:5000/api在浏览器上打开,您将收到响应中定义的res.write()

 

设置 REST API

现在让我们看看如何使用原始 Node.js 设置 REST API。我们将使用 todos 样板来演示这一点。

下面是项目结构。

\---vanilla-nodejs-rest-api
|   app.js
|   controller.js
|   data.js
|   utils.js

No sub-folders exist

添加测试数据

data.js:保存一些临时测试数据。信息保存在 todos 数组中。每个 todo 都有一个唯一的 id、一个 todo 标题、一个简短的描述和一个标记完成的 todo 的布尔值。

//data.js
/** Todos List*/
const todos = [
    {
        id: 1,
        title: "Coding in Javascript",
        description: "Working with functions in JavaScript",
        completed: false,
    },
    {
        id: 2,
        title: "Cooking Supper",
        description: "Preparing rice and chicken",
        completed: false,
    },
    {
        id: 3,
        title: "Taking a walk",
        description: "Easy time at the park",
        completed: false,
    },
    {
        id: 4,
        title: "Watching Netflix",
        description: "Enjoying the new premiered series",
        completed: false,
    },
];
module.exports = todos;

设置控制器

controllers.js:管理此应用程序中使用的每个路由背后的实际功能和逻辑。它由Controller类组成,该类将具有以下主要 HTTP 方法:

  • getTodos():获取并列出临时data.js文件中列出的所有待办事项。
  • getTodo():通过其唯一 ID 获取和列出单个待办事项。
  • createTodo():创建一个新的临时待办事项。
  • updateTodo():更新现有待办事项的值。
  • deleteTodo():从列表中删除待办事项。
// controller.js
// Logic behind the functionalities
const data = require("./data");

class Controller {
    // getting all todos
    async getTodos() {
        // return all todos
        return new Promise((resolve, _) => resolve(data));
    }

    // getting a single todo
    async getTodo(id) {
        return new Promise((resolve, reject) => {
            // get the todo
            let todo = data.find((todo) => todo.id === parseInt(id));
            if (todo) {
                // return the todo
                resolve(todo);
            } else {
                // return an error
                reject(`Todo with id ${id} not found `);
            }
        });
    }

    // creating a todo
    async createTodo(todo) {
        return new Promise((resolve, _) => {
            // create a todo, with random id and data sent
            let newTodo = {
                id: Math.floor(4 + Math.random() * 10),
                ...todo,
            };

            // return the new created todo
            resolve(newTodo);
        });
    }

    // updating a todo
    async updateTodo(id) {
        return new Promise((resolve, reject) => {
            // get the todo.
            let todo = data.find((todo) => todo.id === parseInt(id));
            // if no todo, return an error
            if (!todo) {
                reject(`No todo with id ${id} found`);
            }
            //else, update it by setting completed to true
            todo["completed"] = true;
            // return the updated todo
            resolve(todo);
        });
    }

    // deleting a todo
    async deleteTodo(id) {
        return new Promise((resolve, reject) => {
            // get the todo
            let todo = data.find((todo) => todo.id === parseInt(id));
            // if no todo, return an error
            if (!todo) {
                reject(`No todo with id ${id} found`);
            }
            // else, return a success message
            resolve(`Todo deleted successfully`);
        });
    }
}
module.exports = Controller;

实用程序设置

utils.js:控制标准的 Web API 用例。它包括getReqData()从服务器上的客户端检索数据的功能。

//utils.js
function getReqData(req) {
    return new Promise((resolve, reject) => {
        try {
            let body = "";
            // listen to data sent by client
            req.on("data", (chunk) => {
                // append the string version to the body
                body += chunk.toString();
            });
            // listen till the end
            req.on("end", () => {
                // send back the data
                resolve(body);
            });
        } catch (error) {
            reject(error);
        }
    });
}
module.exports = { getReqData };

设置服务器和路由

app.js:这包含;

  • 服务器的初始化和配置。
  • 侦听服务器不同 HTTP 方法的适当路由。
  • 一个端口号,用于在浏览器上监听和设置服务器。
//app.js
const http = require("http");
const Todo = require("./controller");
const { getReqData } = require("./utils");

const PORT = process.env.PORT || 5000;

const server = http.createServer(async (req, res) => {
    // /api/todos : GET
    if (req.url === "/api/todos" && req.method === "GET") {
        // get the todos.
        const todos = await new Todo().getTodos();
        // set the status code, and content-type
        res.writeHead(200, { "Content-Type": "application/json" });
        // send the data
        res.end(JSON.stringify(todos));
    }

    // /api/todos/:id : GET
    else if (req.url.match(/\/api\/todos\/([0-9]+)/) && req.method === "GET") {
        try {
            // get id from url
            const id = req.url.split("/")[3];
            // get todo
            const todo = await new Todo().getTodo(id);
            // set the status code and content-type
            res.writeHead(200, { "Content-Type": "application/json" });
            // send the data
            res.end(JSON.stringify(todo));
        } catch (error) {
            // set the status code and content-type
            res.writeHead(404, { "Content-Type": "application/json" });
            // send the error
            res.end(JSON.stringify({ message: error }));
        }
    }

    // /api/todos/:id : DELETE
    else if (req.url.match(/\/api\/todos\/([0-9]+)/) && req.method === "DELETE") {
        try {
            // get the id from url
            const id = req.url.split("/")[3];
            // delete todo
            let message = await new Todo().deleteTodo(id);
            // set the status code and content-type
            res.writeHead(200, { "Content-Type": "application/json" });
            // send the message
            res.end(JSON.stringify({ message }));
        } catch (error) {
            // set the status code and content-type
            res.writeHead(404, { "Content-Type": "application/json" });
            // send the error
            res.end(JSON.stringify({ message: error }));
        }
    }

    // /api/todos/:id : UPDATE
    else if (req.url.match(/\/api\/todos\/([0-9]+)/) && req.method === "PATCH") {
        try {
            // get the id from the url
            const id = req.url.split("/")[3];
            // update todo
            let updated_todo = await new Todo().updateTodo(id);
            // set the status code and content-type
            res.writeHead(200, { "Content-Type": "application/json" });
            // send the message
            res.end(JSON.stringify(updated_todo));
        } catch (error) {
            // set the status code and content type
            res.writeHead(404, { "Content-Type": "application/json" });
            // send the error
            res.end(JSON.stringify({ message: error }));
        }
    }

    // /api/todos/ : POST
    else if (req.url === "/api/todos" && req.method === "POST") {
        // get the data sent along
        let todo_data = await getReqData(req);
        // create the todo
        let todo = await new Todo().createTodo(JSON.parse(todo_data));
        // set the status code and content-type
        res.writeHead(200, { "Content-Type": "application/json" });
        //send the todo
        res.end(JSON.stringify(todo));
    }

    // No route present
    else {
        res.writeHead(404, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ message: "Route not found" }));
    }
});

server.listen(PORT, () => {
    console.log(`server started on port: ${PORT}`);
});

测试应用程序

Vanilla Node.js REST API 现在已设置好并准备好进行测试以查看是否一切正常。现在您需要通过运行以下命令来启动服务器:

node app.js

这将在端口 5000 上设置和运行服务器。

使用 Postman 探索 API

让我们使用 Postman 测试 API 中设置的不同方法。如果您不熟悉 Postman API 测试,请阅读本教程以开始使用。

获取所有待办事项

/API/todos GET:这将获取data.js.

要测试这个 GET 请求:

  • 转到邮递员并发送请求GET。请求网址http://localhost:5000/api/todos如下图:

 

  • 这将在 Postman 响应部分记录一个响应,其中列出了所有待办事项data.js

 

通过 id 获取 todo

/API/todos/:id GET:这将只获取一个由 todo 的 id 值指定的 todo。

要测试这个 GET 请求:

  • 转到邮递员并发送请求GET。输入请求 URL 为http://localhost:5000/api/todos/:id,其中:id是您要获取的单个 todo 的 id,如下所示。

 

  • 该请求会将单个待办事项记录到 Postman 响应部分。

删除待办事项

/API/todos/:id DELETE:这将执行DELETE单个 todo 的请求。您只会收到一条响应消息,因为数据是临时的并且没有存储在数据库中。

进行测试:

  • 转到邮递员并发送请求DELETE。输入请求 URL 为http://localhost:5000/api/todos/:id,其中:id是你要删除的单个 todo 的 id,如下图。

  • 这将Todo deleted successfully在您的 Postman 响应控制台中记录一条消息。

更新待办事项

/API/todos/:id PATCH:这将更新待办事项以指示任务已完成,即truefalse。您将在邮递员响应控制台上看到效果。

要查看它的效果如何:

  • 转到邮递员并发送请求PATCH。输入请求 URL 为http://localhost:5000/api/todos/:id,其中:id是您要更新的单个 todo 的 id,如下图所示。

 

  • Postman 响应控制台应如下所示:

添加一个新的待办事项

/API/todos POST:这将创建一个新的待办事项。新的 todo 将作为响应返回,但不会记录在data.js.

要对其进行测试,请执行以下操作:

  • 转到 Postman 并打开一个新选项卡,选择一个POST请求并将请求 URL 输入为http://localhost:5000/api/todos.

 

转到Body选项卡部分,选择raw,然后从右侧的下拉选项中选择“JSON”。

 

  • 添加新待办事项的内容(标题、描述和已完成)。

这是一个简单的例子:

{
   "title": "Vannila Node.js REST API",
    "description": "Working with responses and requests",
    "completed": false
}
  • 填写完以上详细信息后,点击SEND按钮启动 POST 请求,新添加的 todo 将记录在 Postman 控制台中。

 

注意:由于 id 是随机生成的,因此每次发出新的 POST 请求时它可能会有所不同。

你有它:一个完全用 Vannila Node.js 编写的简单的 REST API。我希望您发现本教程具有指导性、信息性和帮助性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值