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

开发和应用 CRUD Node.js com PostgreSQL

开发和应用 CRUD Node.js com PostgreSQL

法拉码农们!都多切托?您可以使用 Node.js 和 PostgreSQL 来实现无后端应用程序的 CRUD 应用。因此,我们将向Azure Functions的无服务器架构迁移项目,向Azure PostgreSQL迁移本地数据库基础,最终实现部署应用程序或GitHub ActionsAzure DevOps

Acredito que o artigo será divido em 5partes, justamente visando ensinar passo a passo a todos vocês aqui.根据情况,以视频形式发布帖子,然后将其发送到视频中(sempre na semana seguinte ao artigo postado)。 Abaixo seguem 作为 5 个部分 dessa série:

请参阅存储库链接,了解有关项目的代码字体的所有信息,以及在 5 个项目期间可重复使用的信息。

重要信息:项目服务没有后端。如果没有最终的项目,请测试一个 API 做后端 criado 并应用程序,而不是前端,然后我们就可以测试一个 api criada 的前端通用测试!

Bom,já falei muito,vamos nessa?!

应用程序开发的循环利用

您可以在使用过程中重复使用这些应用程序,而不需要装饰该应用程序。圣埃莱斯:

您可以使用 PostgreSQL 来使用它,并且完全免费,可以使用 Sistema Operacional 和 melhor de tudo:完全开源! Inúmeras grandes empresas como: Uber, Netflix, Spotify, Instagram, Reddit and tantas outras fazem uso do do do PostgreSQL.因此,一个伟大的流行!

PostgreSQL 是 dados 的主要基础,并且是在 2012 年 Faculdade 银行的基础上推出的。 Semper gostei dele porque é muito simples e fácil de usar!

PostgreSQL 的详细安装指南。现在,我们将继续为您提供使用 Docker 镜像的教程。

安装 PostgreSQL

Bom, estarei ensinando aqui para differentusuários de SO:

  • Windows:对于 Windows,请先下载AQUI。安装时,请在 Windows 上安装程序。

  • MacOS:适用于 Mac,可以下载AQUI包。然后,安装Homebrew即可进行详细说明。 Caso tenham 遇到安装困难,建议使用AQUI视频

  • Linux:对于 Linux 来说,与 Linux 不同,推荐使用 PostgreSQL AQUI

不,我不使用 Windows,但我是开发者的主要负责人。使用 PostgreSQL 版本 12 的方式。安装说明,由pgAdmin提供。请使用浏览器:http://127.0.0.1:16450/ browser / 欢迎使用!

Screen-Shot-03-01-20-at-10-01-PM.png

在 PostgreSQL 中创建表格

Vamos criar agora a tabela com as propriedades que serão usadas para persistir e serem usadas no nosso Back-End.

A classe será:Produto

Classe: Product

- productId: integer primary
- product_name_: varchar
- quantity: int
- price: real
Enter fullscreen mode Exit fullscreen mode

Agora abrem o PgAdmin。准确地说,包括实现 PgAdmin 中的算法的功能。 Éprovável que você precision criar um Database. Bastam criar com o nome que vocês desejarem。可以创建数据库、直接创建脚本和执行脚本(与 PostgreSQL 一致)(符合 gif 格式):

CREATE TABLE products (
    productId SERIAL PRIMARY KEY,
    productName VARCHAR(255) NOT NULL,
    quantity INTEGER NOT NULL,
    price NUMERIC(5,2)
);
Enter fullscreen mode Exit fullscreen mode

postgresql-01.gif

集市上, bastam acessar a tabela revém criada!

postgresql-02.gif

奥蒂莫! Já temos a nossa tabela criada!

Criando 的 Node.js 应用程序设计

Agora que a nossa tabela está criada, vamos criar or projeto no Node.js.接下来的项目是 SOLID & Clean Code 的原则。 Caso vocês queiram saber mais sobre esses dois assuntos, recomendo os links abaixo:

Bom,vamos começar a arquitetar o nosso projeto。大声喊叫意大利面api并执行以下操作:

> npm init -y
Enter fullscreen mode Exit fullscreen mode

Esse comando criará um arquivo padrão do package.json。 E vamos agora instalar os seguintes pacotes:

> npm i --save-dev husky nodemon
Enter fullscreen mode Exit fullscreen mode

E também instalar os demais pacotes comodependencies

