当前位置: 首页 > news >正文

使用 Nodejs、Express、Postgres、Docker 在 JavaScript 中构建 CRUD Rest API

让我们在 JavaScript 中创建一个 CRUD rest API,使用:

  • 节点.js

  • 表达

  • 续集

  • Postgres

  • 码头工人

  • 码头工人组成


介绍

这是我们将要创建的应用程序架构的架构:

我们将为基本的 CRUD 操作创建 5 个端点:

  • 创造

  • 阅读全部

  • 读一个

  • 更新

  • 删除

我们将使用以下方法创建一个 Node.js 应用程序:

  • 表达为框架

  • 序列化为 ORM

  1. 我们将 Dockerize Node.js 应用程序

  1. 我们将有一个 Postgres 实例,我们将使用 Tableplus 对其进行测试

  1. 我们将创建一个 docker compose 文件来运行这两个服务

  1. 我们将使用 Postman 测试 API


分步指南

这是一个分步指南。

新建一个文件夹

mkdir node-crud-api

步入其中

cd node-crud-api

初始化一个新的 npm 项目

npm init -y

安装依赖项

npm i express pg sequelize
  • express 是 Node.js 框架

  • pg 是与 Postgres 数据库连接的驱动程序

  • sequelize 是 ORM,所以我们避免输入 SQL 查询

创建4个文件夹

mkdir controllers routes util models

使用您喜欢的 IDE 打开文件夹。如果你有 Visual Studio Code,你可以从终端输入:

code .

你现在应该有一个类似于这个的文件夹:

现在让我们开始编码。

数据库连接

在“util”文件夹中创建一个名为“database.js”的文件。

此文件将包含内部配置以允许 Node.js 应用程序和正在运行的 Postgres 实例之间的连接。

填充 util/database.js 文件

constSequelize=require('sequelize');constsequelize=newSequelize(process.env.PG_DB,process.env.PG_USER,process.env.PG_PASSWORD,{host:process.env.PG_HOST,dialect:'postgres',});module.exports=sequelize;

用户模型

在“models”文件夹中创建一个名为“user.js”的文件。

该文件将包含模型,在本例中为具有自动递增 ID、名称和电子邮件的用户。

填充 models/user.js 文件:

constSequelize=require('sequelize');constdb=require('../util/database');constUser=db.define('user',{id:{type:Sequelize.INTEGER,autoIncrement:true,allowNull:false,primaryKey:true},name:Sequelize.STRING,email:Sequelize.STRING});module.exports=User;

控制器

该文件包含所有要执行的函数,以便与数据库交互并具有 4 个基本功能:

在“controllers”文件夹中创建一个名为“users.js”的文件

填充 controllers/users.js 文件

constUser=require('../models/user');// CRUD Controllers//get all usersexports.getUsers=(req,res,next)=>{User.findAll().then(users=>{res.status(200).json({users:users});}).catch(err=>console.log(err));}//get user by idexports.getUser=(req,res,next)=>{constuserId=req.params.userId;User.findByPk(userId).then(user=>{if(!user){returnres.status(404).json({message:'User not found!'});}res.status(200).json({user:user});}).catch(err=>console.log(err));}//create userexports.createUser=(req,res,next)=>{constname=req.body.name;constemail=req.body.email;User.create({name:name,email:email}).then(result=>{console.log('Created User');res.status(201).json({message:'User created successfully!',user:result});}).catch(err=>{console.log(err);});}//update userexports.updateUser=(req,res,next)=>{constuserId=req.params.userId;constupdatedName=req.body.name;constupdatedEmail=req.body.email;User.findByPk(userId).then(user=>{if(!user){returnres.status(404).json({message:'User not found!'});}user.name=updatedName;user.email=updatedEmail;returnuser.save();}).then(result=>{res.status(200).json({message:'User updated!',user:result});}).catch(err=>console.log(err));}//delete userexports.deleteUser=(req,res,next)=>{constuserId=req.params.userId;User.findByPk(userId).then(user=>{if(!user){returnres.status(404).json({message:'User not found!'});}returnUser.destroy({where:{id:userId}});}).then(result=>{res.status(200).json({message:'User deleted!'});}).catch(err=>console.log(err));}

航线

在“routes”文件夹中创建一个名为“users.js”的文件。

填充 routes/users.js 文件

constcontroller=require('../controllers/users');constrouter=require('express').Router();// CRUD Routes /usersrouter.get('/',controller.getUsers);// /usersrouter.get('/:userId',controller.getUser);// /users/:userIdrouter.post('/',controller.createUser);// /usersrouter.put('/:userId',controller.updateUser);// /users/:userIdrouter.delete('/:userId',controller.deleteUser);// /users/:userIdmodule.exports=router;

索引文件

要运行我们的应用程序,我们需要在根级别创建更多文件。这是将由 docker 容器执行的文件。

