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

使用 Node.js、Express.js 和 PostgreSQL REST API(RESTful API)实现 CRUD 功能 CRUD 所需条件 设置 PostgreSQL 数据库 设置 Express.js 服务器 创建 CRUD 操作函数 创建 REST API 端点 结论

使用 Node.js、Express.js 和 PostgreSQL 构建 CRUD REST API

REST API(RESTful API)

增删改查

所需物品

设置 PostgreSQL 数据库

设置 Express.js 服务器

创建 CRUD 操作函数

创建 REST API 端点

结论

应用程序编程接口(API)是服务或软件之间进行通信的桥梁。在Web编程中,API用于访问可用的数据和服务。

REST API(RESTful API)

表述性状态转移(REST)包含 Web 服务的标准。REST API 是一种 API 架构风格,它使用 HTTP 协议来访问和使用数据。以下是 REST API 支持的一些数据类型:

  • GET— 获取数据
  • PUT— 修改数据或资源的状态或值
  • POST— 创建数据或资源
  • DELETE— 删除数据或资源

可用于创建 CRUD(创建、读取、更新、删除)服务/应用程序。

增删改查

创建服务时,我们需要一些基本功能来操作资源。这些功能包括创建、读取、更新和删除数据,通常称为 CRUD 操作。

CRUD 代表创建 (Create )、读取 (Read )、更新 (Update ) 和删除 (Delete),实际上是 REST API 中数据类型的一种应用。详情如下:

  • CREATE— 创建数据(POST)
  • READ— 获取/读取现有数据(GET)
  • UPDATE— 修改/更新数据(PUT)
  • DELETE— 删除数据(DELETE)

所需物品

在阅读本文之前,需要先安装以下几项软件:

安装步骤可在相应网站的文档中找到。

设置 PostgreSQL 数据库

首先,我们将在PostgreSQL中创建一个数据库,供服务使用。我们将使用psql相应的程序。以下是具体步骤。

使用以下命令登录:

psql -U postgres
Enter fullscreen mode Exit fullscreen mode

通过使用上述命令,我们已经以 postgres 用户身份登录到 PostgreSQL。

postgres=#
Enter fullscreen mode Exit fullscreen mode

创建数据库

要创建数据库,我们使用以下命令:

postgres=# CREATE DATABASE tutorial
Enter fullscreen mode Exit fullscreen mode

上述命令用于创建一个名为 tutorial 的数据库。要使用/连接到 tutorial 数据库,请使用以下命令:

postgres=# \c tutorial
Enter fullscreen mode Exit fullscreen mode

提示将变为以下内容:

tutorial=#
Enter fullscreen mode Exit fullscreen mode

表示我们已成功连接到教程数据库。

创建表格

接下来,在数据库中创建表tutorial。我们将在public模式中创建一个名为 students 的表。使用以下命令:

tutorial=# CREATE TABLE public.students (
    id serial NOT NULL,
    firstname varchar(40) NULL,
    lastname varchar(40) NULL,
    origin varchar(50) NULL,
    CONSTRAINT students_pkey PRIMARY KEY (id)
);
Enter fullscreen mode Exit fullscreen mode

使用该命令\dt检查表是否已成功创建。

tutorial=# \dt
            List of relations
Schema |   Name   |  Type | Owner
-------+----------+-------+---------
public | students | table | postgres
(1 row)

Enter fullscreen mode Exit fullscreen mode

要查看表格的详细信息,请使用命令\dstudents。

tutorial=# \d students
Table "public. students”
Column    | Type                  | Collation | Nullable | Default
----------+-----------------------+-----------+----------+-----------------------------------------
id        | integer               |           | not null | nextval(’students_id_seq’::regclass)
firstname | character varying(40) |           |          |
lastname  | character varying(40) |           |          |
origin    | character varying(56) |           |          |

Indexes:
      "students_pkey" PRIMARY KEY, btree (id)
Enter fullscreen mode Exit fullscreen mode

设置 Express.js 服务器

1. 项目结构

本文最后呈现的项目结构如下:

tutorial
├───node_modules
│ └─── ....
├───mode
│   └───response.js
├───index.js
├───queries.js
├───package-lock.json
└───package.json
Enter fullscreen mode Exit fullscreen mode

你可以使用这种结构来避免混淆。

2. 项目设置

第一步,创建一个名为 `<project_name>` 的项目目录tutorial,然后使用以下命令初始化Node.js :

mkdir tutorial
cd tutorial
npm init -y
Enter fullscreen mode Exit fullscreen mode

npm init -y命令将生成package.json一个包含以下内容的文件:

{
  "name": "tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
Enter fullscreen mode Exit fullscreen mode

接下来,使用以下命令安装依赖项(Express.js 和 PostgreSQL):

npm install express dan pg
Enter fullscreen mode Exit fullscreen mode

执行完成后,依赖文件将存储在文件node_modules夹中,依赖项列表将package.json如下所示:

{
  "name": "tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "pg": "^8.7.1"
  }
}
Enter fullscreen mode Exit fullscreen mode