> npm i cors dotenv express express-promise-router pg
Enter fullscreen mode Exit fullscreen mode

没有最终结果,o arquivo package.jsonficará da seguinte forma:

{
  "name": "crud-nodejs-psql",
  "version": "1.0.0",
  "description": "Aplicação CRUD com Node.js & PostgreSQL",
  "main": "server.js",
  "scripts": {
    "dev": "nodemon",
    "lint": "eslint --ext .js,.html -f ./node_modules/eslint-friendly-formatter . --fix",
    "prepush": "npm run lint",
    "start": "node server.js"
  },
  "keywords": [
    "node.js",
    "javascript",
    "postgresel",
    "azure",
    "serverless",
    "azure-functions",
    "azure-devops",
    "azure-storage",
    "github-actions",
    "app-service",
    "express"
  ],
  "author": "Glaucia Lemos",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/glaucia86/nodejs-postgresql-azure/issues"
  },
  "homepage": "https://github.com/glaucia86/nodejs-postgresql-azure#readme",
  "devDependencies": {
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-plugin-import": "^2.20.1",
    "husky": "^4.2.3",
    "nodemon": "^2.0.2"
  },
  "dependencies": {
    "cors": "^2.8.5",
    "dotenv": "^8.2.0",
    "eslint-friendly-formatter": "^4.0.1",
    "eslint-plugin-html": "^6.0.0",
    "express": "^4.17.1",
    "express-promise-router": "^3.0.3",
    "pg": "^7.18.2"
  }
}

Enter fullscreen mode Exit fullscreen mode

请注意包含 aqui 的辅助包。可以通过以下方式进行操作:通过视频husky说明eslint这些元素并安装和配置项目。

YouTube:

喊出 estrutura das 面食和 arquivos 符合图像 abaixo:

Screen-Shot-03-05-20-at-10-50-PM.png

您可以通过制作意大利面和档案来获取AQUI项目的存储库或存储库。我希望我能完成一个项目的初始说明,即在项目中使用视频和视频来制作 Node.js 项目中的所有项目:

YouTube:

应用开发

Daqui em diante,não vou explicar o que cada arquivo faz。 RESTful API 的核心原则是 PostgreSQL 的最终开发。 mas, se ficarem curiosos a respeito de cada linha desenvolvida, recomendo que deem uma olhada nos video que eu fiz de uma API parecida com essa, onde eu explico detalhadamente o que é cada arquivo e as suas respectivas responsabilidades AQUI - 视频:Aula 13 à奥拉 26.1

Abram 和Visual Studio Code一起开发了一个解决方案:server.js包括以下代码块:

  • 文件:server.js
/**
 * Arquivo: server.js
 * Descrição: arquivo responsável por toda a configuração e execução da aplicação.
 * Data: 02/03/2020
 * Author: Glaucia Lemos
 */

const app = require('./src/app');

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log('Aplicação executando na porta ', port);
});

Enter fullscreen mode Exit fullscreen mode

集市、艾布拉姆或阿奎沃src -> app.js以及包括 bloco de código abaixo:

  • 文件:app.js
const express = require('express');
const cors = require('cors');

const app = express();

// ==> Rotas da API:
const index = require('./routes/index');
// const productRoute = require('./routes/product.routes');

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.json({ type: 'application/vnd.api+json' }));
app.use(cors());

app.use(index);
// app.use('/api/', productRoute);

module.exports = app;

Enter fullscreen mode Exit fullscreen mode

请注意,请注意,注释中app.js存在各种不同的情况,请执行以下 API 的初始操作。 Mas,lá para frente estaremos fazendo algumas alterações 有意义的 nesse arquivo 和 depois descomentar essas linhas。

最后,艾布拉姆或阿奎沃src -> routes -> index.js以及包括阿拜克斯的块:

  • 文件:src -> routes -> index.js
/**
 * Arquivo: src/routes/index.js
 * Descrição: arquivo responsável pela chamada da Api da aplicação.
 * Data: 02/03/2020
 * Author Glaucia Lemos
 */

const express = require('express');

const router = express.Router();

router.get('/api', (req, res) => {
  res.status(200).send({
    success: 'true',
    message: 'Seja bem-vindo(a) a API Node.js + PostgreSQL + Azure!',
    version: '1.0.0',
  });
});

module.exports = router;

Enter fullscreen mode Exit fullscreen mode

