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

news2024/11/30 2:44:42

让我们在 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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/344565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【H.264】码流解析 annexb vs avcc

H264码流解析及NALUAVCC和ANNEXB 前者是FLV容器、mp4 常用的。后者 是实时传输使用,所以是TS 一类的标准。VLC显示AVC1就是AVCC AVCC格式 也叫AVC1格式,MPEG-4格式,字节对齐,因此也叫Byte-Stream Format。用于mp4/flv/mkv, VideoToolbox。 – Annex-B格式 也叫MPEG-2 trans…

微信公众号扫码授权登录思路

引言 上学期研究了一下微信登录相关内容,也写了两三篇笔记,但是最后实际登录流程没有写,主要因为感觉功能完成有所欠缺,一直也没有好的思路;这两天我又看了看官方文档,重新构思了一下微信公众号登录相关的…

操作系统综合实验

实验目的 加深对进程概念理解,进一步认识进程并发执行掌握Linux系统的进程创建和终止操作掌握文件系统调用及文件标准子例程的编程方法掌握Linux下终端图形编程方法,能编写基于文本的图形界面掌握proc文件系统的使用 相关知识 Linux C编程中的头文件 …

知识点整合

⭐面试 自我介绍(优势岗位匹配度) 为什么来我们公司(对公司的了解) 讲讲做的项目(为什么这么做,思路和贡献) 跨部门涉案的业务流程 我们跨部门涉案业务主要是本系统、配合物流系统和罚没系…

二战字节跳动成功上岸,准备了小半年,拿27k也算不上很高吧~

先说下我基本情况,本科不是计算机专业,现在是学通信,然后做图像处理,可能面试官看我不是科班出身没有问太多计算机相关的问题,因为第一次找工作,字节的游戏专场又是最早开始的,就投递了&#xf…

SpringMVC传值

实现步骤 先看后台代码如何获取前端传过来的数据,直接在方法的参数列表中添加RequestParam(xxx),再在后面加上参数列表即可 不过这样的方式会出现一个问题:当前端页面没有提交相应的数据过来的时候,后台会出现异常,所…

Elasticsearch7.8.0版本进阶——数据读流程

目录一、数据读流程概述二、数据读流程步骤2.1、数据读流程图2.2、数据读流程步骤(从主分片或者副本分片检索文档的步骤顺序)2.3、数据读流程注意事项一、数据读流程概述 从主分片或者从其它任意副本分片检索文档。 二、数据读流程步骤 2.1、数据读流…

5_机试_递归和分治

一、递归 本章介绍程序设计中的另一个非常重要的思想一递归策略。递归是指函数直接或间接调用自身的一种方法,它通常可把一个复杂的大型问题层层转化为与原问题相似但规模较小的问题来求解。递归策略只需少量的程序就可描述解题过程所需的多次重复计算,…

谈谈Java多线程离不开的AQS

如果你想深入研究Java并发的话,那么AQS一定是绕不开的一块知识点,Java并发包很多的同步工具类底层都是基于AQS来实现的,比如我们工作中经常用的Lock工具ReentrantLock、栅栏CountDownLatch、信号量Semaphore等,而且关于AQS的知识点…

DDR4 信号说明

SDRAM Differential Clock :Differential clocks signal pairs , pair perrank . The crossing of the positive edgeand the negative edge of theircomplement are used to sample thecommand and control signals on theSDRAMSDRAM差分时钟:差分时钟信号对&#…

MagicThoughts|让ChatGPT变得更智能的Finetuned数据集

近两个月,ChatGPT无疑都是AI领域最炙手可热的话题。而它的成功,也引发了行业内外对于对话式AI、LLM模型商业化应用可能性的思考。诚然,尽管就目前来看ChatGPT对大部分问答都能基本做到“对答如流”。但是,ChatGPT本质上依旧是预训…

Flutter Modul集成到IOS项目

Flutter Modul集成到IOS项目中1. 创建一个Flutter Modul2.在既有应用中集成Flutter Modul2.1 Flutter的构建模式选择2.1.1 debug模式2.1.2 Release模式2.1.3 Podfile 模式2.2 Cocoapods管理依赖库集成方式2.3 直接在Xcode中集成framework2.4 Local Network Privacy Permissions…

采用 spring 配置文件管理Bean

文章目录采用 spring 配置文件管理Bean一、安装配置Maven二、Spring 框架1、Spring 官网三、Spring 容器演示-采用Spring配置文件管理Bean1、创建Manev项目2、添加Spring依赖3、创建杀龙骑士类4、创建勇敢骑士类5、采用传统方式让勇敢骑士完成杀龙任务6、采用Spring 容器让勇敢…

创建Ubuntu虚拟机与Windows共享的文件夹

目录 1、Windows创建一个共享文件夹 2、在虚拟机的设置中选择Windows下的共享文件夹 3、在Ubuntu中查看共享文件夹 1、Windows创建一个共享文件夹 该共享文件夹可以被Windows和Ubuntu访问,需要注意的是,Ubuntu在共享目录下的一些操作会受到限制&…

图解经典电路之OCL差分功放-三极管分立器件电路分析

下面从简到繁,从框架到细节的顺序讲解电路。即先讲框架,然后逐渐添加电路细节,所以大家跟上思路。 1、第一步,尽可能的抽象这个电路,等效如下: 图二 OCL等效电路 整个OCL电路,可以等效为一个大功率的运放,加上几个电阻电容构成了一个同向放大器,就是这么简单。 为了便…

Linux常用命令---系统常用命令

Linux系统常用命令场景一: 查看当前系统内核版本相关信息场景二: sosreport 命令场景三: 如何定位并确定命令?场景四:查看当前系统运行负载怎场景五: 查看当前系统的内存可用情况场景六:查看网卡…

【DOTA】目标检测数据集介绍与使用

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 DOTA 数据集简单介绍 1. 正文 1.1 简介 数据集包含来自不同的传感器和平台的航拍图。每张图像的像素尺寸在 800 800 到 20,000 20,000 之间&#xf…

如何编写接口测试用例?

接口测试用例如何编写?下面简单给大家讲解一下。 接口测试用例是目前软件开发中不可或缺的一个重要部分,因此编写接口测试用例同样重要。 接口测试用例的作用非常明显,它能够帮助我们了解产品正在考验、调整它如何表现在特定情境之下、产品是…

2023金三银四,测试人还能找到好工作吗?

按照往年的惯例,春节后复工的 3 月、4 月是人员跳槽最频繁的时候,俗称“金三银四”。然而,市场大环境的影响,很多行业感受到了一丝寒冷的气息。我们以为受影响比较轻的互联网行业,头上也充满乌云,所谓互联网…

2023年浙江交安安全员考试题库及答案

百分百题库提供交安安全员考试试题、交安安全员考试真题、交安安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 50.根据《建设工程安全生产管理条例》第65条规定,施工单位有下列()行…