接下来,在根文件夹中创建 index.js 文件。该文件是运行 Node.js 服务器所需的主文件。在 index.js 文件中,我们添加以下脚本:

const express = require("express");
const bodyParser = require("body-parser");

const app = express();
const port = 3000;

app.use(bodyParser.json());
app.use(
    bodyParser.urlencoded({
        extended: true
    })
)
Enter fullscreen mode Exit fullscreen mode

require函数用于管理我们项目的所有依赖项。

接下来,我们创建一个返回 JSON 的根 URL (/) 。

app.get("/", (request, response) => {
    response.json({
        info: 'Hello world!'
    });
})
Enter fullscreen mode Exit fullscreen mode

保存文件。要运行服务器,请使用以下命令:

node index.js
Enter fullscreen mode Exit fullscreen mode

如果服务器运行成功,您将在终端上看到以下内容:

$ node index.js
Server is running on 3000
Enter fullscreen mode Exit fullscreen mode

如果您http://localhost:3000通过客户端应用程序(Postman 或 Web 浏览器)访问,您将收到如下所示的 JSON 响应:

{
  "info": "Hello world!"
}
Enter fullscreen mode Exit fullscreen mode

3. 将 Express 与 PostgreSQL 连接

下一步的重要工作是将 Node.js 与 PostgreSQL 连接起来。我们创建一个名为queries.js的文件(文件名不必与文章中的完全相同,但程序中的用法应该保持一致),该文件将用于设置数据库连接以及访问和操作数据的查询语句。

本节首先需要做的是设置与要使用的数据库的连接池。这可以通过以下脚本完成:

const Pool = require("pg").Pool;
const pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'nama_db_kamu',
    password: 'password_kamu',
    port: 5432
});
Enter fullscreen mode Exit fullscreen mode

4. 创建响应类(可选)

这是一个可选步骤,纯属个人偏好。创建 Response 类的目的是为了规范我们创建的 API 的响应或输出。我常用的 Response 类如下所示:

class Response {
    constructor(status = false, code = 400, message = "", data = null) {
        this.status = status;
        this.code = code;
        this.message = message;
        this.data = data;
    }
}

module.exports = Response;
Enter fullscreen mode Exit fullscreen mode

本文将使用 Response 类queries.js。在本文中,我们将始终使用此 Response 类来格式化 API 响应中的 JSON 数据。

const Pool = require("pg").Pool;
const pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'testing_db',
    password: 'development',
    port: 5432
});
const ResponseClass = require("./model/response") // opsional
Enter fullscreen mode Exit fullscreen mode

创建 CRUD 操作函数

在本节中,我们将创建 5 个 CRUD 函数:

  • getStudents()— 获取所有学生数据
  • getStudentById()— 根据学生ID检索学生数据
  • createStudent()— 创建学生数据
  • updateStudent()— 根据学生ID更新学生数据
  • deleteStudent()— 根据学生ID删除学生数据

我们将在文件中声明这五个函数queries.js,它们将被访问index.js

获取 |getStundents()

const getStudents = (request, response) => {
    var responseReturn = new ResponseClass();
    pool.query('SELECT * FROM students ORDER BY id ASC', (error, results) => {
        if (error) {
            throw error
        }

        responseReturn.status = true;
        responseReturn.code = 200;
        responseReturn.message = "Success";
        responseReturn.data = results.rows;

        response.status(200).json(responseReturn);
    })
}
Enter fullscreen mode Exit fullscreen mode

获取 |getStudentById()

const getStudentById = (request, response) => {
    var responseReturn = new ResponseClass();
    const id = parseInt(request.params.id)
    pool.query('SELECT * FROM students WHERE id = $1', [id], (error, results) => {
        if (error) {
            throw error
        }
        if (results.rowCount == 0) {
            responseReturn.status = true;
            responseReturn.code = 404;
            responseReturn.message = "User not found";
            responseReturn.data = null;
        } else {
            responseReturn.status = true;
            responseReturn.code = 200;
            responseReturn.message = "Success";
            responseReturn.data = results.rows[0];
        }
        response.status(200).json(responseReturn);
    })
}
Enter fullscreen mode Exit fullscreen mode

帖子 |createStudent()

const createStudent = (request, response) => {
    const { firstname, lastname, origin } = request.body;
    pool.query('INSERT INTO students (firstname, lastname, origin) VALUES ($1, $2, $3)', [firstname, lastname, origin], (error, results) => {
        if (error) {
            throw error
        }
        response.status(201).send("Student added");
    })
}
Enter fullscreen mode Exit fullscreen mode

放置 |updateStudent()