集市,艾布拉姆或命令命令执行意大利面api和执行命令:

> nodemon
Enter fullscreen mode Exit fullscreen mode

E, em seguida, abram o postman e incluam a seguinte URL no (GET): localhost:3000/api/e vejam o resultado:

Screen-Shot-03-02-20-at-12-47-AM.png

您可以使用符合相关图像的 API 功能!集市上,没有任何发展。阿奎瓦莫斯!

Entendendo um pouco mais sobre pacote: 'node-postgres'

不,没有任何时刻安装alguns 包,包括node-postgres包。这是 PostgreSQL 客户端(而非 Node.js)的基础。
Esse pacote um projeto开源。我们可以通过简单的文档和方向来实现 Promises 或 Async/Await 的实现。我可以使用 desenvolver esse 教程!

建议阅读有关 AQUI 的文档

该项目更喜欢使用Sequelize以及PostgreSQL、MySQL、MariaDB、SQLite 和 Microsoft SQL Server 的 ORM。 Justo para deixar esse projeto-1mais simples。

Se vocês desejarem, quando eu terminar essa série, posso criar um projeto na mesma estrutura usando o Sequelize. Deixem nos commentários abaixo se desejam que eu faça um artigo com o Sequelize! 😉

现在就开始吧node-postgres,快来吧!

Criando uma variável deambiente com 'dotenv'

尾声是从声音中发出的声音,是在安装时发出的声音。 Esse pacote server para que possamos armazenar as nossas variáveis deenvironmente que não desejamos deixar disponível para o public ao realizar um commit.

例如,我们使用连接字符串作为数据库的基础,并且使用连接字符串作为数据库的敏感信息,而不是对所有世界进行分配。 Vamos tratar isso agora no nosso projeto。 Para isso, sigam os seguintes passos abaixo:

Na raiz do projeto, dentro da Pasta apicrie o arquivo .env。包括以下内容或后续代码:

DATABASE_URL=postgres://{db_username}:{db_password}@{host}:{port}/{db_name}
Enter fullscreen mode Exit fullscreen mode

No meu caso, ficou da seguinte forma:

DATABASE_URL=postgres://postgres:glau123@localhost:5432/crud-nodejs-psql
Enter fullscreen mode Exit fullscreen mode

如果您没有使用db_usernamePostgreSQL,请直接使用 PgAdmin 服务器的命令,但可能Properties -> Connections会遇到用户名问题。 Vejam 没有 gif abaixo:

postgresql-03.gif

配置 Base 数据库:'database.js'

该集市包括一个没有任何连接字符串的集市.env,它是一个解耦和配置 PostgreSQL 应用程序基础连接的集市。

Para isso, abram o arquivo database.jse incluam o seguinte bloco de codigo:

  • config/database.js
/**
 * Arquivo: config/database.js
 * Descrição: arquivo responsável pelas 'connectionStrings da aplicação: PostgreSQL.
 * Data: 04/03/2020
 * Author: Glaucia Lemos
 */

const { Pool } = require('pg');
const dotenv = require('dotenv');

dotenv.config();

// ==> Conexão com a Base de Dados:
const pool = new Pool({
  connectionString: process.env.DATABASE_URL
});

pool.on('connect', () => {
  console.log('Base de Dados conectado com sucesso!');
});

module.exports = {
  query: (text, params) => pool.query(text, params),
};

Enter fullscreen mode Exit fullscreen mode

这个区块可能是一个连接字符串,用于连接 Node.js 上的 PostgreSQL 数据库。

注意使用 pacote 的状态node-postgres。 Se desejarem entender um pouco mais sobre o pg.Pool,推荐一个空闲的 AQUI,pois apartir deagora usaremos bastante ele,包括作为propriedades desse construtor!

Criando a rota:(发布)“创建产品”

我可以对应用程序进行配置,并实现与爸爸的基础连接! Agora é que de fato começará a brincadeira! E para isso, vamos desenvolver a primeira rota. E para isso, vamos desenvolver a primeira rota. E para isso, vamos desenvolver a primeira rota. Para isso, vamos usar bastante apartir de agora dois arquivos: product.controller.jse product.routes.js.

Sigam os seguintes passos:

包括 bloco de código abaixo no arquivoproduct.routes.js

  • 文件:product.routes.js