在根文件夹中,创建一个名为 index.js 的文件

填充“index.js 文件”:

constexpress=require('express');constbodyparser=require('body-parser');constsequelize=require('./util/database');constUser=require('./models/user');constapp=express();app.use(bodyparser.json());app.use(bodyparser.urlencoded({extended:false}));app.use((req,res,next)=>{res.setHeader('Access-Control-Allow-Origin','*');res.setHeader('Access-Control-Allow-Methods','GET, POST, PUT, DELETE');next();});//test routeapp.get('/',(req,res,next)=>{res.send('Hello World');});//CRUD routesapp.use('/users',require('./routes/users'));//error handlingapp.use((error,req,res,next)=>{console.log(error);conststatus=error.statusCode||500;constmessage=error.message;res.status(status).json({message:message});});//sync databasesequelize.sync().then(result=>{console.log("Database connected");app.listen(3000);}).catch(err=>console.log(err));

码头部分

让我们在根级别再创建 3 个文件:

  • .dockerignore(以点开头)

  • Dockerfile(大写字母 D)

  • docker-compose.yml

结构应如下所示:

.dockerignore 将包含一行:

node_modules

Dockerfile

要创建 Docker 镜像,我们需要一个简单但功能强大的文件。这就是所谓的“Dockerfile”(大写字母 D)。我们可能会使用不同的名称,但让我们暂时保持简单。

FROM node:14# Create app directoryWORKDIR /appCOPY package*.json ./RUN npm install# Bundle app sourceCOPY . .EXPOSE 3000CMD [ "node", "index.js" ]

Docker 组合文件

要运行多个服务,一种简单的方法是创建一个名为“docker-compose.yml”的文件

docker-compose.yml 文件:

version:"3.9"services:node_app:container_name:node_appbuild:.image:francescoxx/node_live_appports:-"3000:3000"environment:-PG_DB=node_live_db-PG_USER=francesco-PG_PASSWORD=12345-PG_HOST=node_dbdepends_on:-node_dbnode_db:container_name:node_dbimage:postgres:12ports:-"5432:5432"environment:-POSTGRES_DB=node_live_db-POSTGRES_USER=francesco-POSTGRES_PASSWORD=12345volumes:-node_db_data:/var/lib/postgresql/datavolumes:node_db_data:{}

构建 Docker 镜像并运行 docker 容器

在容器中运行 Postgres

首先,让我们运行 postgres 容器:

docker compose up -d node_db

要检查日志,我们可以键入:

docker compose logs

你应该得到类似于这个的输出:

如果我们看到“数据库系统已准备好接受连接”,我们就可以开始了!

让我们使用 TablePlus 对其进行测试。

单击 + 创建新连接

从 docker-compose.yml 文件复制值。(如果您保留原值,密码为 12345)

构建并运行 Docker 服务

其次,让我们构建我们的 Docker iamge:

docker compose build

最后,让我们启动服务:

docker compose up node_app

这应该是终端上的输出

使用 Postman 测试应用

让我们使用 Postman 测试应用程序。

向 localhost:3000 发出 GET 请求

向 localhost:3000/users 发出 GET 请求

我们应该有一个空数组作为响应

让我们创建 3 个用户:aaa、bbb 和 ccc

让我们再次检查所有用户:

向 localhost:3000/users 发出 GET 请求

我们应该看到 3 个用户:

让我们得到一个用户,例如用户 2

向 localhost:3000/users/2 发出 GET 请求

让我们更新现有用户,例如同一用户 2

使用不同的主体向 localhost:3000/users/2 发出 PUT 请求

最后,让我们删除用户号 3

对 localhost:3000/users/3 进行删除请求

我们还可以使用 TablePlus 检查值

结论

这是一个基本示例,说明如何使用 Node.js、Express、Sequelize、Postres、Docker 和 Docker Compose 构建 CRUD rest API。

相关文章:

使用 Nodejs、Express、Postgres、Docker 在 JavaScript 中构建 CRUD Rest API

让我们在 JavaScript 中创建一个 CRUD rest API,使用:节点.js表达续集Postgres码头工人码头工人组成介绍这是我们将要创建的应用程序架构的架构:我们将为基本的 CRUD 操作创建 5 个端点:创造阅读全部读一个更新删除我们将使用以下…...

电子招标采购系统源码之什么是电子招投标系统?

随着互联网时代的到来,各行业都受到不同的影响,其中招投标行业也不例外。为了顺应互联网潮流的发展,电子招投标逐渐取代传统的纸质的招投标方式,给招标方、投标方、招标代理等各方也带来了前所未有的机遇与挑战。那么什么是电子招…...

匹配文件名称模块glob和fnmatch