const updateStudent = (request, response) => {
    const id = parseInt(request.params.id);
    var responseReturn = ResponseClass();
    try {
        const { firstname, lastname, origin } = request.body;
        pool.query('UPDATE students SET firstname = $1, lastname = $2, origin = $3 WHERE id = $4', [firstname, lastname, origin, id], (error, results) => {
            if (error) {
                throw error
            }

            responseReturn.status = true;
            responseReturn.code = 200;
            responseReturn.message = "User modification successed";
            responseReturn.data = null;
            response.status(200).send(responseReturn);
        })
    } catch (error) {
        responseReturn.status = false;
        responseReturn.code = 500;
        responseReturn.message = error.message;
        responseReturn.data = null
        response.status(500).json(responseReturn);
    }
}
Enter fullscreen mode Exit fullscreen mode

完整的代码queries.js如下:

const Pool = require("pg").Pool;
const pool = new Pool({
    user: 'postgres',
    host: 'localhost',
    database: 'testing_db',
    password: 'development',
    port: 5432
});
const ResponseClass = require("./model/response") // opsional

const getStudents = (request, response) => {
    var responseReturn = new ResponseClass();
    pool.query('SELECT * FROM students ORDER BY id ASC', (error, results) => {
        if (error) {
            throw error
        }

        responseReturn.status = true;
        responseReturn.code = 200;
        responseReturn.message = "Success";
        responseReturn.data = results.rows;

        response.status(200).json(responseReturn);
    })
}

const getStudentById = (request, response) => {
    var responseReturn = new ResponseClass();
    const id = parseInt(request.params.id)
    pool.query('SELECT * FROM students WHERE id = $1', [id], (error, results) => {
        if (error) {
            throw error
        }
        if (results.rowCount == 0) {
            responseReturn.status = true;
            responseReturn.code = 404;
            responseReturn.message = "User not found";
            responseReturn.data = null;
        } else {
            responseReturn.status = true;
            responseReturn.code = 200;
            responseReturn.message = "Success";
            responseReturn.data = results.rows[0];
        }
        response.status(200).json(responseReturn);
    })
}

const createStudent = (request, response) => {
    const { firstname, lastname, origin } = request.body;
    pool.query('INSERT INTO students (firstname, lastname, origin) VALUES ($1, $2, $3)', [firstname, lastname, origin], (error, results) => {
        if (error) {
            throw error
        }
        response.status(201).send("Student added");
    })
}

const updateStudent = (request, response) => {
    const id = parseInt(request.params.id);
    var responseReturn = new ResponseClass();
    try {
        const { firstname, lastname, origin } = request.body;
        pool.query('UPDATE students SET firstname = $1, lastname = $2, origin = $3 WHERE id = $4', [firstname, lastname, origin, id], (error, results) => {
            if (error) {
                throw error
            }

            responseReturn.status = true;
            responseReturn.code = 200;
            responseReturn.message = "User modification successed";
            responseReturn.data = null;
            response.status(200).send(responseReturn);
        })
    } catch (error) {
        responseReturn.status = false;
        responseReturn.code = 500;
        responseReturn.message = error.message;
        responseReturn.data = null
        response.status(500).json(responseReturn);
    }
}

const deleteStudent = (request, response) => {
    const id = parseInt(request.params.id)
    pool.query('DELETE FROM students WHERE id = $1', [id], (error, results) => {
        if (error) {
            throw error
        }
        response.status(201).send("Student deleted");
    })
}


module.exports = {
    getStudents,
    getStudentById,
    createStudent,
    updateStudent,
    deleteStudent
}
Enter fullscreen mode Exit fullscreen mode

创建 REST API 端点

下一步是创建将在 REST API 中使用的端点。端点是可以根据其请求方法(,,,GET访问的 URL POSTPUTDELETE

第一步是queries.js通过添加以下代码导入函数index.js

const db = require('./queries');
Enter fullscreen mode Exit fullscreen mode

接下来,需要添加的代码如下:

const express = require("express");
const bodyParser = require("body-parser");

const app = express();
const port = 3000;
const db = require('./queries');

app.use(bodyParser.json());
app.use(
    bodyParser.urlencoded({
        extended: true
    })
)

app.listen(port, () => {
    console.log("Server is running on " + port);
});

app.get("/", (request, response) => {
    response.json({
        info: 'Hello world!'
    });
})
app.get("/students", db.getStudents);
app.get("/students/:id", db.getStudentById);
app.put("/students/:id", db.updateStudent);
app.post("/students", db.createStudent);
app.delete("/students/:id", db.deleteStudent);
Enter fullscreen mode Exit fullscreen mode

现在您可以运行服务器并访问各个端点,每个端点都需要使用正确的 HTTP 数据类型。

结论

因此,我们成功创建了一个具有基本 CRUD 功能的 REST API。希望它能对您有所帮助 🙂

文章来源:https://dev.to/ahmadtheswe/crud-rest-api-with-nodejs-expressjs-and-postgresql-57b2