// @ts-nocheck
/**
 * Arquivo: src/routes/product.routes.js
 * Descrição: arquivo responsável pelas rotas da api relacionado a classe 'Product'.
 * Data: 04/03/2020
 * Author Glaucia Lemos
 */

const router = require('express-promise-router')();
const productController = require('../controllers/product.controller');

// ==> Definindo as rotas do CRUD - 'Product':

// ==> Rota responsável por criar um novo 'Product': (POST): localhost:3000/api/products
router.post('/products', productController.createProduct);

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

讨论阿基沃方法论的createProduct逻辑product.controller.js

  • controllers/product.controller.js
const db = require("../config/database");

// ==> Método responsável por criar um novo 'Product':

exports.createProduct = async (req, res) => {
  const { product_name, quantity, price } = req.body;
  const { rows } = await db.query(
    "INSERT INTO products (product_name, quantity, price) VALUES ($1, $2, $3)",
    [product_name, quantity, price]
  );

  res.status(201).send({
    message: "Product added successfully!",
    body: {
      product: { product_name, quantity, price }
    },
  });
};
Enter fullscreen mode Exit fullscreen mode

观察一下,使用插入代码的简单查询,使用 SQL 脚本进行操作。简单的阿西姆。 E claro que, para retornar os valores inseridos colocamos uma mensagem paraconfirmar o produto criado and retornando todos os value desse produto.

app.js预先测试和应用程序的预先准备。 Para isso, descomente as linhas onde estavam as rotas de product.routes:

  • 文件:app.js
/**
 * Arquivo: app.js
 * Descrição: arquivo responsável por toda a configuração da aplicação.
 * Data: 02/03/2020
 * Author: Glaucia Lemos
 */

const express = require('express');
const cors = require('cors');

const app = express();

// ==> Rotas da API:
const index = require('./routes/index');
const productRoute = require('./routes/product.routes');

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use(express.json({ type: 'application/vnd.api+json' }));
app.use(cors());

app.use(index);
app.use('/api/', productRoute);

module.exports = app;

Enter fullscreen mode Exit fullscreen mode

意大利面的提示音和数字或后续音api

> nodemon
Enter fullscreen mode Exit fullscreen mode
  1. 集市上,我们的人民测试了我们的初夜。 Para isso, abram o Postman no seguinte endpoint: (POST) localhost:3000/api/products, conforme o gif abaixo:

postgresql-04.gif

Se aparecer a seguinte mensagem como abaixo:

