发布于 2026-01-06 0 阅读
0

如何在 Ubuntu 18.04 上使用 Node.js 和 Express 创建 CRUD API

如何在 Ubuntu 18.04 上使用 Node.js 和 Express 创建 CRUD API

CodeTips致力于帮助零基础或经验很少的初学者学习编程。

我们确实会将文章交叉发布到其他网站以覆盖更广泛的受众,但为什么不订阅我们的新闻通讯,直接在您的邮箱中获取最新文章呢?

本文内容最初来源于CodeTips。原始内容会保持更新,但其他来源的内容可能不是最新版本。


介绍

如何在 Ubuntu 18.04 上使用 Node.js 和 Express 创建 CRUD API

API(应用程序编程接口)是一种通过一系列预定义的请求与服务进行交互的方式。

Express 是一个基于 Node.js 的开源 Web 框架,旨在简化网站、Web 应用程序和 API 的开发。

在本教程中,您将在一台 Ubuntu 18.04 服务器上创建一个简单的 CRUD API。该 API 将通过公共 IP 地址访问,因此您可以从任何有互联网连接的地方访问它。

立即使用此推荐链接注册 Digital Ocean ,即可获得 100 美元信用额度!

先决条件

步骤 1 — 创建一个简单的 Express 应用,提供“Hello World”程序。

在这一步中,我们将创建一个非常简单的 API,只有一个端点,然后在后续步骤中以此为基础进行构建。

首先,在您选择的位置创建一个新目录,并package.json通过在终端中运行以下命令来创建一个默认文件:

npm init -y

Enter fullscreen mode Exit fullscreen mode

在同一终端中,安装express依赖项:

npm i express

Enter fullscreen mode Exit fullscreen mode

接下来,在您选择的代码编辑器中打开项目并创建一个新server.js文件。

在新文件中,添加以下代码:

const express = require('express')
const app = express()
const port = 3000

app.get('/hello', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`App listening on port ${port}!`))

Enter fullscreen mode Exit fullscreen mode

使用该express应用程序,我们定义一个/hello端点,该端点将返回文本Hello World!,并在端口上运行我们的应用程序3000

请注意,该/hello端点仅匹配 GET 请求,因为我们已使用该app.get方法对其进行了定义。

在终端中运行以下命令来启动应用程序:

node index.js

Enter fullscreen mode Exit fullscreen mode

你应该会看到以下输出结果:

$ node index.js
App listening on port 3000!

Enter fullscreen mode Exit fullscreen mode

现在打开你常用的浏览器,并访问localhost:3000/hello。如果一切顺利,Hello World!浏览器中应该会显示 。

恭喜!您已创建了一个 API,现在可以通过端点与之通信/hello。接下来,我们将在此基础上进行扩展,使我们的 API 更加完善!

步骤 2 — 扩展应用程序以从内存状态获取属性。

目前我们只有一个端点,/hello它会返回文本Hello World!。虽然我们创建了一个 API,这很棒,但就功能而言,它并不十分有用。

在这一步中,我们将使用 API 并使其返回一些有用的数据。我们将以员工详细信息为例。

首先,让我们在应用程序中添加另一个端点,用于检索记录。

const express = require('express')
const app = express()
const port = 3000

app.get('/hello', (req, res) => res.send('Hello World!'))

app.get('/employee/:id', (req, res) => {
  console.log(req.params.id)
  res.sendStatus(200)
})

app.listen(port, () => console.log(`App listening on port ${port}!`))

Enter fullscreen mode Exit fullscreen mode

我们定义了一个新的/employee端点,就像我们之前对/hello端点所做的那样,但我们也使用了查询参数。

查询参数使用冒号定义,前面的文本用于引用该参数。在我们的/employee端点中,我们定义了一个名为 `<parameter_name>` 的查询参数id,以下console.log语句展示了我们如何引用该参数的值。

停止并启动应用程序,以便新的代码更改生效,打开浏览器并导航到http://localhost:3000/employee/wiggly

结果,您应该在终端中看到以下输出:

$ node index.js
App listening on port 3000!
wiggly

Enter fullscreen mode Exit fullscreen mode