匹配文件名称模块glob 1.概述 glob模式规则与re模块的正则表达式规则不大相同,glob模块遵循标准的UNIX路径扩展规则。 fnmatch模块用于根据glob模式比较文件名 2.glob表达式匹配文件名 2.1.测试文件 介绍glob配置规则前,先使用下面的代码创建测试文…...

day12_oop

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、继承 三、重写 四、this和super 五、访问修饰符 零、 复习昨日 局部变量和成员变量什么区别 位置,作用域,初始值,内存位置,生命周期 构造方法…...

在 Flutter 中使用 webview_flutter 4.0 | js 交互

大家好,我是 17。 已经有很多关于 Flutter WebView 的文章了,为什么还要写一篇。两个原因: Flutter WebView 是 Flutter 开发的必备技能现有的文章都是关于老版本的,新版本 4.x 有了重要变化,基于 3.x 的代码很多要重…...

嵌入式ARM工业边缘计算机BL302的CAN总线接口如何设置?

CAN 接口如图所示,输入如下命令: ifconfig -a //查看所有网卡 如果 FlexCAN 驱动工作正常的话就会看到 CAN 对应的网卡接口,如图。从图中可 以看出,有一个名为“can0”的网卡,这个就是 BL302 板上的 CAN1 接口对应的 c…...

Win11系统如何安装Ubuntu20.04(WSL版本)并安装docker

终于还是下定决心去换电脑了……这次采用轻量级的WSL,发现虽然没有占内存的GUI界面,但是编码和阅读文档还是非常nice的 1、首先开启Win11的虚拟机服务 2、下载你期望的Ubuntu服务器(这里以20.04为例) 安装成功后,发现…...

Elasticsearch和Solr的区别

背景:它们都是基于Lucene搜索服务器基础之上开发,一款优秀的,高性能的企业级搜索服务器。(是因为他们都是基于分词技术构建的倒排索引的方式进行查询)开发语言:java语言开发诞生时间:Solr2004年…...

如何在北京买房

首先我陈述一点,如果为了买房后再卖掉赚取差价,我这篇文章也许不适合,我这篇文章为整体愿景的发展而设计,为可操作房产的买卖而操作。 买房的愿景: 首先,我们要以一种心态来买房。那就是以始为终的态度&am…...

使用Proxifier+burp抓包总结

一、微信小程序&网页抓包 1. Proxifier简介 Proxifier是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链。 2. 使用Proxifier代理抓包 原理:让微信相关流量先走127.0.0.1:80到burp。具体…...

安装华为aab包的处理方式

1、转换 aab包 为 apks 说明: 1、bundletool-all-1.11.2.jar 转换文件的工具 2、a.aab aab源文件 3、xxx.apks 导入的文件以及路径(例如:D:\Android\xxx.apks) 4、–ksxxxx.jks 该aab打包所需的jsk文件 5、三条命令为 jsk打包所…...

Word处理控件Aspose.Words功能演示:使用 C++ 将 RTF 文档转换为 PDF

Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外,API支持所有流行的Word处理文件…...

【Java|多线程与高并发】进程与线程的区别与联系

文章目录什么是进程什么是线程上下文切换多线程一定比串行执行快吗进程与线程的区别与联系什么是进程 进程的定义:进程是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源,比如说CPU(寄存器),IO,内存&a…...

K8s手工创建kubeconfig

我们通过 kubectl 命令行连接 k8s apiserver 时需要依赖 kubeconfig 文件。 kubeconfig 文件通常包含了 context(上下文)列表,每个 context 又会引用 cluster 和 user,最后通过 current-context 指定当前 kubeconfig 使用哪个 con…...

【SQL开发实战技巧】系列(十七):时间类型操作(下):确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数

系列文章目录 【SQL开发实战技巧】系列(一):关于SQL不得不说的那些事 【SQL开发实战技巧】系列(二):简单单表查询 【SQL开发实战技巧】系列(三):SQL排序的那些事 【SQL开发实战技巧…...

代码随想录算法训练营第二十八天 | 491.递增子序列,46.全排列,47.全排列 II

一、参考资料递增子序列题目链接/文章讲解:https://programmercarl.com/0491.%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97.html 视频讲解:https://www.bilibili.com/video/BV1EG4y1h78v 全排列题目链接/文章讲解:https://programmercarl.…...

使用 Three.js 后处理的粗略铅笔画效果

本文使用Three.js的后处理创建粗略的铅笔画效果。我们将完成创建自定义后处理渲染通道、在 WebGL中实现边缘检测、将法线缓冲区重新渲染到渲染目标以及使用生成和导入的纹理调整最终结果的步骤。翻译自Codrops,有改动。 Three.js 中的后处理 Three.js中的后处理是一…...

推荐一些不常见的搜索引擎

