Giới thiệu
PostgreSQL (tiết tắt là Postgres) là một trong những cơ sở dữ liệu được sử dụng nhiều nhất trong việc xây dựng các ứng dụng phần mềm. Postgres là một hệ thống quản lý cơ sở dữ liệu đối tượng quan hệ chung, mã nguồn mở (RDBMS). Một trong những lợi thế của việc sử dụng Postgres là hỗ trợ cả truy vấn quan hệ (SQL) và không quan hệ (NoSQL).
Một cách để kết nối một cơ sở dữ liệu với một ứng dụng web là thông qua việc sử dụng một ORM (Object Relational Mapper). Một ORM hoạt động như một lớp giao tiếp giữa ứng dụng của bạn và cơ sở dữ liệu. Mục đích của hướng dẫn này là để giải thích làm thế nào bạn có thể sử dụng Postgres trong ứng dụng Express của bạn thông qua Sequelize ORM.
Sequelize ORM được mô tả như:
Một TypeScript và Node.js ORM hiện đại cho Oracle, Postgres, MySQL, MariaDB, SQLite và SQL Server, và nhiều hơn nữa.
Một TypeScript và Node.js ORM hiện đại cho Oracle, Postgres, MySQL, MariaDB, SQLite và SQL Server, và nhiều hơn nữa.
Bạn sẽ xây dựng một API quản lý nhiệm vụ đơn giản. API sẽ có thể tạo, liệt kê, cập nhật trạng thái hoàn thành và xóa nhiệm vụ.
Hướng dẫn này là đầu tiên trong một loạt các hướng dẫn sắp tới tập trung vào việc sử dụng cơ sở dữ liệu quan hệ trong Express bằng cách sử dụng Sequelize.
Điều kiện
Để tiếp tục với hướng dẫn này, bạn sẽ cần những điều sau:
- Một trình soạn thảo văn bản (ví dụ, VS Code)
- Một khách hàng API để kiểm tra các điểm cuối (ví dụ: Postman)
- Node.js được cài đặt trên máy tính của bạn
- Kiến thức cơ bản về Express
- Một trường hợp của Postgres chạy cục bộ hoặc từ xa
Dự án Setup
Chúng ta sẽ bắt đầu bằng cách thiết lập các tệp và thư mục thích hợp để tạo một ứng dụng Express và cài đặt các gói cần thiết.
-
Create the project directory:
mkdir tasks-manager-api
-
Navigate to the project directory:
cd tasks-manager-api
-
Initialize the NPM package by running the following command to create a
package.json
file with default settings:npm init -y
-
Install Express and other core dependencies:
npm install express express-async-errors dotenv && npm install nodemon --save-dev
-
Install Postgres driver for Node.js:
npm install pg
-
Install Sequelize:
npm install sequelize
-
In the root directory, create the
models
andutils
folders:mkdir models utils
-
In the root directory, create a
.env
file, which will contain the server’s port number and the database URL of any Postgres instance:PORT=5000 DATABASE_URL=postgres://<user>:<password>@<host>:<port>/<database>
-
In the root directory, create the
index.js
file, which is the application entry point:touch index.js
-
Set up the command to run the local development server by editing the
scripts
object inpackage.json
:{ //… "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "nodemon index.js", "start": "node index.js" }, //… }
Cấu trúc thư mục dự án nên trông như thế này:
Cấu hình Sequelize
Tạo hai tập tin trongutils
Quản lý :config.js
vàdb.js.
Loading Environment Variables Các biến môi trường
Trong theconfig.js
file, tải các biến môi trường từ.env
File sử dụngdotenv
package.Sau đó xuấtPORT
vàDATABASE_URL
các biến để chúng có thể được truy cập trong các phần khác của ứng dụng.
Cácconfig.js
File phải có các nội dung sau:
require('dotenv').config()
const PORT = process.env.PORT || 3000
const DATABASE_URL = process.env.DATABASE_URL
module.exports = {
PORT,
DATABASE_URL
}
Tạo Sequelize Instance
Trong thedb.js
file, tạo một Sequelize instance. Bạn có thể tạo một Sequelize instance bằng cách truyền URI kết nối cơ sở dữ liệu (được lưu trữ trongDATABASE_URL
) đến Sequelize constructor. Sau đó bạn tạo một hàmconnectToDB,
sẽ kiểm tra kết nối với cơ sở dữ liệu bằng cách gọiauthenticate
chức năng. Cuối cùng, bạn xuất khẩuconnectToDB
chức năng và phiên bản Sequelize.
Cácutils/db.js
File phải có các nội dung sau:
const Sequelize = require("sequelize");
const { DATABASE_URL } = require("./config");
const sequelize = new Sequelize(DATABASE_URL)
const connectToDB = async () => {
try {
await sequelize.authenticate()
console.log("Database connection established successfully.")
} catch (error) {
console.log("Unable to connect to the database:", error)
return process.exit(1)
}
return null
}
module.exports = {
connectToDB,
sequelize
}
Xác định mô hình Task
Một mô hình Sequelize là một đại diện của một bảng trong cơ sở dữ liệu. Bạn có thể xác địnhTask
mô hình bằng cách mở rộng SequelizeModel
Lớp và gọiModel.init(attributes, options)
chức năng
Trong themodels
quản lý, tạo cáctask.js
File với các nội dung sau:
const {Model, DataTypes} = require("sequelize")
const {sequelize} = require("../utils/db")
class Task extends Model {}
Task.init({
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
title: {
type: DataTypes.STRING,
allowNull: false
},
completed: {
type: DataTypes.BOOLEAN,
defaultValue: false
}
}, {
sequelize,
modelName: "Task",
timestamps: true,
underscored: true,
defaultScope: {
attributes: {
exclude: ["createdAt", "updatedAt"]
}
}
})
Task.sync()
module.exports = Task
Cácattributes
Parameter xác định cấu trúc củaTask
trong cơ sở dữ liệu.TheTask
Mô hình có 3 thuộc tính:
- id: Một trường số nguyên là một khóa chính tự tăng được sử dụng để xác định duy nhất từng bản ghi.
- Title: Một trường chuỗi đại diện cho tên của nhiệm vụ.
- hoàn thành: trường hoàn thành có một giá trị Boolean cho biết nếu nhiệm vụ đã được hoàn thành.
Cácoptions
parameter cấu hình cách Sequelize xử lý mô hình.Task
Mô hình có các tùy chọn sau:
- Sequelize là phiên bản Sequelize được tạo trước đó trong Utils/db.js.
- modelName: Tên của bảng được tạo trong cơ sở dữ liệu.
- timestamps: Khi được đặt thành true, tự động thêm các trường createdAt và updatedAt vào mô hình.
- nhấn mạnh: Khi được đặt thành true , chuyển đổi trường case camel sang trường Snake trong cơ sở dữ liệu.
- defaultScope: Trừ một số thuộc tính mặc định khi truy vấn.
CácTask.sync()
hàm đồng bộ hóa mô hình với cơ sở dữ liệu bằng cách tạo bảng nếu bảng không tồn tại. tuy nhiên, bạn nên lưu ý rằng đồng bộ hóa nên được thực hiện bằng cách sử dụng di chuyển.
Tạo Express Server
Cuối cùng, bạn đặt tất cả mọi thứ lại với nhau bằng cách tạo máy chủ Express.index.js
file, bạn thiết lập middleware cần thiết, xác định các đường dẫn điểm cuối API, và chạy máy chủ express.
Cácstart
chức năng chịu trách nhiệm cho việc khởi tạo máy chủ Express.start
function đầu tiên kiểm tra kết nối với cơ sở dữ liệu bằng cách gọiconnectToDB()
Nếu kết nối thành công, nó khởi động máy chủ Express, lắng nghe trên cổng được chỉ định.
Cácindex.js
File có các nội dung sau:
require("express-async-errors");
const express = require("express");
const app = express();
const { PORT } = require("./utils/config");
const { connectToDB } = require("./utils/db");
const Task = require("./models/task");
// middlewares
app.use(express.json());
// routes
app.get("/api/tasks", async (req, res) => {
const tasks = await Task.findAll();
res.json({
message: "List of tasks",
tasks: tasks,
});
});
app.post("/api/tasks", async (req, res) => {
const { title } = req.body;
const task = await Task.create({ title });
res.status(201).json({
message: "Task created successfully",
task,
});
});
app.patch("/api/tasks/:id/toggle-completed", async (req, res) => {
const { id } = req.params;
const task = await Task.findByPk(id);
if (!task) {
return res.status(404).json({ message: "Task not found" });
}
task.completed = !task.completed;
await task.save();
res.json({
message: task.completed
? "Task marked as completed"
: "Task marked as not completed",
task,
});
});
app.delete("/api/tasks/:id", async (req, res) => {
const { id } = req.params;
const task = await Task.findByPk(id);
if (!task) {
return res.status(404).json({ message: "Task not found" });
}
await task.destroy();
res.json({
message: "Task deleted successfully",
});
});
const start = async () => {
try {
await connectToDB();
app.listen(PORT, console.log(`Server is running on port ${PORT}`));
} catch (error) {
console.error(error);
process.exit(1);
}
};
start();
Thử nghiệm API Endpoint
Bây giờ bạn có thể tiến hành kiểm tra các điểm cuối API:
- Tạo một nhiệm vụ mới—POST /api/tasks:
- Danh sách tất cả các nhiệm vụ—GET /api/tasks:
- Toggle hoàn thành trạng thái—PATCH /api/tasks/:id/toggle-completed:
- Xóa một Task—DELETE /api/task:
Kết luận
Bây giờ bạn biết làm thế nào để kết nối một ứng dụng Express với một cơ sở dữ liệu Postgres bằng cách sử dụng Sequelize. Bạn đã xây dựng một API quản lý nhiệm vụ đơn giản, và trong quá trình này, bạn đã cấu hình Sequelize, kết nối Sequelize với một phiên bản Postgres, xác địnhTask
mô hình, và tạo ra các điểm cuối API.
Hiện tại, logic controller được viết trongindex.js
Trong các hướng dẫn sắp tới, chúng tôi sẽ tái tạo cơ sở mã này thành một cấu trúc có thể mở rộng hơn bằng cách sử dụng bộ điều khiển, bộ định tuyến và di chuyển Sequelize.
Để đọc thêm, bạn nên đi qua cácSequel tài liệuđể tìm hiểu thêm về truy vấn mô hình, xác thực, liên kết và nhiều hơn nữa.
Bạn có thể tìm thấy mã nguồn đầy đủ cho hướng dẫn này trênGitHub.
Tài nguyên
- Tài liệu Sequelize (v6)
- PostgreSQL là gì? - AWS
- Sử dụng cơ sở dữ liệu quan hệ với Sequelize – FullStackOpen
- Tài liệu Express.js