注意wiggly终端输出的内容,也就是我们在 URL 中使用的内容(/employee/wiggly)。wiggly你可以将其更改为任何你想要的内容,并查看终端输出。

这项技术的强大之处在于,我们只需定义一条路由,即可用于多种不同的场景。例如,我们可以创建一个端点,使用唯一标识符检索员工的详细信息,而这正是我们现在要做的事情!

让我们创建一个对象,作为应用程序的内存状态,并添加一些虚拟员工:

/**  
We'll use the Object key as the unique identifier, made up of the
first letter of the employees first name and whole of their last name.
*/
const employees = {
  'sbrown': {
    firstName: 'Steve',
    lastName: 'Brown',
    department: 'Engineering'      
  },
  'jsmith': {
    firstName: 'Janine',
    lastName: 'Smith',
    department: 'Marketing'      
  },
  'kjones': {
    firstName: 'Karen',
    lastName: 'Jones',
    department: 'Sales'      
  },
  'bwilliams': {
    firstName: 'Ben',
    lastName: 'Williams',
    department: 'Administration'
  }
}

Enter fullscreen mode Exit fullscreen mode

现在,我们不再记录id参数值,而是从对象中返回员工详细信息:

app.get('/employee/:id', (req, res) => {
  res.json(employees[req.params.id])
})

Enter fullscreen mode Exit fullscreen mode

由于我们将返回一个 JSON 对象,因此我们使用该res.json方法,该方法除其他事项外,还会设置所有正确的标头并以 JSON 格式返回响应。

http://localhost:3000/employee/kjones重启应用程序,然后在浏览器中访问。

您应该在浏览器中看到以下响应:

{"firstName":"Karen","lastName":"Jones","department":"Sales"}

Enter fullscreen mode Exit fullscreen mode

尝试将对象kjones中的任何其他唯一标识符更改为其他标识符,employees并查看返回值的变化。