5.雅虎网来自 Yahoo.com 的屏幕截图,2023 年 2 月截至 2022 年 1 月,Yahoo.com(Verizon Media)的搜索市场份额为 11.2%。雅虎的优势在于多元化,除搜索外还提供电子邮件、新闻、金融等服务。二十多年来,雅虎…...

RabbitMQ工作模式

目录1.Work queues工作队列模式1.1 模式说明1.2 代码1.3 测试1.4 小结2.订阅模式类型3.Publish/Subscribe发布与订阅模式3.1 模式说明3.2 代码3.3 测试3.4 小结4.Routing路由模式4.1 模式说明4.2 代码4.3 测试4.4 小结5.Topics通配符模式5.1 模式说明5.2 代码5.3 测试5.4 小结6…...

机器学习在预测脊髓型颈椎病中的应用:一项28名参与者的事后初步研究

机器学习在预测脊髓型颈椎病中的应用:一项28名参与者的事后初步研究 Machine Learning for the Prediction of Cervical Spondylotic Myelopathy: A Post Hoc Pilot Study of 28 Participants 简单说:训练了两个模型:1)预测脊髓型颈椎病诊断&#xff0…...

Linux系统编程-makefile文件与make命令的使用

目录 一.makefile文件 1.1什么是makefile 1.2 makefile的一、二、三 1.2.1 一个规则 (1) 两个基本原则: (2) 使用 ALL 来指定makefile的终极目标: 1.2.2 两个函数 (1) src $(wildcard *.c) (2) obj $(patsubst %.c, %.o, $(src)) 1.2.3 三个…...

代码审查进入“零延迟”时代:如何在CI/CD流水线毫秒级触发语义级风险推演?——2026奇点大会核心议题深度拆解

更多请点击: https://intelliparadigm.com 第一章:AI原生代码审查:2026奇点智能技术大会Code Review新范式 在2026奇点智能技术大会上,AI原生代码审查(AI-Native Code Review)正式取代传统人工规则引擎混合…...

在Taotoken模型广场根据任务需求挑选合适模型的实践心得

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在Taotoken模型广场根据任务需求挑选合适模型的实践心得 作为一名开发者,在构建应用时,选择合适的模型是项…...

智能车信标FM信号不稳?用9018和UPC1677搭建射频功放的避坑指南

智能车信标FM信号不稳?用9018和UPC1677搭建射频功放的避坑指南 在智能车竞赛和电子设计项目中,稳定可靠的FM信标信号是确保车辆精确定位和导航的关键。然而,许多参赛团队在实际搭建射频功放电路时,常会遇到信号弱、传输距离不足、…...

Dify 部署与使用

版本说明:本文基于 Dify 社区版最新稳定版(Docker Compose 部署方式)编写,涵盖部署原理、环境配置、Chat 应用、RAG 知识库、工作流编排及常见问题排查。 第1章 快速部署:从 0 到 1 启动 Dify 1.1 系统要求与架构概览 Dify 采用微服务架构设计,通过 Docker Compose 一…...

大规模深度学习性能调优:自顶向下的五件套

GPU 利用率上不去?显存莫名 OOM?分布式训练卡死不动?这些问题不能靠"再加一张卡"解决,必须靠 Profiling 把瓶颈找出来。性能调优的正确顺序是自顶向下:先在框架层看哪个算子慢,再下到系统层看 CP…...

探索罗技PUBG压枪宏:从技术原理到实战配置的进阶指南

探索罗技PUBG压枪宏:从技术原理到实战配置的进阶指南 【免费下载链接】logitech-pubg PUBG no recoil script for Logitech gaming mouse / 绝地求生 罗技 鼠标宏 项目地址: https://gitcode.com/gh_mirrors/lo/logitech-pubg 在激烈的《绝地求生》竞技环境中…...

SITS2026千人会场无线漫游卡顿真相(2026年最新802.11ax+Wi-Fi 7协同调度实测报告)

更多请点击: https://intelliparadigm.com 第一章:SITS2026千人会场无线漫游卡顿真相(2026年最新802.11axWi-Fi 7协同调度实测报告) 在SITS2026大会主会场(容纳1280人),参会者密集使用4K视频会…...

SITS大会议题申报倒计时72小时:手把手教你避开92%申报者踩过的5个致命误区

更多请点击: https://intelliparadigm.com 第一章:SITS大会议题申报倒计时72小时:手把手教你避开92%申报者踩过的5个致命误区 误区一:议题标题堆砌技术热词,缺乏真实问题锚点 大量申报者使用“AI云原生区块链赋能De…...

Gemini3.1Pro成本优化实战指南

在做 2026 年的多模态项目时,大家最关心的往往不是“能不能用”,而是“怎么用得更划算”。如果你正在对接不同模型、比较价格与可用性,先把计费规则与调用链路梳理清楚,会省下大量试错成本。你也可以把 KULAAI(dl.877a…...