{
    "message": "Product added successfully!",
    "body": {
        "product": {
            "product_name": "Logitech MK270 Wireless Keyboard and Mouse Combo",
            "quantity": "2",
            "price": "18.99"
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

É porque persistiu perfeitamente。请注意以下事项,abram 或 PgAdmin da tabela criada 并遵守 gif 格式:

postgresql-05.gif

佩菲托! Uma vez que a gente consegue cricar a primeira rota, as demais serão fáceis!

Vamos dar continuidade!

Criando a rota: (GET) '列出所有产品'

Agora vamos criar 会列出所有有关 PostgreSQL 的产品和持久化信息。 Seria interessante vocês aproveitarem que a rota POSTjá está criada e include mais bados, para ajudar nas rotas futuras!

重新启动并获取Product.routes.js并包括待办事项列表和产品列表:

  • 文件:product.routes.js

// ==> Rota responsável por listar todos os 'Products': (GET): localhost:3000/api/products
router.get('/products', productController.listAllProducts);

Enter fullscreen mode Exit fullscreen mode

Agora 会自动打开Product.controller.js并按照listAllProducts的逻辑进行处理

  • arquivo:product.controller.js

// ==> Método responsável por listar todos os 'Products':
exports.listAllProducts = async (req, res) => {
  const response = await db.query('SELECT * FROM products ORDER BY product_name ASC');
  res.status(200).send(response.rows);
};

Enter fullscreen mode Exit fullscreen mode

请注意查询如下:SELECT * FROM products ORDER BY Product_name ASC。 Aqui estou pedindo para retornar todos os produtos persistidos no PostegreSQL em ordem alfabética! Fiz isso para deixar um pouco different! ;)

Vamos testar、abram o Postman 和 vejam o resultado:

postgresql-06.gif

功能齐全!注意,se precisarmos fazer um SELECTmais elaborado com subconsultas, seguindo a lógica, vai funcionar perfeitamente! :)

Criando a rota: (GET) 'List Product by Id'

集市,ficou muito fácil。我们将 SQL 与 CRUD 的相关性与 Node.js 的应用程序结合起来。

Vamos agora criar a rota para listar um minated produto pelo Id。 Novamente、abram 或 arquivo product.routes.jse 包括 mais uma rota:

  • 文件:product.routes.js
(...)

// ==> Rota responsável por selecionar 'Product' pelo 'Id': (GET): localhost:3000/api/products/:id
router.get('/products/:id', productController.findProductById);

(...)
Enter fullscreen mode Exit fullscreen mode

Agora abram o arquivo product.controller.jse vamos desenvolver a lógica dessa rota:

  • arquivo:product.controller.js
(...)

// ==> Método responsável por selecionar 'Product' pelo 'Id':
exports.findProductById = async (req, res) => {
  const productId = parseInt(req.params.id);
  const response = await db.query('SELECT * FROM products WHERE productid = $1', [productId]);
  res.status(200).send(response.rows);
}
Enter fullscreen mode Exit fullscreen mode

Vamos testar agora essa rota no Postman 和 vejamos o que acontece:

postgresql-07.gif

E vamos prosseguir!

Criando a rota: (PUT) '根据 ID 更新产品'

Vamos agora novamente retornar ao arquivo product.routes.jspara criar a rota updateProductByIdque será responsável por atualizar o produto pelo Id:

  • 文件:product.routes.js
(...)

// ==> Rota responsável por atualizar 'Product' pelo 'Id': (PUT): localhost: 3000/api/products/:id
router.put('/products/:id', productController.updateProductById);
Enter fullscreen mode Exit fullscreen mode

恢复方法updateProductById逻辑product.controller.js

  • arquivo:product.controller.js
(...)

// ==> Método responsável por atualizar um 'Product' pelo 'Id':
exports.updateProductById = async (req, res) => {
  const productId = parseInt(req.params.id);
  const { product_name, quantity, price } = req.body;

  const response = await db.query(
    "UPDATE products SET product_name = $1, quantity = $2, price = $3 WHERE productId = $4",
    [product_name, quantity, price, productId]
  );

  res.status(200).send({ message: "Product Updated Successfully!" });
};

Enter fullscreen mode Exit fullscreen mode

Está atualizando perfeitamente! Vejam 没有 gif abaixo:

postgresql-08.gif

Agora vamos para a nossa ultima rota!

Criando a rota:(删除)“按 ID 删除产品”

Enfim,chegamos a ultima rota da nossa api! Voltemos ao arquivo product.routes.jse vamos criar a rota para o método deleteProductById

  • 文件:product.routes.js
(...)

// ==> Rota responsável por excluir 'Product' pelo 'Id': (DELETE): localhost:3000/api/products/:id
router.delete('/products/:id', productController.deleteProductById);

(...)
Enter fullscreen mode Exit fullscreen mode

E enfim, desenvolver a lógica dessa rota no arquivo product.controller.js:

  • arquivo:product.controller.js
(...)

// ==> Método responsável por excluir um 'Product' pelo 'Id':
exports.deleteProductById = async (req, res) => {
  const productId = parseInt(req.params.id);
  await db.query('DELETE FROM products WHERE productId = $1', [
    productId
  ]);

  res.status(200).send({ message: 'Product deleted successfully!', productId });
};
Enter fullscreen mode Exit fullscreen mode

尽享完美功能,您可以在 PostgreSQL 上使用 5 个产品!

postgresql-10.gif

Palavras Finais

您可以使用 Node.js 持久化本地化的 CRUD API RESTFul,而不使用 PostgreSQL。无需通过Azure App Service即可实现部署应用程序! Depois de realizar esse部署iremos testar no Postman e consequentemente no Swagger!

Lembrando que essa série está dividida em 5 partses, a qual vocês podem acompanhar desde os códigos desenvolvidos, os links de cadaparte dos artigos e os video de cada série: AQUI

最重要的是要处理所有的声音。您可以通过Twitter与电子书进行转换。 E já temos o resultado Final!

Então sim。我已经提供了所有这些信息,作为我们的终端,您可以在电子书上使用 VuePress!

E para ficarem por dentro de várias outras novidades, no deixem de me seguir lá no twitter!

叽叽喳喳

不可以! Até a próxima pessoal! 😍

文章来源:https://dev.to/azure/desenvolvendo-uma-aplicacao-crud-node-js-com-postgresql-3clk