现在,尝试在浏览器中将值更改id为不存在的值(例如http://localhost:3000/employee/wiggly)。不会返回任何内容,这是正确的,但我们没有向用户提供任何原因的提示;是出了什么问题,还是该员工根本不存在?

让我们更新端点,检查给定的员工是否id存在,如果不存在,则返回一个404 Not Found响应;否则,返回员工详细信息。

app.get('/employee/:id', (req, res) => {
  const employee = employees[req.params.id]

  if (!employee) {
    return res.sendStatus(404)
  }

  res.json(employee)
})

Enter fullscreen mode Exit fullscreen mode

重启应用程序,然后在浏览器中尝试相同的 URL。现在应该会得到更详细的响应Not Found,这对用户来说信息更丰富。

在这一步中,我们把一个非常简单且不太实用的 API 改造成了一个可以使用查询参数查询数据的 API。我们还学习了如何处理查询不存在的员工信息的情况。

步骤 2 — 扩展应用程序,以从内存状态中添加/删除属性。

我们现在有一个可以根据员工 ID 检索员工的 API,但是如果员工加入/离开公司怎么办?我们需要一种方法来将他们添加到员工列表中/从员工列表中删除,这就是我们将在这一步中实现的目标。

我们先来关注新员工入职的情况。当有人入职时,我们希望将他们添加到我们的employees对象中,以便以后可以查询他们。

为此,我们将使用POST请求,其声明方式与上面的请求相同GET

app.post('/employee', (req, res) => {
  res.sendStatus(200)
})

Enter fullscreen mode Exit fullscreen mode

请重启应用程序以应用我们的代码更改。

我们的新路由除了返回状态之外什么也不做,200 OK因为在编写逻辑之前,我想先谈谈我们如何发出POST请求。

当你在浏览器中输入地址时,就像我们在前面的步骤中所做的那样(例如http://localhost:3000/hello),我们就是在通过发出请求来请求资源GET

我们不能使用相同的机制来发出任何其他类型的请求(POST例如PUTDELETE等等),那么我们如何访问这些端点呢?有很多不同的方法,但我们只关注其中一种——CURL。

POST使用 CURL 向我们的新端点发出请求,请在终端中运行以下命令:

curl -X POST 'http://localhost:3000/employee'

Enter fullscreen mode Exit fullscreen mode

我们在新端点中添加的唯一功能是返回200 OK状态,也就是您应该在终端中看到的响应。

$ curl -X POST 'http://localhost:3000/employee'
OK

Enter fullscreen mode Exit fullscreen mode

让我们构建这个逻辑,将一名员工添加到我们的employees对象中。

我们首先需要做的是获取新员工的详细信息。如果我们查看现有员工的信息,我们需要三项信息—— firstNamelastNamedepartment

上一节中,我们使用req.params属性提取了idURL 参数。处理请求时POST,我们还可以使用请求体。

使用 CURL,我们可以结合 Header ( -H) 标志来指定内容类型,该标志会告知服务器请求内容的格式,以及 Data ( --data) 标志来传递 JSON 对象。

我们将发送一个 JSON 对象,因此我们将设置一个Content-Type标头或application/json,告诉服务器我们正在发送 JSON,并将我们的新员工指定为数据:

CURL -X POST 'http://localhost:3000/employee' -H 'content-type: application/json' --data '{"firstName": "John", "lastName": "Doe", "department": "engineering"}'

Enter fullscreen mode Exit fullscreen mode

我们现在向 发出POST请求,http://localhost:3000/employee并将上述 JSON 对象作为请求正文。

默认情况下,我们的 Express 应用程序不会解析此 JSON 对象,因此我们需要启用一些中间件来启用它。

const express = require('express')
const app = express()
const port = 3000

/**
-- Employee object
*/

/** 
Middleware that looks at requests with an application/json 
Content-Type header and stores the request body, as JSON,
in req.body
*/
app.use(express.json())

/**
-- Other endpoints
*/

app.post('/employee', (req, res) => {
  console.log(req.body)
  res.sendStatus(200)
})

Enter fullscreen mode Exit fullscreen mode

在定义任何路由之前,请先告知您的系统app使用express.json中间件。然后,在新端点中记录请求正文。

重启应用程序,然后使用 CURL 发送请求,请求体为 JSON 格式。运行应用程序的终端应该会输出以下信息:

$ node index.js
App listening on port 3000!
{ firstName: 'John', lastName: 'Doe', department: 'engineering' }

Enter fullscreen mode Exit fullscreen mode

现在我们可以从新的POST端点接收一个新的员工对象,所以让我们构建逻辑以确保我们获得所有三个必需字段(firstNamelastName和),根据department构造,然后将其添加到我们的对象中(如果该对象尚未被使用)。idfirstNamelastNameemployeeid

app.post('/employee', (req, res) => {
  const { firstName, lastName, department } = req.body

  if (!firstName || !lastName || !department) {
    // 400 = bad request. It indicates to the user that
    // there was something wrong with their request.
    return res.status(400).send('One or more required fields are missing')
  }

  const id = (firstName[0] + lastName).toLowerCase()

  if (employees[id]) {
    // Provide a custom message so the user knows what the
    // problem with the request is.
    return res.status(400).send('A user with that id already exists')
  }

  // We set the employee properties explicitly, just in case
  // the user sends other fields through that we're not interested
  // in storing.
  employees[id] = { firstName, lastName, department }

  res.sendStatus(200)
})

Enter fullscreen mode Exit fullscreen mode

重启应用程序并尝试以下场景:

  • 提交POST请求时,请省略一个或多个必填字段。
  • 发出一个POST带有 a 的请求firstNamelastName该请求会创建一个id已经存在的 a(例如,Sarah Brown这将与 a 冲突Steve Brown)。
  • 先发出一个POST请求并获得成功,然后再发出一个GET请求来检索新员工的详细信息。

现在,让我们运用目前所学的知识创建一个新的DELETE端点,该端点接收一个员工id并将其从我们的对象中移除employees

app.delete('/employee/:id', (req, res) => {
  const employee = employees[req.params.id]

  if (!employee) {
    return res.sendStatus(404)
  }

  delete employees[req.params.id];

  res.sendStatus(200)
})

Enter fullscreen mode Exit fullscreen mode

你会注意到这与我们的员工端点非常相似GET;我们使用 URL 参数,检查员工是否存在,200如果一切顺利则返回状态。唯一的区别是我们通过员工employeesid.

使用CURL 发出请求与我们上面看到的请求DELETE非常相似:POST

curl -X DELETE 'http://localhost:3000/employee/sbrown'

Enter fullscreen mode Exit fullscreen mode

重启应用程序并尝试以下操作:

  • DELETE使用现有员工id(例如)向我们的新端点发出请求http://localhost:3000/employees/sbrown
  • GET使用同一员工id(例如)向我们的员工端点发出请求,http://localhost:3000/employees/sbrown并查看您现在是否收到404 Not Found响应。

恭喜——您已创建了一个 CRUD API!

POST在这一步中,我们真正将 API 提升到了一个新的水平,允许用户添加和删除员工,并且我们通过启用中间件学习了如何处理数据express.json

步骤 3 — 将 API 部署到 Digital Ocean

我们现在有了一个可以创建、删除和检索员工信息的API。目前为止我们取得的成果非常棒,但它只存在于我们的笔记本电脑上。为了将我们的应用程序提升到一个新的水平,我们需要将其托管在一个可以公开访问的服务器上,以便我们可以从世界任何地方访问它。

根据我们的前提条件,您需要一台 Digital Ocean 服务器。首先,请在您的服务器上创建一个新目录。

$ mkdir ~/simple-crud

Enter fullscreen mode Exit fullscreen mode

接下来,在本地项目目录下的终端中,运行以下命令,将必要的文件复制到服务器:

$ scp package-lock.json package.json server.js ubuntu@YOUR_IP:./simple-crud/

Enter fullscreen mode Exit fullscreen mode

将 `<user>`替换ubuntu为您创建的用户,并将YOUR_IP` 替换为您的服务器公网 IP 地址。

我们现在已经将我们的文件复制package-lock.jsonpackage.json服务器上的server.js新文件夹中。simple-crud

simple-crud接下来,在服务器上的文件夹中,安装应用程序的依赖项:

`
$ npm i

`

最后,使用 PM2 启动应用程序:

`
$ pm2 start server.js --name "simple-crud"

`

为确保应用程序已正确启动,您可以运行该pm2 logs程序并确保看到以下日志行:

`
$ pm2 logs
0|simple-c | App listening on port 3000!

`

接下来,我们将修改默认的 NGINXserver代码块,将所有请求转发到我们的应用程序。

用于vi编辑默认配置:

`
$ sudo vi /etc/nginx/sites-available/default

`

然后,将根位置(location /)替换为以下代码,该代码会将所有 HTTP 请求转发到我们的应用程序。

`
location / {
proxy_pass http://localhost:3000 ;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $
}

`

在这一步中,我们将应用程序从只能在笔记本电脑上运行,升级到在 Digital Ocean 服务器上运行,这意味着我们的应用程序可以从世界任何地方访问!

步骤 4 — 使用我们托管在 Digital Ocean 上的新 API,而不是本地主机。

我们现在有一个运行在 Digital Ocean 服务器上的应用程序,可以从世界任何地方访问。我们知道如何在本地访问我们的 API,但现在我们该如何与它交互呢?

我们只需localhost在 CURL 命令中将地址替换为我们的公网 IP 地址即可:

`
$ curl -X GET ' http://157.245.243.1/employee/sbrown '
{"firstName":"Steve","lastName":"Brown","department":"Engineering"}

$ curl -X POST ' http://157.245.243.1/employee ' -H 'content-type: application/json' --data '{"firstName": "John", "lastName": "Doe", "department": "engineering"}'
OK

curl -X DELETE ' http://157.245.243.1/employee/jsmith '
OK

`

结论

您已成功创建了一个具有内存状态的 CRUD API,并将其部署到 Digital Ocean 服务器,这意味着您可以使用公共 IP 地址从任何地方与其交互。


CodeTips致力于帮助零基础或经验很少的初学者学习编程。

我们确实会将文章交叉发布到其他网站以覆盖更广泛的受众,但为什么不订阅我们的新闻通讯,直接在您的邮箱中获取最新文章呢?

本文内容最初来源于CodeTips。原始内容会保持更新,但其他来源的内容可能不是最新版本。

文章来源:https://dev.to/codetips/how-to-create-a-crud-api-using-node-js-and-express-on-ubuntu-18-04-24h8