O curso definitivo de Node JS 2026: Express, MongoDB, APIs REST, Socket e muito mais | Code Bless You | Skillshare

Velocidade de reprodução


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

O curso definitivo de Node JS 2026: Express, MongoDB, APIs REST, Socket e muito mais

teacher avatar Code Bless You, Make Coding Easy To Learn

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

    • 1.

      Introdução do curso

      2:57

    • 2.

      Seção 01 — O que é o NodeJS

      5:51

    • 3.

      História do NodeJS

      2:40

    • 4.

      Como o NodeJS funciona

      5:48

    • 5.

      Instalando o Node JS no sistema

      3:17

    • 6.

      Escrevendo o primeiro código de nó

      5:26

    • 7.

      torne o VS Code legal [OPCIONAL]

      1:59

    • 8.

      Seção 02 — O que são módulos

      3:52

    • 9.

      Criando seu próprio módulo

      6:47

    • 10.

      Acessando módulo em outro módulo

      5:10

    • 11.

      Exercício para módulo próprio

      3:04

    • 12.

      Usando o módulo de caminho

      7:13

    • 13.

      Obtendo detalhes do sistema operacional

      3:08

    • 14.

      Módulo de sistema de arquivos

      4:13

    • 15.

      Criando um servidor usando o módulo HTTP

      5:18

    • 16.

      Como lidar com rotas diferentes

      3:41

    • 17.

      Seção 03 — introdução ao NPM

      2:27

    • 18.

      Criando a embalagem

      4:20

    • 19.

      Instalando o pacote no projeto

      4:07

    • 20.

      Desinstalando pacotes

      1:03

    • 21.

      Instale o pacote como dependência do desenvolvedor

      1:46

    • 22.

      Pacotes desatualizados e atualizá-los

      5:56

    • 23.

      Remova pacotes não usados do projeto.

      1:48

    • 24.

      Seção 04 - API x API REST

      7:41

    • 25.

      Lista de API de planejamento para o Projeto 01

      1:49

    • 26.

      Configure um novo aplicativo

      1:08

    • 27.

      Crie um servidor usando o Express

      6:39

    • 28.

      Exercício para criar servidor expresso

      2:36

    • 29.

      Criando uma API para obter a lista de todos

      3:34

    • 30.

      Configuração do reinício automático do nodemon

      1:55

    • 31.

      Variáveis de ambiente

      3:42

    • 32.

      Parâmetros de rota e parâmetros de consulta

      5:43

    • 33.

      Obtenha um único documento por ID

      4:47

    • 34.

      API POST para adicionar um novo todo

      11:06

    • 35.

      Como validar os dados do usuário

      3:20

    • 36.

      Passando o código de status

      3:10

    • 37.

      res.send e res.json

      3:12

    • 38.

      Atualize tudo único com uma solicitação de PUT.

      5:29

    • 39.

      Exercício excluir tudo específico

      3:48

    • 40.

      Seção 05 — introdução do Middleware

      4:09

    • 41.

      Criando middleware personalizado

      3:17

    • 42.

      Criado em Middleware

      4:51

    • 43.

      Compartilhamento de arquivos estáticos do servidor

      4:28

    • 44.

      Middleware útil de terceiros

      4:58

    • 45.

      Como programar de acordo com o ambiente

      4:02

    • 46.

      arquivo env e pacote dotenv

      3:47

    • 47.

      Diferentes configurações para diferentes ENV

      3:43

    • 48.

      Mecanismos de template em aplicação de nó

      5:59

    • 49.

      Como limpar a estrutura do aplicativo de código

      5:34

    • 50.

      Seção 06 - Assíncrono x síncrono

      9:45

    • 51.

      para chamadas em

      6:32

    • 52.

      Resolvendo o problema usando retorno de chamada

      7:31

    • 53.

      Inferno de retorno

      3:39

    • 54.

      Promessa em JavaScript

      5:51

    • 55.

      Substituir chamadas por promessas

      7:51

    • 56.

      Async:await em JavaScript

      6:51

    • 57.

      Seção 07 Noções básicas de MongoDB

      1:16

    • 58.

      introdução ao banco de dados

      4:34

    • 59.

      Instale o MongoDB no Windows

      4:19

    • 60.

      Conecte o MongoDB com o aplicativo Node

      5:41

    • 61.

      Importância do esquema

      3:15

    • 62.

      Definindo esquema para documento

      4:05

    • 63.

      Criando modelos

      3:48

    • 64.

      Salvando um novo dado

      4:46

    • 65.

      Consulte os dados

      7:48

    • 66.

      Operadores de comparação no MongoDB

      6:17

    • 67.

      Operadores lógicos no MongoDB

      6:56

    • 68.

      Expressão regular no MongoDB

      5:23

    • 69.

      Conte e estime a quantidade de documentos

      2:46

    • 70.

      Paginação e consulta infinita

      6:37

    • 71.

      Atualize os dados

      9:20

    • 72.

      Atualizar operadores no MongoDB

      1:42

    • 73.

      Exclua os dados com a ajuda de ex

      3:01

    • 74.

      Exercício 01 — Configurando o MongoDB

      7:16

    • 75.

      Exercício 02 — para armazenamento de dados

      5:59

    • 76.

      Exercício 03 — colhendo dados

      5:52

    • 77.

      Exercício 04 — Atualização e remoção de tarefas

      8:21

    • 78.

      Seção 08 - Construído em validadores

      6:42

    • 79.

      Validadores personalizados

      4:28

    • 80.

      Validadores assíncronos

      1:59

    • 81.

      Opções úteis de SchemaTypes

      0:55

    • 82.

      Relação entre os modelos

      5:05

    • 83.

      Abordagem híbrida para relações

      2:23

    • 84.

      usando abordagem de referência

      4:41

    • 85.

      Como extrair dados de referência [Populate]

      2:47

    • 86.

      Aplicando a abordagem incorporar

      4:25

    • 87.

      Aplicando abordagem híbrida

      3:11

    • 88.

      Indexes no MongoDB

      10:54

    • 89.

      Como os índices funcionam no MongoDB

      9:47

    • 90.

      Seção 09 – Projeto 02 e planejamento

      1:51

    • 91.

      Criando um novo servidor

      2:39

    • 92.

      Conectando ao banco de dados

      2:15

    • 93.

      Exercício — criando modelo de usuário

      4:10

    • 94.

      Criando o novo usuário

      12:26

    • 95.

      Usar hash da senha para segurança

      5:16

    • 96.

      Validação de entrada do usuário usando Joi

      8:45

    • 97.

      Como funciona a autenticação

      3:30

    • 98.

      Gere o token JWT para o usuário

      5:45

    • 99.

      Configurando a expiração do token

      2:19

    • 100.

      Proteja a chave de segurança no Ambiente

      2:13

    • 101.

      Exercício Criar rota de login

      8:11

    • 102.

      Como autenticar o usuário? Logou ou não?

      12:56

    • 103.

      OAuth em detalhes

      5:44

    • 104.

      OAuth no aplicativo de nó — Faça login com o Google

      15:03

    • 105.

      OAuth com JWT

      16:36

    • 106.

      Faça login com o Facebook usando o OAuth

      10:37

    • 107.

      Simplificando o código

      3:00

    • 108.

      Problema com Single Token [ATUALIZAÇÃO]

      2:16

    • 109.

      Access Token e Atualização de Token [ATUALIZAÇÃO]

      7:17

    • 110.

      Implemente o access token e o refresh token [ATUALIZAÇÃO]

      9:24

    • 111.

      Atualize rota para novo token de acesso [ATUALIZAÇÃO]

      10:37

    • 112.

      OAuth com dois tokens [ATUALIZAÇÃO]

      2:21

    • 113.

      Rota para fazer logout de um usuário [ATUALIZAÇÃO]

      3:55

    • 114.

      Seção 10 — como criar o modelo de categoria

      3:58

    • 115.

      Crie uma nova API de categorias com upload de imagem.

      11:27

    • 116.

      Defina o nome do arquivo e o filtro em mais

      11:55

    • 117.

      Como obter a API de todas as categorias

      1:39

    • 118.

      Compartilhando imagens estáticas do servidor

      2:06

    • 119.

      Exercício: definindo modelo de produtos

      6:56

    • 120.

      Autorização baseada em função

      8:59

    • 121.

      Autorização personalizada baseada em funções

      5:40

    • 122.

      Como lidar com várias imagens de produtos

      3:30

    • 123.

      Create new Products

      7:16

    • 124.

      Obtendo todos os dados de produtos

      11:37

    • 125.

      Paginação ou consulta infinita

      5:58

    • 126.

      Como enviar produtos por categoria

      3:17

    • 127.

      Enviando produto por pesquisa

      2:25

    • 128.

      Exercício — obtendo dados de um único produto

      5:50

    • 129.

      Exercício. — Excluindo o produto

      10:52

    • 130.

      Pesquisar produtos por título [OPCIONAL]

      4:05

    • 131.

      Seção 11 — Por que lidamos com erros?

      2:44

    • 132.

      como lidar com promessas rejeitadas

      3:25

    • 133.

      Crie erros de middleware

      3:26

    • 134.

      Remova blocos de tentativa de captura

      1:44

    • 135.

      Registre erros no arquivo

      11:46

    • 136.

      Erros de log no mongoDB

      2:24

    • 137.

      Exceções não detectadas

      7:16

    • 138.

      Rejeições de promessas não processadas

      3:23

    • 139.

      Recapitulação do manuseio e registro de erros

      1:50

    • 140.

      Seção 12 — criando o modelo de carrinho

      6:50

    • 141.

      Definindo a lista de API para carrinho

      1:22

    • 142.

      Como adicionar produtos ao carrinho

      20:38

    • 143.

      Como obter o carrinho do usuário

      2:23

    • 144.

      Aumente a quantidade de produtos

      9:22

    • 145.

      Reduza a quantidade de produtos

      3:58

    • 146.

      Removendo um produto único do carrinho

      5:34

    • 147.

      Criando modelo de pedidos

      4:27

    • 148.

      Fluxo de trabalho de pagamentos

      3:53

    • 149.

      Implementando o gateway de pagamento Razorpay

      49:43

    • 150.

      Pagamento internacional usando o Paypal

      49:15

    • 151.

      Obtendo o histórico de pedidos

      2:21

    • 152.

      Atualizando o status por administrador

      5:17

    • 153.

      Limpando o código para arquivo de índice

      3:27

    • 154.

      Seção 13 — introdução do projeto 03

      1:05

    • 155.

      Configurando o Projeto 03

      5:14

    • 156.

      Crie modelo de usuário

      4:23

    • 157.

      Registrando um novo usuário

      10:35

    • 158.

      Exercício - API de login do usuário

      0:28

    • 159.

      Solução: API de login do usuário

      4:53

    • 160.

      Implemente o access token e o refresh token [ATUALIZAÇÃO]

      5:16

    • 161.

      Rota de atualização e logout [ATUALIZAÇÃO]

      9:00

    • 162.

      Detalhes atuais do usuário conectado

      7:27

    • 163.

      Resetando a senha do usuário

      13:11

    • 164.

      Formas de enviar e-mails no Node JS

      2:17

    • 165.

      Configure o Amazon SES para enviar e-mails

      21:09

    • 166.

      Como enviar e-mails GRATUITAMENTE

      10:13

    • 167.

      Seguidor e Seguidor Logic

      2:18

    • 168.

      Siga o usuário

      9:08

    • 169.

      Aceite a solicitação de acompanhamento

      7:45

    • 170.

      Exercício — obtendo a lista de seguidores e seguidores

      6:24

    • 171.

      Exercício — não siga o usuário

      3:34

    • 172.

      Seção 14 - Introdução

      0:26

    • 173.

      Crie um modelo de postagem

      3:43

    • 174.

      Crie uma nova publicação

      15:43

    • 175.

      Obtendo postagens atuais de usuários

      4:16

    • 176.

      Como obter o feed

      9:31

    • 177.

      Excluindo a postagem

      6:51

    • 178.

      Curta e diferencia do post

      4:56

    • 179.

      Implementando o recurso de comentários

      6:15

    • 180.

      Adicionando resposta aos comentários

      5:21

    • 181.

      Exercício — removendo comentário específico

      4:37

    • 182.

      Handling de erros

      3:06

    • 183.

      Introdução da seção 15

      1:10

    • 184.

      Criando o chat: modelo de mensagem

      6:23

    • 185.

      Obtendo chats para usuários

      6:32

    • 186.

      Recebendo mensagens de chat específico

      3:44

    • 187.

      API para enviar mensagens

      10:02

    • 188.

      O que são WebSockets

      5:16

    • 189.

      Conexão do soquete

      8:20

    • 190.

      Emissor de soquete e métodos

      8:07

    • 191.

      Recebendo mensagens para ambos os usuários

      2:02

    • 192.

      Lógica de participar da sala de chat

      3:00

    • 193.

      Implementando a participação em uma sala de chat

      4:35

    • 194.

      Exercício - Indicador de digitação

      8:48

    • 195.

      Aplicando o código de mensagem de envio real

      5:33

    • 196.

      Autenticar o usuário no Socket

      10:52

    • 197.

      Marcar usuários como Online e offline

      3:44

    • 198.

      Vários soquetes para um usuário único

      5:50

    • 199.

      Mensagens de atualização entregues

      17:15

    • 200.

      Atualizando o status da mensagem para visualizações

      8:53

    • 201.

      Adicionando campos de grupo no Schema

      2:42

    • 202.

      Crie uma nova API de grupo

      3:41

    • 203.

      Adicionando a lógica de chat de grupo em eventos de socket

      14:22

    • 204.

      Seção 16 — Opções de implantação

      2:32

    • 205.

      Simplificando o código

      8:18

    • 206.

      Como preparar o aplicativo de Node para produção

      2:58

    • 207.

      Visão geral do processo de implantação

      0:39

    • 208.

      Carregando o aplicativo de Node no Github

      5:52

    • 209.

      Implantando o aplicativo de Node na renderização

      3:37

    • 210.

      adicionando o MongoDB Cloud

      6:51

    • 211.

      O que é a arquitetura MVC? [BBONNUS]

      7:00

    • 212.

      Aplique a arquitetura de MVC [BBONNUS]

      20:56

  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

69

Estudantes

--

Sobre este curso

Boas-vindas ao masterclass definitivo de Node.js 2025 — uma jornada completa de 20 horas para o desenvolvimento moderno de back-end. Neste curso, você vai além da teoria e realmente criar projetos reais usando o Node.js, Express, MongoDB, Socket.IO e muito mais.

Se você quiser se tornar um desenvolvedor completo, conquistar sua primeira função de backend ou simplesmente entender como o Node.js funciona de forma simples, este curso oferece tudo o que precisa em um só lugar.

O que você vai aprender:

  • Entenda os conceitos principais do Node.js, incluindo módulos e bibliotecas integradas.

  • O que é o Node JS? Como o nó funciona sob o capô
  • Crie e estruture APIs RESTful usando o Express.

  • Trabalhe com o MongoDB e o Mongoose para armazenar, consultar e gerenciar dados.

  • Implemente a autenticação do usuário com tokens JWT.

  • Como adicionar login OAuth com o Google e o Facebook.

  • Crie fluxos de redefinição de senha usando o Amazon SES e SMTP.

  • Como integrar gateways de pagamento como o PayPal e o Razorpay.

  • Crie recursos em tempo real (chat individual e chat em grupo) usando o Socket.IO.

  • Implante aplicativos Node.js

  • Muito mais.

Por que você deveria fazer este curso:

O desenvolvimento de back-end é o centro de toda a web moderna e aplicativo móvel. Ao dominar o Node.js, você consegue ter a habilidade de:

  • Crie APIs escalonáveis e prontas para produção que potencializam aplicativos reais.

  • Adicione recursos reais, como autenticação, pagamentos e bate-papo aos seus projetos.

  • Aplique suas habilidades em trabalhos como freelancer, projetos de startup ou funções de desenvolvedor profissional.

  • Mantenha-se atualizado com os padrões do setor de 2025 em desenvolvimento de back-end.

Projetei este curso para que você passe de iniciante a desenvolvedor confiante de back-end passo a passo, com foco no aprendizado prático e casos de uso reais.

Para quem é este curso

Este curso é para:

  • Iniciantes que querem começar o desenvolvimento de back-end com o Node.js.

  • Desenvolvedores de front-end que querem se tornar engenheiros completos.

  • Estudantes, empreendedores e aspirantes a desenvolvedores que querem criar aplicativos completos para o mundo real.

Não é necessário nenhum conhecimento prévio do back-end, mas você já deve estar familiarizado com JavaScript básico (variáveis, funções, matrizes, objetos).

Materiais/recursos

Para participar deste curso, é necessário:

Você também terá acesso ao código inicial, modelos de projeto e arquivos de exemplo para ajudar você a acompanhar.

 

Conheça seu professor

Teacher Profile Image

Code Bless You

Make Coding Easy To Learn

Professor

Hi! I'm a passionate software engineer from Code Bless You and I love to teach about coding and general skills in less time. I've taught many people how to become professional software engineers.

My goal is to make coding fun for everyone. That's why my courses are simple, animated, and with practical implementation.

Learn by doing

Step-by-step tutorials and project-based learning.

Get support

One-on-one support from experts that truly want to help you.

don’t stress. have fun.

I can't wait to see you in class!

- Code Bless You

Visualizar o perfil completo

Level: Beginner

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui aulas curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

Transcrições

1. Introdução ao curso: Bem-vindo ao curso definitivo de NoJS. Neste curso, você aprenderá tudo sobre nodejs, do básico ao avançado, em uma linguagem simples e fácil de entender No final deste curso, você começará a criar aplicativos pendentes rápidos, escaláveis e seguros sem se Deixe-me contar alguns dos principais recursos abordados neste curso. Então, você aprenderá a conexão com o banco de dados. Paginação e rolagem financeira, autenticação de usuário, bem como recursos de login com o Google e login com o Facebook, envio de e-mails do nosso back-end, upload de várias imagens, erros de manuseio e registro, aplicar integração total de pagamento usando papel e também recursos de bate-papo em tempo real usando soquete, também recursos de bate-papo em tempo real envio de mensagens individuais, mostrando a digitação indicadores, tratamento do status da mensagem, se ela é enviada, entregue ou vista, e também recursos de bate-papo em grupo. Agora, para aprender esses conceitos avançados, precisamos de uma base sólida. Então, primeiro, começaremos aprendendo nodejs, como conceitos básicos do node, módulos integrados, Express, que é a estrutura nod Js mais popular e mais usada, alguns conceitos repressores de JavaScript, como callbacks Além disso, veremos o Mongo DB e as mangas e, se você entender os conceitos básicos com clareza, poderá implementar qualquer tópico avançado do node jazz com muita facilidade Além disso, quero esclarecer uma coisa. Neste curso, não criaremos front-end porque esse não é o escopo deste curso, mas experimentaremos alguns recursos com o front-end para que você tenha uma compreensão clara do fluxo de trabalho completo desses recursos. Eu lhe darei um código pronto para o front-end para degustação, então você só precisa executar esse arquivo e experimentar alguns recursos. É muito divertido. Então, se você sabe um pouco sobre node jazz, ou está confuso em conceitos, se não sabe nada sobre no Jazz, então este curso é para você. Durante este curso, criaremos três aplicativos de back-end. Primeiro, fazer um aplicativo para aprender conceitos básicos e, em seguida, dois grandes projetos: aplicativo de comércio eletrônico e back-end de aplicativo de mídia social, para aprender conceitos avançados de Node Jazz Agora você pode perguntar quem sou eu? Sou engenheiro de software e também ensino programação em linguagem fácil de explicar usando meu canal do YouTube, Deus te abençoe, e com meus cursos on-line No geral, neste curso, você receberá mais de 200 videoaulas em SD, implementação no mundo real, vários exercícios, para que você possa aprender sem Js com implementação prática, algumas dicas e truques e muito mais. Depois de concluir este curso, você escreverá o código No JS com confiança e usando as melhores técnicas ; portanto, inscreva-se rapidamente e torne-se um herói do No Js o to No Jazz UC neste curso. 2. Seção 01 — O que é o NodeJS: NodeJS é o mais popular para desenvolvedores, mas não é uma linguagem de programação ou não é um framework Então, o que é realmente nod Js? Vamos ver isso. Nojs é simplesmente um ambiente de execução para executar código JavaScript fora do navegador. O que eu quero dizer com isso? Então, como sabemos, usamos código JavaScript para alterar os dados na página da web ou implementar alguma lógica, mas não podemos executar o Ja Script fora do navegador. necessário vincular nosso arquivo JavaScript ao nosso arquivo SDML e, em seguida, podemos executá-lo em nosso navegador Mas com o nodejs, podemos executar o código JavaScript fora do navegador O Nodejs fornece um ambiente de execução para executar código JavaScript. Os desenvolvedores usam principalmente o Nojz para criar serviços de back-end chamados API ou, podemos dizer, interface de programação de aplicativos Agora você pode perguntar o que é uma API? Basicamente, é uma forma de dois programas se comunicarem entre si. Eu explico isso com um exemplo. Então aqui está um restaurante. Estamos sentados na mesa e queremos pedir comida. Nesse caso, o que faremos? Não podemos ir diretamente à cozinha e pedir nossa comida ao chef. Em vez disso, chamaremos um garçom. Garçom, pegaremos nosso pedido e o entregaremos na cozinha Depois disso, a cozinha começa a processar nosso pedido e dá comida ao garçom, e então o garçom entregará a comida Então, aqui, a Água é como um mensageiro que pega nosso pedido e passa esse pedido para o nosso destino. E então o garçom receberá uma mensagem de resposta desse destino e trará de volta para Então, no mundo real, essa mesa na qual estamos sentados é nosso aplicativo cliente ou front-end. Queremos obter alguns dados sobre alimentos que estão disponíveis no back-end. Chamaremos o Waiter, que é uma API, e enviaremos solicitações para Agora, a API transferirá essa solicitação para o servidor ou banco de dados, que é nossa cozinha, e esse servidor ou banco de dados compartilhará a resposta, que são os dados que queremos. E a API entrega os dados de resposta ao nosso cliente. Agora você entende o que é uma API. A API é uma forma de dois programas se comunicarem entre si. Com o NodeJS, podemos criar APIs do mundo real. Além disso, podemos criar aplicativos em tempo real super rápidos com o node JS Esses serviços fornecem energia aos nossos clientes, como aplicativos web e aplicativos móveis, muito úteis. Você sabia que Netflix, Paper, Uber, Lin DIN e muitas outras empresas famosas usam o No Jazz? Sim, porque o Noe Jaz torna seus serviços super rápidos e eficientes Além disso, P fez uma ótima pesquisa sobre Joe Jaz. Eu vou te dizer isso em apenas um minuto. Então, para resumir, o Node Jazz é um ambiente de execução e é a escolha ideal para criar aplicativos altamente escaláveis relacionados a dados e em tempo real Agora você pode perguntar, existem muitas estruturas e linguagens como Java e asp.net, que também podem criar O que há de especial no Node Jazz? Por que devemos aprender node jazz? Por que é tão popular? Em primeiro lugar, sem jazz, podemos criar serviços de back-end super rápidos e altamente escaláveis com baixo custo Além disso, as pessoas fizeram um ótimo experimento sem jazz. Nesse experimento, as pessoas criam o back-end do aplicativo sem jazz e também constroem o mesmo aplicativo com Java e spring. E você sabe o resultado desse experimento? É realmente chocante. Eles descobriram que o aplicativo Node é construído duas vezes mais rápido do que o aplicativo Java mais o Spring e com menos pessoas. Em Java mais spring, eles têm cinco desenvolvedores, então no node, eles só precisam de dois desenvolvedores, e ainda assim esses dois desenvolvedores criam aplicativos mais rapidamente no nodejs Além disso, o aplicativo node ocupa 40% menos arquivos. Além disso, em Java, eles têm 5.000 linhas de código, mas em nodejs, eles têm apenas 1.500 linhas de código, que é três vezes Portanto, o aplicativo de nó é muito mais rápido, tempo de resposta 35% mais rápido do que o aplicativo Java, e o aplicativo de nó pode atender quase duas solicitações X por segundo do que o aplicativo Java. Esse resultado chocou a todos e as pessoas migraram imediatamente muitos serviços do Java para o node Jz É muito legal, certo? Em segundo lugar, com o node jazz, obtemos uma base de código mais limpa e consistente porque, com menos código, podemos fazer muitas coisas complexas. Além disso, é ótimo para prototipagem, o que significa que o node Jazz é rápido e fácil usar ao criar a primeira versão de um aplicativo A primeira versão é chamada de protótipo. Além disso, como sabemos, no node jazz, usaremos JavaScript. Portanto, se você é amigo e desenvolvedor, pode aprender o node Jazz facilmente sem aprender uma nova linguagem de programação. E se você aprender front-end e back-end, poderá mudar sua função desenvolvedor full stack, melhorar sua carreira e receber E mais um benefício do Nojs é Nojz tem um grande ecossistema de bibliotecas de código aberto, o que significa que há código predefinido para Assim, podemos usar o código de outra pessoa e implementar seus recursos em nosso aplicativo. Portanto, no geral, aprender nodejs em 2025 ou no futuro certamente beneficiará você e sua carreira em programação 3. História do NodeJS: Na lição anterior, vemos que o No Jazz é um ambiente de execução para executar código JavaScript fora do navegador. Mas vamos ver como Noe Jazz inventou uma história interessante. Antes de 2009, o JavaScript era como um super-herói preso dentro de um navegador como Chrome, Firefox e muitos outros Em todos esses navegadores, há um mecanismo de JavaScript. Quando executamos nosso código JavaScript dentro do navegador, navegador passa esse código para o mecanismo JavaScript. mecanismo JavaScript processa esse código e o converte em código de máquina, que nosso computador pode entender. Por exemplo, o Microsoft Taj usa o Chakra Engine, o Firefox, usa o mecanismo Spider Monkey e o Google Chrome, usa o Fiat Engine, que é o mecanismo JavaScript mais poderoso entre todos os Por causa desses mecanismos de JavaScript diferentes, às vezes o código JavaScript funciona forma diferente em navegadores diferentes. Quando usamos JavaScript somente em navegadores , existem muitas limitações. Não podemos criar servidores nem realizar tarefas do Bend, como lidar com banco de dados, autenticação de usuários ou APIs Agora, na época um desenvolvedor, Yandll entra em cena Ele pensa: e se usássemos o motor Vat e deixássemos o JavaScript rodar em servidores em vez de apenas navegadores. Ele pega o motor Vet, que é o motor Js mais rápido, e grava esse motor no código CplusPlus Pode executar o código Jascip em nossa máquina e chamar esse software de nodejs, e isso é o SOO que o nodejs inventou Nod Js é um ambiente de tempo de execução para executar código JavaScript porque tem o mecanismo V JA Script Esse ambiente é um pouco diferente do que temos em nosso navegador. Como no script Ja do navegador, temos um objeto de documento para lidar com o documento SDML Também temos o objeto Window. Não entramos nesses objetos no node Jazz e também não queremos acessar objetos de documentos e janelas porque no node jazz, estamos criando serviços de back-end, e objetos de documento e janela são para tarefas de front-end. Então, por que precisamos de documento e janela no back-end? Com o node js, podemos fazer muitas outras coisas, como acessar o sistema de arquivos para ler e gravar arquivos. Podemos nos conectar ao banco de dados e armazenar dados no banco de dados, além de criar APIs rápidas e muito mais. Agora, uma pergunta que você pode fazer: como o nodejs é super rápido, como nenhum Jz funciona, e veremos isso na próxima lição 4. Como o NodeJS funciona: Então, vimos que o nodejs é usado para back-end super rápidos e altamente escaláveis Mas How Nod Js é super rápido. Portanto, a razão pela qual nenhum Js é super rápido é por causa de seu não bloqueio ou, podemos dizer natureza assíncrona do node Agora você pode perguntar o que é assíncrono? Deixe-me explicar com um exemplo simples. Imagine que aqui está um restaurante. Temos uma cozinha aqui e várias mesas. Agora, o primeiro cliente quer fazer o pedido. Então aqui, nosso garçom, vá até a primeira mesa e peça o pedido Digamos que uma pizza. E então nosso garçom dá esse pedido ao chef na cozinha Agora, enquanto prepara pizza, nosso garçom examinará outras mesas Digamos que a mesa dois queira dar outro pedido, então o garçom pegue esse pedido e também o entregue na cozinha Nosso garçom solteiro pode lidar com muitas mesas. Ele não precisa esperar que o chef conclua um pedido e depois pode servir outro pedido. Ele não precisa fazer isso. Isso é chamado de forma não bloqueadora ou assíncrona, e é assim que a aplicação de nós funciona Esse único redator está trabalhando como um único thread do node JS, cuja tarefa é lidar com a solicitação Portanto, esse único thread pode ser usado para lidar com várias solicitações sem bloqueio. Agora, do outro lado dessa forma assíncrona, também temos a forma síncrona também temos a forma síncrona Vamos entender isso também com o mesmo exemplo. Então, aqui, o cliente Vn quer fazer o pedido. Nosso garçom pega o pedido da primeira mesa e o entrega para a cozinha, e nós mesmos começamos a nos preparar para esse pedido como Agora, como sabemos, a pizza pode levar algum tempo para ser preparada. Nesse momento, em vez de manusear outras mesas, nosso garçom espera na cozinha para concluir o pedido Suponha que demore 10 minutos, então nosso garçom esperará lá por 10 minutos na cozinha Depois disso, entregue a pizza na primeira mesa. Agora, naquele momento, os clientes em outras mesas precisam se sentar porque nosso garçom fica bloqueado por 10 minutos Isso é chamado de bloqueio ou forma síncrona. A maioria das estruturas de back-end mais antigas, como w.net ou Rails, funcionam de forma síncrona Então, quando alguém envia solicitações no servidor, o servidor aloca um thread para lidar com essa solicitação Nosso exemplo, é weiter. Agora imagine que temos uma solicitação para obter a lista de usuários. Essa tarefa precisa de operação de banco de dados, o que pode levar tempo. Agora, se nesse momento recebermos outra solicitação , para lidar com essa nova solicitação, precisamos também fornecer a eles um novo tópico ou escritor Agora imagine que em nosso servidor há 1.000 solicitações. Devemos criar um tópico para todas essas solicitações? Se sim, então temos que aumentar o número de hardwares de servidor, que é muito caro É por isso que os aplicativos desenvolvidos em asp.net ou rails precisam de mais servidores e Agora, nesse momento, o nó entra em cena e, como vimos, o e, como vimos, nó usa a forma assíncrona ou sem bloqueio Obviamente, podemos fazer com que o aplicativo asp.net ou Rails funcione como um aplicativo sem bloqueio ou Mas, para isso, precisamos fazer um trabalho extra. Por outro lado, os aplicativos de nós funcionam por padrão de forma assíncrona ou sem bloqueio Portanto, é muito rápido e fácil de gerenciar. Quando recebemos várias solicitações no servidor do nó, nó tem um único encadeamento. Esse único thread pode lidar com uma solicitação. Agora, se essa tarefa levar tempo, encontre algo no banco de dados e, em seguida, nosso único thread adiciona essa tarefa na lista chamada evento Q, passa para outra solicitação e começa a lidar com essa solicitação. Esse evento Que notificará nó quando eles obtiverem dados do banco de dados e, em seguida, nosso nó enviará esses dados para a solicitação. Dessa forma, nosso único thread pode atender a vários usuários, e é por isso que o nodejs é uma ótima opção para aplicativos com uso intensivo de dados ou relacionados à rede Pode atender a mais clientes sem adicionar mais servidores, e é por isso que os aplicativos de nós também são altamente escaláveis Agora, a questão é: devemos usar o node Jazz para todos os tipos de aplicativos? E a resposta é não. Não devemos usar o node para aplicativos com uso intensivo de CPU. Agora, o que é o CiPI intensivo? Uso intensivo de CPU significa aplicativos que têm tarefas relacionadas à CPU, como aplicativos de edição de vídeo ou edição de fotos. Nesses tipos de aplicativos, temos muitos cálculos que podem usar poucas opções de CPU, que faz o sistema de arquivos ou a rede. E, como sabemos, o node é um aplicativo de thread único quando executa operações relacionadas à CPI quando outros clientes precisam esperar para concluir Aqui, o node perderá a vantagem de ser assíncrono, e é por isso que não devemos usar node para Pode usar o nó para aplicativos de entrada e saída, relacionados à rede ou dados em tempo real. Lembre-se de que não devemos usar o node para aplicativos intensivos em CiPI Caso contrário, o node pode ser usado para quase todos os tipos de aplicativos. Então, entendemos como o nod Jazz é mais rápido do que outros frameworks de back-end Não se preocupe com as teorias. Ao criar projetos no node Jaz, você entenderá tudo com muita facilidade Então, vamos começar a aprender o Node Jaz na prática. 5. Instalando o Node JS no sistema: Vamos ver como instalar o NodeJS em nosso sistema. Em primeiro lugar, verificaremos se Nojs já está em nosso sistema ou não Então, abra o prompt de comando no Windows e, se estiver usando Mac ou Linux, abra seu terminal e escreva o nó, versão do traço e pressione Enter Veja aqui eu recebo esse tipo de mensagem de erro, nó não é reconhecido como um comando interno ou externo. Isso significa que o nó não está instalado no meu sistema. Se você chegar aqui, a versão nodejs, significa que o node já está instalado em seu sistema, mas eu recomendo que você instale a versão mais recente da tabela do node Então acesse o navegador e o opennjs.org. Neste site, obtemos uma versão LTS do Nodjs para download, o que significa a versão mais recente da tabela que o nó recomenda oficialmente usar No momento em que estou gravando este curso, versão mais recente é 22.14 Mas, no futuro, pode haver uma versão atualizada disponível. Então, basta clicar nesta versão e o download começará. Uma pergunta que você pode fazer: esse curso é relevante para as futuras versões do node? E a resposta é sim. Este curso permanecerá relevante para qualquer versão do Node JS porque, neste curso, vamos nos concentrar fortemente nos fundamentos do Node JS, e você pode usar esses fundamentos em qualquer versão do Node JS Portanto, você não precisa se preocupar com nenhuma atualização de JS. Se alguma atualização importante ocorrer , atualizarei este curso de acordo com isso. Agora nossa configuração está pronta para ser instalada. Então, vamos abri-lo. Deixe-me colocar aqui Clique em Avançar, aceite os termos e condições e clique em Avançar. A partir daqui, você altera o caminho da instalação, mas, na minha sugestão, deixe como está. Novamente, clique em Avançar e Avançar e instale. E está feito. Agora, vamos verificar se o Nojs foi instalado com sucesso ou não. Então, volte ao prompt de comando ou terminal e escreva a versão dos nós e pressione Enter. Veja, agora eu chego aqui no nod Gs versão 22.14 0.0. Portanto, instalamos o node com sucesso em nosso sistema. Outra coisa que precisamos neste curso é o editor de código. editor de código favorito pessoal é Visual Studio Code ou o VS code, que é um dos melhores editores de código. Obviamente, você pode usar qualquer outro editor de código, mas poucos editores têm o poder que o código VS tem Além disso, neste curso, compartilharei minhas dicas e truques para o código VS. Então, se você não tem o código VS, acesse code.visualstudio.com, acesse code.visualstudio.com, baixe o código VS e instale-o. É muito simples. Agora, na próxima lição, escreveremos nosso primeiro código JS de nó. 6. Escrevendo o primeiro código de nó: Vamos escrever nosso primeiro código JS de nó. Abra uma pasta na qual você deseja criar um projeto. Aqui, abro a pasta Project e, nessa pasta, crio uma nova pasta, digamos, primeiro projeto e simplesmente abro esse projeto no VS code. Bom. Esse código VS parece um pouco menor para este curso. Então, deixe-me ampliar. Normalmente, eu não amplio muito, mas com esse zoom, você pode ver claramente o que estou fazendo. Perfeito. Agora vamos criar um novo arquivo aqui. Digamos que o ponto índice seja. Você pode usar qualquer nome. Depende totalmente de você. Agora, dentro desse arquivo, podemos escrever nosso código JavaScript normal, que estamos acostumados a escrever. Então, vamos simplesmente criar uma variável chamada saudação igual a E depois disso, simplesmente consultamos esse registro. Olá vírgula e simplesmente insira a variável de saudação. Salve esse arquivo. Agora você pode perguntar: como podemos executar esse código sem nosso navegador? Porque anteriormente, estávamos executando o JavaScript usando o navegador. Então, para executar esse código sem cadeiras, precisamos de um terminal. E use nosso terminal de sistema e abra nossa pasta de projeto nesse terminal, ou podemos usar o terminal de código VS. Eu sempre uso o terminal VSCode porque é fácil de abrir, vá ao menu do terminal e selecione um novo terminal, ou você pode pressionar Control plus Ele abrirá aqui o terminal. Agora, para executar esse arquivo index dot js, simplesmente escrevemos node, space e nosso nome de arquivo, que é index dot js. O nome do seu arquivo é apt Gs, então você deve escrever aqui nodspace app dot js e Veja, aqui temos nossa linha de console. Então, parabéns. Você escreve seu primeiro código nodejs Agora, para ocultar este terminal, podemos pressionar novamente Control plus Bectig Agora, aqui também podemos adicionar uma função e chamar essa função, mesma forma que estamos fazendo no JavaScript normal. Então, após o log de pontos do console na nova linha, podemos criar uma mensagem de impressão de função. E nos colchetes de Cully, simplesmente consolamos o registro de pontos . Tenha um bom dia. E depois dessa função, simplesmente chamamos essa função de impressão de mensagem, para que possamos obter essa mensagem do console, salvar esse arquivo e, para executá-lo novamente, o que escrevemos no terminal? Escreva, escrevemos o índice de espaço do nó dot js. Veja aqui que temos esses dois Consoles Loui. Então, podemos usar aqui definir a função de tempo limite, definir a função de intervalo, etc Podemos adicionar quase todo o código JavaScript no aplicativo node. Agora você pode perguntar qual tipo de código JavaScript não podemos adicionar aqui no projeto node JS. Portanto, no projeto NodeJS, podemos adicionar todos os tipos de código JavaScript, exceto escrever código de manipulação de doom, como documento dot Get element ou window dot location, etc., porque, como sabemos, qualquer código que escrevemos no aplicativo Node será executado no servidor e no servidor. Como podemos acessar objetos Como podemos acessar Deixe-me mostrar praticamente o que acontecerá se usarmos o documento neste arquivo JS de pontos de índice. Eu comento todo esse código usando Control plus slash ou Command plus slash e simplesmente aqui, o log de pontos do console Imprima aqui o objeto do documento. Salve esse arquivo e, no terminal, executamos novamente o node index dot js, ou podemos simplesmente pressionar um perro Isso trará um comando anterior para nós. Veja, aqui temos um erro que diz que o documento não está definido e é A mostrando a linha. Portanto, não podemos usar aqui o código de manipulação de doom. Outra coisa é que também não podemos usar aqui eventos específicos do navegador, como Alert. Então, no local deste console, adicionamos Alert, diga olá. Salve esse arquivo e vamos executá-lo novamente. Veja aqui que o alerta não está definido porque, novamente, esses são eventos relacionados ao navegador. O servidor não pode mostrar o Alerta no navegador. É o front-end que pode mostrar o Alert. Então, para resumir no arquivo Js de índice ou em qualquer outro arquivo no projeto node, escrevemos código JavaScript para servidor, podemos usar vários módulos, lidar com SDDPRquest, acessar nossos arquivos de sistema, conectar-se ao banco de dados, criar aplicativos em tempo real e muitas outras coisas que aprenderemos passo a passo neste curso Não se preocupe, você dominará o node após este curso. Você só precisa codificar comigo e tentar escrever o código depois de entendê-lo corretamente. Não basta copiar e colar. Você precisa entender por que escrevemos esse código específico e depois o implementamos. É muito simples. 7. Torne o VS Code legal [OPCIONAL]: Na lição anterior, se você se perguntar como meu código é reformatado quando eu salvo o arquivo Para isso, estou usando uma das melhores e mais populares extensões de código do VS chamada pretty. Instale essa extensão. Agora temos que fazer pequenas configurações para a instalação do Pretty E. Então, na seção de instalação, role para baixo até a seção do formatador padrão E aqui, copie essas duas linhas de código sem colchetes de Cully Agora, abra as configurações no ícone de engrenagem inferior, vá para configurações e, no canto superior direito, partir daqui, abra as configurações, toques e arquivo e, na última linha, adicione vírgula e, na nova linha, passe essas Veja esse arquivo. Agora, volte às configurações e formato de pesquisa ao salvar e verifique se está verificado e pronto. Além disso, muitos estudantes me perguntam qual tema e fontes eu uso para meu código VS. Então, atualmente, estou usando meu tema favorito, que é Au Mirage Warder Você pode baixá-lo no painel de extensão. Este tema não é muito claro nem muito escuro, então é bom para nossos olhos e tem uma boa aparência. O nome da fonte que estou usando é Monisa. Qual é a fonte paga, você pode baixar essa fonte da maneira que quiser Não posso dizer mais nada. Instale-os em seu sistema. E então, a partir da configuração do código VS, pesquise aqui a família de fontes e adicione o nome da fonte logo no início, e pronto. Você pode usar qualquer tema e fonte que desejar. Depende totalmente de você. E se você tiver uma ótima combinação, poderá adicionar suas capturas de tela do VS code na seção de perguntas e respostas Adoro ver isso, e pronto. Estamos prontos para ir. Então, vamos mergulhar nesse código JS do node. 8. Seção 02 — O que são módulos: Bem-vindo à segunda seção do curso definitivo de Node JS. Nesta seção, aprenderemos tudo o que precisamos saber sobre módulos, como o que são módulos? Como podemos criar nossos próprios módulos? Além disso, temos alguns módulos integrados , como caminho, sistema operacional, sistema arquivos, módulo DTP para criação de servidor e muito mais Vamos começar com o que são módulos. Mas antes disso, deixe-me dar uma situação. Na seção anterior, criamos esse arquivo JS de pontos de índice. Agora imagine que este é o projeto Began da Netflix, que é um projeto realmente grande. Este projeto tem muitos recursos, como conexão de banco de dados, autenticação de usuário, gateway de pagamento muitas outras APIs Agora imagine que adicionamos todo esse código de recurso em um único arquivo G de ponto de índice. Como você vai gerenciar isso? Ou se alguém lhe disser para adicionar outro recurso no mesmo projeto, imagine o quão confuso e difícil seria Qual é a solução aqui? Pense sobre isso. Aqui, podemos criar esses recursos separadamente em arquivos diferentes e, em seguida, simplesmente inseri-los no arquivo NodeJS do índice principal Esses arquivos pequenos diferentes são chamados de módulos no node JS. Se eu tiver problemas na conexão com o banco de dados, posso acessar o módulo de conexão do banco de dados e resolver ou melhorar esse código de forma independente. Resumindo, o módulo é um trecho de código que executa uma tarefa específica. Por exemplo, imagine que você está construindo um carro. Um carro tem muitas peças, como motor, rodas, lençóis, etc Cada peça é construída separadamente e também pode ser substituída ou reparada sem afetar o carro inteiro Agora, no node JS, os módulos funcionam de forma semelhante. Cada módulo representa uma parte diferente do nosso aplicativo, e esses módulos podem trabalhar juntos para formar um aplicativo completo. E é por isso que os módulos são uma parte muito importante do node JS. Agora podemos dividir os módulos em três tipos. O primeiro são os módulos locais. Esses são os módulos que criaremos para nosso próprio aplicativo, como módulo de banco de dados para conexão de banco de dados, módulo de pagamento para lidar com pagamentos, etc O segundo são os módulos principais. Esses são os módulos integrados que obtemos com o node JS. Eles já estão disponíveis em todos os aplicativos de nós. Por exemplo, FS para sistema de arquivos, STTP para criar um servidor STTP ou fazer STTPRquest Sistema operacional para funcionalidade relacionada ao sistema operacional e muito mais. Não se preocupe, explicarei nossos módulos principais nas próximas lições desta seção. Agora, o terceiro são os módulos de terceiros. Esses são os módulos criados e publicados por outros desenvolvedores. Se quisermos usá-los , precisamos instalar manualmente esses módulos em nosso projeto. Por exemplo, express dot js é um módulo de terceiros, que nos ajuda a criar APIs rapidamente. Outro módulo é o Mongoose for Mongo Div et cetera. Esses são módulos de terceiros criados por outra pessoa e também podemos usá-los em nosso projeto. Não se preocupe com todas essas coisas, vamos passo a passo e aprenderemos cada uma delas. Então, para resumir rapidamente, módulo é um trecho de código que executa uma tarefa específica Podemos armazená-los em arquivos separados e depois usá-los em qualquer outro arquivo. Agora, na próxima lição, criaremos nosso próprio módulo. 9. Criando seu próprio módulo: Vamos criar nosso próprio módulo personalizado. Então, aqui em nosso aplicativo, criamos um novo arquivo chamado de operações matemáticas dot js. Neste módulo, adicionaremos algumas operações matemáticas básicas e as reutilizaremos em nosso arquivo principal index dot js Então, primeiro, vamos criar uma nova função chamada AD e passar aqui dois parâmetros chamados A e B. E dentro dessa função, simplesmente escrevemos a adição desses dois parâmetros, A mais B. Você pode perguntar, como podemos usar essa função dentro do nosso arquivo index dot js? Porque todos nós sabemos que quando definimos uma função dentro de um arquivo, só podemos usá-la nesse arquivo, não fora do arquivo. Então, para usar essa função de anúncio em outro arquivo, temos que exportar essa função desse módulo de operações matemáticas e, em seguida, podemos importá-la no arquivo js de pontos de índice. Mas antes disso, deixe-me te mostrar uma coisa. Portanto, em nodejs, todos os arquivos têm um objeto chamado nesse objeto de módulo, temos muitas propriedades que fornecem informações sobre esse módulo específico Deixe-me mostrar isso na prática. Após essa função, simplesmente escrevemos log de pontos do console e imprimimos aqui o objeto do módulo. Agora temos que executar esse módulo de operações matemáticas. Então, abra o terminal e escreva node, math e pressione tab. Ele preencherá automaticamente o nome do arquivo. Veja, aqui temos esse objeto de módulo com várias propriedades. O primeiro é o ID, que é o ID exclusivo do módulo. Em seguida, temos o caminho, que é o caminho completo do nosso projeto. Depois disso, temos a exportação e ela é definida como objeto vazio. Você adivinha corretamente, se quisermos exportar a função de adição , teremos que adicionar a função dela nesse objeto de exportação. Depois disso, temos o nome do arquivo atual com o caminho completo e várias outras propriedades. Agora, como podemos adicionar a função add dentro desse objeto de exportação? É muito simples. Então, aqui escrevemos o módulo dot exports dot add, que é o nome da propriedade igual à função add Certifique-se de que não chamemos aqui a função add. Acabamos de adicionar aqui o nome da função. Eu sei que você acha que isso é um pouco confuso, mas confie em mim, não é Deixe-me te mostrar isso. Então, basta mover esse registro de pontos do console abaixo das exportações de pontos deste módulo. Salve esse arquivo e, no terminal, executaremos novamente esse arquivo. Você pode ver no objeto de exportação que temos a propriedade add e ela está configurada para adicionar função. Portanto, se você confundir com o mesmo nome de propriedade , também podemos alterar aqui nome da propriedade, como adicionar números Salve esse arquivo e vamos executá-lo novamente. Veja, aqui temos nome da propriedade de números de anúncios para adicionar a função. Agora também podemos exportar mais de uma função do módulo. Então, aqui criamos mais uma função chamada sub track. Novamente, precisamos aqui de dois parâmetros, A e B, e dentro dessa função, simplesmente retornamos A menos B. Agora, você pode me dizer como exportar essa função Certo, simplesmente escrevemos aqui módulo dot exports dot subtract é igual à nossa Veja as mudanças e dê uma olhada. Vamos executar novamente esse arquivo. Veja, aqui temos esse novo substrato de propriedade para nossa função abstrata Além disso, não é necessário que só possamos exportar funções do nosso módulo. Também podemos exportar variáveis, objetos ou matrizes, basicamente o que quisermos. Suponha que aqui no topo, criemos uma variável chamada nome. É igual a, digamos, código mais U e outra variável, número da sorte é igual a, digamos, sete Agora, se quisermos exportar apenas a variável nome , só podemos adicionar aqui módulo dot exports nome do ponto igual ao Não precisamos exportar a segunda variável se não vamos usá-la em nenhum outro arquivo. Exporte apenas variáveis ou funções que precisamos usar em outro lugar em nosso aplicativo. Agora, aqui está uma coisa. Essas três linhas de código parecem um pouco feias porque estamos repetindo as exportações de pontos do módulo Existe algum atalho para escrever isso? Sim, deixe-me te mostrar. Então, aqui podemos escrever algo assim. As exportações de pontos do módulo são iguais a, e aqui passamos o objeto e adicionamos todas as propriedades que queremos exportar neste único Então escrevemos, adicionamos, esfriamos, função, adicionamos outra propriedade, função substack colon, substack e podemos definir o nome como nome Esse código e essas três linhas de código funcionam da mesma forma porque aqui estamos definindo as propriedades uma por uma. Mas aqui nós os colocamos diretamente no objeto. Vamos remover essas três linhas. Nós não precisamos disso. Salve esse arquivo. Vamos limpar o terminal usando o CLS e, em seguida, executar o mesmo arquivo e ver aqui que obtemos o mesmo objeto de exportação de antes Portanto, se soubermos quando nome da nossa propriedade e o nome do valor de passagem são iguais , podemos remover essa coluna e o nome da variável. Portanto, essa adição significa adicionar adição de coluna. Da mesma forma que removemos esse substrato da coluna e também o nome da coluna Portanto, há várias maneiras de escrever o mesmo código. Salve isso e vamos executá-lo mais uma vez. Veja aqui que obtemos novamente o mesmo objeto de exportação. Agora temos propriedades no objeto de exportação e podemos acessar esse objeto de exportação em qualquer outro arquivo neste projeto, e veremos isso na próxima lição. 10. Acessando o módulo em outro módulo: Na lição anterior, criamos nosso módulo de operons matemáticos e exportamos três propriedades Deixe-me também remover essa linha do console. Nós não precisamos disso. Agora vamos ver como podemos acessar essas propriedades no arquivo JS de pontos de índice ou em qualquer outro arquivo. Vamos remover esse código anterior. Nós não queremos isso. Agora, para importar qualquer módulo em nosso arquivo, temos a função necessária no node Js. Chamamos essa função aqui e dentro dessa função nos códigos, inseriremos o caminho do nosso módulo. Então, como podemos ver, esses dois arquivos estão na mesma pasta, então podemos escrever aqui uma barra de pontos para frente, que representa a pasta atual E aqui escrevemos o nome do nosso arquivo, operações matemáticas dot js. Ou também podemos remover essa extensão dot js porque, se não passarmos a extensão com o nome do nosso módulo, por padrão, o nodejs usará dot js como E se tivermos esse arquivo de operações matemáticas na subpasta? Em seguida, temos que escrever aqui o nome da pasta primeiro e, em seguida, adicionar o nome do arquivo de barra E se tivermos esse módulo de operações Mth na pasta principal , aqui no lugar do ponto único, usaremos o ponto duplo Não se preocupe com a prática, você aprenderá isso. Por enquanto, basta escrever operações matemáticas de barra e ponto. Este retorno de função necessário exporta o objeto deste módulo, que obtemos aqui interminalmente. Deixe-me te mostrar. Aqui, armazenamos esse valor em uma variável chamada operações matemáticas. Você pode usar qualquer outro nome, mas, principalmente, usamos o mesmo nome desse módulo. Portanto, não precisamos nos lembrar de outro nome, então não precisamos nos lembrar de outro nome. Aqui, simplesmente compilamos operações matemáticas de log de pontos, salvamos as alterações e agora podemos executar esse arquivo index dot js O ponto de índice do nó é. Veja, aqui obtemos o objeto com essas três propriedades que adicionamos no objeto exports em Mth Operations Aqui, no lugar de operações matemáticas simples, podemos fazer metoperons dot AD E aqui passamos argumentos, digamos 20 e 30. Salve-os e vamos executar esse arquivo novamente. Veja, aqui temos a adição de dois números. Portanto, usamos com sucesso uma função de outro módulo. Você pode ver como é simples criar um módulo e usá-lo em outros arquivos. Só precisamos exportar desse módulo e, com require, podemos usar essas exportações em qualquer outro arquivo. Assim, podemos usar outras propriedades como methoperons dot Substack ou methoperons dot Mas podemos ver que quando precisamos usar qualquer uma dessas propriedades, precisamos escrever esse ponto matemático de operações. Então, podemos usar aqui o tópico Javascript chamado desestruturação de objetos Provavelmente você sabe disso porque é um tópico puro de Javascript. Mas vamos ver isso rapidamente. Então, aqui escrevemos nosso objeto e queremos extrair suas propriedades como variáveis. Então, no lugar dos metoperons dot AD, só temos que escrever EdD Então, no início, escrevemos Cs agora aqui, temos que usar colchetes iguais ao nome do nosso objeto, que Agora, você consegue pensar no que temos que escrever nesses colchetes Temos que escrever aqui o nome das propriedades, que queremos extrair desse objeto como variável. Escrevemos aqui add, que é nossa função, substract, que é outra função, name, que é nossa variável Agora, no lugar desse anúncio de pontos de operações matemáticas, podemos simplesmente usar essa adição e também podemos adicionar aqui o nome. Salve esse arquivo e vamos executá-lo em nosso terminal. Veja, aqui temos 50 e nosso nome. Além disso, ao fazer a reestruturação de objetos em outra linha, alguns desenvolvedores experientes gostam fazer na mesma linha exigida Então, eles simplesmente pegaram esse objeto daqui e simplesmente o colaram no lugar do nome dessa operação matemática. Portanto, não precisamos dessa linha extra, salve esse arquivo e vamos executá-lo novamente. Veja, aqui temos o mesmo resultado. Se você se confundir dessa forma de estruturação objetiva , pode simplesmente usar o método de anúncios de pontos de operações matemáticas Está totalmente bem. No final das contas, nosso código deve funcionar. 11. Exercício para módulo próprio: Agora é hora de fazer um pouco de exercício, para que você possa revisar os módulos Então, aqui você precisa criar um novo módulo em seu aplicativo chamado Logger E dentro disso, você precisa exportar duas funções. Uma função retornará data atual com essa expressão e outra função retornará ano atual com essa expressão. E então você precisa consolar esse resultado no arquivo JS de pontos de índice, mesma forma que fazemos no módulo de operações matemáticas, e nossa saída deve ficar assim, experimente e observe a solução. Então, espero que você conclua este exercício ou pelo menos tente resolvê-lo. Agora vamos ver a solução. Primeiro, criamos um novo arquivo chamado logger dot js. Agora, aqui, temos que adicionar duas funções. Portanto, a primeira função é a data atual e, no colchete GLY, simplesmente retornamos uma nova string de data, ponto e duas vezes Agora vamos duplicar essa função, selecioná-la e pressionar Shift mais alter mais seta para baixo ou Shift mais Option mais seta para baixo Vamos mudar o nome da função para ano atual e, no lugar de duas sequências temporais, escrevemos get full year. Agora, você se lembra de como exportamos essas funções? Usamos o módulo dot exports, e aqui simplesmente o configuramos como objeto e, dentro dele, escrevemos a data atual data atual e o ano atual na função do ano atual. Ou podemos simplificá-los removendo o mesmo nome. Ótimo. Então, exportamos essas funções. Agora só precisamos inserir essas funções em nosso arquivo JS de pontos de índice. Então, na parte superior, adicionamos função necessária e simplesmente passamos aqui o caminho do nosso módulo, que é uma barra de pontos porque esse módulo também está na mesma pasta e no mesmo registrador Agora podemos armazenar seu valor de exportação em uma variável chamada logger Ou, como fizemos na lição anterior, podemos desestruturá-lo assim Então, adicione aqui os calibrakets e veja aqui que obtemos as propriedades da data atual e do ano atual Agora, após esse console, adicionamos outro console e simplesmente chamamos aqui as duas funções uma por uma, data atual e ano atual. Salve as alterações e vamos executar esse arquivo no terminal. É uma cadeira de índice de nós, e veja aqui nossa saída. Assim, você pode ver como é simples e fácil criar nossos próprios módulos e acessá-los em outros módulos. 12. Usando o módulo de caminho: Então, até agora, vimos como trabalhar com módulos locais. Agora vamos ver alguns módulos principais ou podemos dizer módulos que já estão disponíveis no node JS. Então vá até nodjs.org e, a partir do cabeçalho, abra Certifique-se de selecionar outra versão e selecionar a versão Ts porque é a versão estável. Aqui obtemos todas as informações sobre o node JS, como objeto simples, console. Além disso, temos muitos tópicos explicados e como usá-los. Temos alguns módulos principais, como sistema de arquivos. Dentro disso, eles explicam todos os seus métodos e propriedades. Além disso, temos o módulo STP, módulo OS, o módulo de caminho e muito mais Aqui, veremos alguns módulos principais importantes que precisamos para criar nosso back-end. Se você gosta de aprender tudo isso , leia esta documentação. Mas, na minha sugestão, abordarei todos os módulos importantes. Vamos começar com o módulo Path. O Path Module é usado para trabalhar com caminhos de arquivos e diretórios. Por exemplo, quando queremos armazenar a imagem carregada em nosso servidor, usando esse módulo de caminho, podemos fornecer a essa imagem caminho adequado para salvá-la em uma pasta específica. Portanto, se você quiser mesclar dois caminhos ou outras coisas relacionadas a caminhos, poderá usar esse módulo de caminho. Deixe-me te mostrar isso. Além disso, você pode ver aqui que eles nos mostram como podemos acessar esse módulo em nosso aplicativo. Da mesma forma que estamos acessando nossos módulos locais na função necessária. Mas no lugar do caminho do arquivo, escrevemos o nome do nosso módulo. Então, em nosso aplicativo, eu simplesmente removo esse código. Não precisamos disso agora, aqui escrevemos a função require e, nos códigos, escrevemos a coluna do nó e o nome do nosso módulo principal, que é path. Na versão anterior do nó, apenas escrevíamos o nome do módulo principal sem o prefixo da coluna do nó Além disso, isso funcionará na versão atual. Eu uso essa sintaxe anterior, você pode usar qualquer sintaxe, depende totalmente de Agora, da mesma forma que antes, essa função require written exporta objeto desse módulo de caminho. Temos que armazená-los em um caminho variável. Agora você pode perguntar por que não desestruturamos aqui esse objeto como fizemos anteriormente? Sim, podemos fazer o mesmo aqui, mas ainda não sabemos sua propriedade. Portanto, é melhor não se desestruturar aqui. Agora, deixe-me mostrar alguns métodos úteis do módulo de caminho. Suponha que queremos ver algumas informações sobre um arquivo específico. Então, aqui temos o método path dot parse, e nesta função de análise, como passar o caminho completo do nosso arquivo Mas como podemos obter o caminho completo do nosso arquivo? Portanto, no node js, vimos anteriormente que todos os arquivos têm objetos de módulo, que usamos como exportações de pontos do módulo. Além disso, todos os arquivos têm outras duas variáveis. Um é o nome do arquivo underscore underscore, que retorna o caminho completo do arquivo atual e underscore underscore Dname, que é o caminho do diretório Deixe-me mostrar esses dois primeiro. Então, por enquanto, eu comento esse método de pasta de caminho e rapidamente consol log de pontos, underscore underscore Dname console dot log, underscre, nome do arquivo esse método de pasta de caminho e rapidamente consol log de pontos, underscore underscore Dname console dot log, underscre, nome do arquivo. Salve as alterações e vamos executar esse arquivo. Veja, aqui temos o caminho completo do diretório atual. Diretório significa pasta e, abaixo disso, para Underscore DescefleName, temos o caminho completo Agora, de volta ao nosso arquivo, removemos esse console e removemos o comentário daqui usando Control plus slash ou Command plus slash e, simplesmente nesta função de análise, passamos o nome do arquivo Underscredsc Obtemos alguns detalhes sobre esse caminho de arquivo e, para imprimir o resultado, simplesmente o agrupamos com o log de pontos do console. Bom, salve as alterações e vamos executar esse arquivo. Veja, aqui temos esse objeto. Primeiro, obtemos a propriedade raiz, que é o caminho raiz do caminho atual. Aqui no Windows, temos C, dois pontos, barra invertida. Se você é usuário de Mac ou Linux , você chegará aqui na barra frontal Em seguida, temos o DR, que é o caminho do diretório depois disso, temos a base, que é a última parte desse caminho, que é o ponto de índice Js. Depois disso, temos EXT para extensão e, por último, obtemos o nome da última parte, que é índice. Esse método de correção é usado para obter detalhes sobre o caminho específico Agora vamos ver mais um método útil módulo de caminho que é join. Suponha que, em nosso banco desejemos armazenar o caminho em que armazenamos nossa imagem enviada, como a foto do perfil. Entenda as fotos do perfil em pasta chamada uploads em Aqui podemos usar o método path dot join. Aqui, primeiro, precisamos do caminho do projeto atual e como podemos obter esse caminho de pasta? Devemos usar o nome do arquivo de sublinhado? Não, temos que usar underscore undisco dirname. No segundo argumento, passaremos o nome da nossa pasta , que é uploads Obteremos um caminho da pasta do nosso projeto e nos juntaremos à pasta Uploads no final desse caminho do projeto. Veja o que recebemos. Removemos esse console e armazenamos esse caminho em variável chamada caminho do perfil e os pontos do console registram esse caminho do perfil. Salve esse arquivo e vamos executá-lo. Veja, aqui temos o caminho completo. Esta primeira parte é sublinhado, querido nome, e entramos na pasta Uploads no final Sei que isso é um pouco confuso, mas não se preocupe quando usarmos esses módulos em nosso projeto, tudo isso fará sentido Agora, aqui você pode perguntar: podemos unir duas partes manualmente? Por que precisamos usar seu módulo de caminho. Então, como sabemos, para um caminho de arquivo, o Windows usa a barra invertida usuários de Mac e Linux usam Portanto, obtemos resultados diferentes em sistemas diferentes. Se escrevermos manualmente o caminho com uma barra invertida , no Mac não conseguiremos encontrar nosso Além disso, atualmente, nosso projeto está disponível localmente, e é por isso que sabemos qual é o caminho. Mas, no mundo real, implantamos nosso aplicativo de back-end em algum lugar da Internet e não sabemos o caminho para esse servidor Portanto, esse módulo de caminho é muito útil nesse tipo de situação. 13. Obtendo os detalhes do sistema operacional: Às vezes, precisamos de alguns detalhes do sistema operacional do nosso servidor , como qual sistema operacional ele está usando ou quanta memória eles têm, etc Para isso, temos outro módulo principal chamado OS, que significa sistema operacional. Então, removemos esse código anterior e você pode me dizer como podemos acessar esse sistema operacional? Certo, podemos usá-lo pela função require e simplesmente passar aqui o nó, coluna OS. Só podemos usar o sistema operacional. Agora podemos armazenar isso em uma variável chamada OS. Suponha que aqui queremos executar um código específico para o sistema Windows e, para Mac, queremos executar outra coisa. Aqui podemos escrever se a condição é uma plataforma de pontos, isso retornará o nome da plataforma na qual esse código está sendo executado. Se a plataforma st for igual a win 32, se isso for verdade, executaremos o código para Windows Por enquanto, acabamos de escrever console dot Log, hello, Windowsser Depois disso, queremos executar algum código para o sistema Mac. Adicionamos s e verificamos que a plataforma de pontos é igual a Dawn. Esse é o nome da plataforma para macOS. Dentro disso, executamos o log de pontos do console, hello MCUser. Por fim, simplesmente passamos ls e Consol dot log Hellouser. Verifique se está funcionando ou não. Veja as mudanças e dê uma olhada. Veja, aqui temos o Hello Windows user, então está funcionando. Agora, no módulo OS, temos muito mais propriedades. Não quero aborrecê-lo explicando todas as propriedades, porque isso levará muito tempo Mas deixe-me explicar mais duas propriedades úteis do módulo OS. Primeiro, podemos obter a memória total do sistema operacional usando este módulo do sistema operacional. Portanto, os pontos totalizam MM para memória, e podemos simplesmente imprimi-los usando o log de pontos do console. Além disso, temos outra propriedade chamada MM livre para obter a memória livre. Então, duplicamos essa linha usando Shift mais alter, seta para baixo ou a opção Shift plus, mais seta para baixo e alteramos essa função MM total com FreeMM Salve as alterações e dê uma olhada. Veja, aqui temos memória em mordidas. Tenho oito GB de memória total e a memória livre é de quase dois GB. Você pode ver que essa é a importância do node js. Antes do node js, usando JavaScript simples, não conseguíamos obter esse tipo de detalhe. Então é assim que o módulo OS é usado para obter informações do sistema operacional. 14. Módulo do sistema de arquivos: Há outro módulo principal popular que usamos para interagir com arquivos Por exemplo, com o sistema de arquivos ou o módulo FS, podemos escrever o arquivo, ler o arquivo, atualizar o arquivo e também podemos excluir um arquivo específico. Então, aqui na documentação do nó, abrimos o módulo do sistema de arquivos. Podemos ver que ele tem muitos métodos e propriedades. Deixe-me mostrar como podemos usar o Módulo FS. Vamos remover esse código anterior. Não se preocupe Vou adicionar todo esse código em um arquivo separado para que você possa vê-lo mais tarde. Aqui, queremos acessar o módulo principal, exigir o código Fs e armazená-lo em uma variável chamada Fs. Agora, simplesmente escrevemos Fs dot e vemos aqui a lista de todos os métodos. Mas o que é isso? Todos esses métodos têm duas variações. Um é o método síncrono ou de bloqueio, e o outro é sem palavra-chave que significa assíncrono Agora, como sabemos, o node é popular por causa de sua forma assíncrona ou sem bloqueio Temos que sempre usar métodos assíncronos no node js. O Node nos fornece um método síncrono para simplificar. Deixe-me mostrar os dois, um por um. Aqui, queremos obter a lista de arquivos que temos na pasta atual. Para isso, temos um método chamado read directory sync, e aqui passamos o caminho do diretório que queremos ler. Barra de ponto final, que é o diretório atual, e armazenamos esses dados em uma variável chamada data E, no final, simplesmente registramos esses dados. Salve as alterações e vamos ver o que temos aqui. Veja, aqui temos a lista de todos os arquivos dentro desta pasta. Agora vamos ver também como podemos usar o método Asynrns. Então, como diretório vermelho, e o mesmo de antes, na primeira posição, passamos nosso caminho de diretório, que é uma barra de ponto final Agora, em quase todos os métodos assíncronos, preciso passar o segundo argumento, que é a função de retorno de chamada, que é a função executada quando esse trabalho assíncrono E também podemos ver isso nas sugestões. Agora, há duas possibilidades para todo trabalho assíncrono Recebemos um erro ou concluímos esse trabalho com sucesso. Eu sei que isso é um pouco confuso se você estiver lidando com trabalho assíncrono por tempo, mas não se preocupe nas próximas seções, mas não se preocupe nas próximas seções, eu tenho uma seção completa Você aprenderá tudo isso em profundidade. Agora, nessa função na primeira posição, obtemos erro e, no segundo parâmetro, obtemos nossos dados. Se obtivermos um erro , obteremos null nesses dados E se obtivermos nossos dados , obteremos null nesse erro Então, para lidar com esse cenário, podemos superar a condição dela. Se o erro estiver disponível, registraremos o erro. Como vamos fazer o log de pontos do console, nossos dados. Simples assim. Agora vamos comentar esse console para o método síncrono Salve as alterações e dê uma olhada. Veja, aqui obtemos novamente os mesmos dados. Agora, se você quiser verificar se recebemos um erro ou não , podemos alterar esse caminho para outra coisa, salvar e executar esse arquivo novamente. Veja, aqui temos um erro, esse arquivo ou diretório não existe. Agora você entende como esses métodos de atuação funcionam. Além disso, não se preocupe com essa complexidade porque dificilmente usamos esses módulos principais em nosso projeto. Atualmente, estou mostrando apenas módulos, e esse módulo de arquivo está um pouco avançado para esse estágio. Então não se preocupe com isso. Você o dominará quando os usarmos em nossos projetos. 15. Criando um servidor usando o módulo HTTP: Vamos ver um dos módulos principais mais importantes do node JS, que é o módulo SDTP módulo SDDP nos permite criar um servidor SDDP e também lidar com diferentes SDDPRquest Como sabemos, o NodeJS é usado para criar back-end para nosso aplicativo cliente, mas atualmente, acessamos esse back-end apenas acessamos esse back-end E se nosso front-end quiser acessar nosso back-end? Então, para interagir com a web no nó, temos o módulo SDDP. Deixe-me mostrar de forma correta como podemos criar um servidor. Assim como antes, acesse módulo STDP usando a função necessária e passe aqui o SDDP e armazene isso na Agora, você pode me dizer o que esse módulo STDP está escrito? Eu retornarei o método SDDB. Agora, esse STDP tem um método chamado Create server, que é usado para criar um servidor para nosso aplicativo de back-end Agora, o que passaremos dentro dessa função de criação de servidor? Simplesmente, aqui passamos a função de retorno de chamada. Quando alguém envia solicitações ao nosso servidor, essa função de retorno de chamada é executada Deixe-me te perguntar uma coisa. Qual é o principal trabalho do nosso servidor? Portanto, quando o usuário envia a solicitação ao servidor, servidor precisa retornar a resposta de acordo com a solicitação de dados. Então, aqui em nossa função de servidor, precisamos das informações sobre a solicitação do usuário, qual API ele solicita, etc Então, aqui, nesse argumento de função, obtemos o objeto de solicitação, que são os detalhes da solicitação do usuário. Agora, aqui temos informações sobre a solicitação. Portanto, nosso servidor executa seu processo e suponha que queremos retornar a resposta como mensagem de olá mundo. Para enviar a resposta aqui no argumento da função, obtemos aqui o objeto de resposta após esse objeto de solicitação. Além disso, muitos desenvolvedores gostam de escrever um nome curto, Rg para solicitação e Rs para resposta Agora, para retornar a mensagem Hello world, escrevemos o ponto de resposta R. E em códigos, passamos nossa mensagem Hello world. No mundo real, retornaremos dados daqui, por enquanto estamos apenas escrevendo uma mensagem quando alguém envia uma solicitação no servidor. E aqui, também temos que dizer que essa resposta termina aqui. Então, escrevemos o ponto de resposta N. Isso garantirá que nosso processo de resposta termine aqui. Agora, aqui criamos nosso servidor, mas precisamos iniciá-lo em alguma porta. Se você não reagir, nosso aplicativo será executado no host local 5173 se for criado por y. Agora, da mesma forma que temos que iniciar este servidor em alguma porta Vamos ver como podemos fazer isso. Aqui, neste método stp dot Create Server, retorne nosso objeto de servidor, nós o armazenamos em uma variável chamada servidor E depois disso, na parte inferior, escrevemos o ponto LISN do servidor E nessa função, passaremos nossa porta na qual queremos iniciar esse servidor. Muitos desenvolvedores gostam de executar servidores em 5.000 ou 3.000. Mas você pode fornecer qualquer porta, certifique-se de que essa porta não seja usada em seu sistema. Aqui, eu gosto de usar 3.000. No mundo real, quando implantamos nosso servidor, essa porta será substituída pelo nosso nome de domínio Bend, como catwis.com ou tasrag dotben.com Além disso, nessa função, podemos passar outra função de retorno de chamada Essa função será executada quando nosso servidor for iniciado com sucesso. Aqui, simplesmente escrevemos consol dot log server start listening na porta 3.000 Salve as alterações e vamos executar esse código porque, sem esse código em execução, como o servidor criará o node index dot js. Veja, aqui o servidor começa a escutar na porta 3.000. Se você estiver usando Mac e usar a porta 5.000, poderá receber o erro de que a porta 5.000 já está em uso porque, no Mac pesquisas de receptor ARP são executadas nessa porta Pode usar outra porta como 5.001, 5.002 ou você pode até mesmo usar Não há regra para o número da porta, desde que a porta já esteja sendo usada por outro serviço em nosso sistema. Agora, para verificar isso, precisamos enviar solicitações nessa porta. Então, abra um navegador e simplesmente escreva aqui o URL, coluna 3.000 do host local ou o número da sua porta Veja, aqui está nossa mensagem, Hello World. Então, criamos nosso servidor com sucesso e também iniciamos esse servidor. Portanto, sempre que alguém enviar solicitações no servidor, essa função será executada e imprimirá essa mensagem simples assim. 16. Como lidar com rotas diferentes: Agora, atualmente, estamos enviando solicitações na rota portuária, o que significa rota para casa. Mas, no mundo real, o usuário pode enviar solicitações para o host local. Coluna 3.000, cortar sobre ou cortar produtos Portanto, também temos que lidar com essas diferentes rotas em nosso servidor. E para lidar com rotas diferentes, primeiro precisamos de informações para qual rota o usuário envia a solicitação. E para isso tenho aqui o objeto de solicitação. Escrevemos aqui com a condição de que eu solicite URL de ponto igual a em códigos, barra frontal Essa barra simples representa a rota raiz. Nos colchetes CL, podemos simplesmente mover esse ponto de resposta, função de gravação, retendo alter ou option, e a seta para cima Depois disso, queremos lidar, digamos, com a rota. Então, aqui adicionamos si request dot URL igual a in codes about e, se for verdade, simplesmente retornamos outro ponto de resposta da mensagem à direita É uma questão de rota. Assim, podemos adicionar quantas solicitações quisermos. E depois de todas as rotas, passaremos, o que significa rotas de passagem de usuário, que não são tratadas aqui E é por isso que aqui retornamos uma resposta simples, ponto à direita, rota não encontrada. Além disso, certifique-se de que essa função de ponto de resposta chamada no final dessa função do servidor. Salve as alterações e volte para o nosso navegador. Se mudarmos nosso URL para slash about, você pode me dizer o que obteremos aqui? Vamos ver. Veja, aqui recebemos a mesma mensagem de olá mundo porque em nosso terminal, nosso código antigo ainda está sendo executado, no qual não lidamos com rotas. Para executar esse novo código, precisamos executar novamente nosso aplicativo. No terminal primeiro, interromperemos o aplicativo pressionando Control mais C no Windows e no Mac. Depois disso, executamos novamente o node index dot js. Bom, chegamos aqui, os servidores começam a escutar na porta, e no navegador, se atualizarmos nossa página, veja, agora recebemos a mensagem aqui É uma questão de rota. E se tentarmos solicitar outras rotas, aqui teremos uma rota não encontrada. É assim que lidamos com diferentes rotas de API usando o módulo SGDP Agora imagine que temos 20 rotas de API diferentes e, para lidar com elas, temos que escrever mais 18 blocos sf E se todas essas rotas tiverem centenas de sinais de código , gerenciar nosso próprio servidor ficará muito confuso. Portanto, no mundo real, não usaremos esse módulo SDDP. Ou o fato de termos um módulo de terceiros muito popular chamado Express e o Express tem muito mais benefícios do que esse módulo SDTP Além disso, usando o Express, podemos dividir nossas rotas em arquivos diferentes, para não nos confundirmos quando precisarmos fazer alguma atualização ou quando quisermos adicionar novas funcionalidades Eu explico todos esses módulos para que você entenda pouco como node está funcionando e se familiarize com alguma sintaxe de JavaScript Espero que você goste desta seção, a próxima seção. 17. Seção 03 — introdução ao NPM: Venha para a terceira seção das pontuações definitivas do Node JS. Nesta pequena seção divertida, veremos tudo sobre o gerenciador de pacotes node ou, em resumo, o NPM Então, o que é o gerenciador de pacotes node? O gerenciador de pacotes Node é uma ferramenta que nos ajuda a gerenciar pacotes ou bibliotecas para nosso projeto Node. Em palavras simples, o NPM é como um grande armazém para desenvolvedores Nesse depósito, os desenvolvedores armazenam seu código JavaScript para outros desenvolvedores possam pesquisar esse código e baixar o código reutilizável em seu projeto Deixe-me te mostrar isso. Então vá para o NPM. JS.com. Aqui podemos pesquisar o nome do nosso pacote ou biblioteca. Pacote ou biblioteca significa um pedaço de código reutilizável. Por exemplo, na seção anterior, eu disse que usaremos Express Library para criar um servidor STD Veja, aqui temos muitos resultados para essa pesquisa. Simplesmente, abrimos este pacote Express. Veja no lado esquerdo, obtemos a documentação básica, como usá-la, etc., e no lado direito, obtemos informações sobre o pacote Em primeiro lugar, na parte superior, temos o comando de instalação, que você verá na próxima lição. Em seguida, temos o link do repositório do Github para que possamos ver o código e também obter o link do site oficial Aqui podemos ver que são os downloads mensais desse pacote. Com isso, podemos ver a popularidade desse pacote. Além disso, obtemos informações sobre a versão e muitas outras coisas. Portanto, no NPM, obtemos pacotes para quase todas as funcionalidades que queremos adicionar em nosso aplicativo E o incrível é que todos esses pacotes podemos usar gratuitamente. Portanto, existem pacotes premium, mas é raro comprarmos pacotes. Na verdade, eu não comprei nenhum pacote até agora. Portanto, nesta seção, veremos comandos sobre como instalar pacotes diferentes. Também desinstalou pacotes, instalou dependências de desenvolvedores, atualizou alguns pacotes, etc. Portanto, nesta pequena seção, você se familiarizará com os comandos do NPM e não se confundirá com eles. Eles são extremamente simples e fáceis. Então, vamos começar esta seção. 18. Criando a embalagem: Então, como vimos na lição anterior, usamos quantos pacotes quisermos em nosso projeto. Agora, quando instalamos qualquer pacote, esse pacote tem vários arquivos e pastas, que baixaremos em nosso projeto e os armazenaremos em uma que baixaremos em nosso projeto e os armazenaremos em pasta chamada Node Modules. Agora imagine que instalamos dez ou 20 pacotes em nosso aplicativo. Todos esses arquivos serão armazenados nessa pasta de módulos do nó. Quando queremos compartilhar nosso projeto ou fazer o upload do nosso projeto no Github , não carregamos essa pasta de módulos do nó porque isso aumentará o tamanho do projeto e também aumentará o número de arquivos Portanto, não carregamos a pasta de módulos do nó. Agora você pode perguntar se não compartilhamos essa pasta de módulos do nó com alguém, como essa pessoa sabe quais pacotes precisa instalar. Para resolver esse problema em nosso projeto de nó, criaremos um arquivo chamado package dot JCN Nesse arquivo, os nós armazenam todas as informações principais sobre nosso projeto. Portanto, sempre que começamos a trabalhar em qualquer projeto de nó, primeira coisa que fazemos é criar Gs e arquivos empacotados para nosso Vamos ver como podemos criar o arquivo Gn do pacote. Então, aqui eu crio uma nova pasta chamada NPM Dash Commands e abro essa pasta no código vis Bom. Agora aqui, primeiro de tudo, temos que criar o arquivo GSN do pacote para isso, abrimos nosso terminal usando o Control Plus Batak, e aqui escrevemos NPM, init Veja, este utilitário o guiará na criação de um arquivo sn do pacote. Na parte inferior, ele pede o nome do nosso projeto. Se quiser alterá-lo , você pode escrever um novo nome aqui, mas certifique-se de usar letras minúsculas e também sem espaço. Estou feliz com esse nome atual, então simplesmente pressiono Enter. Depois disso, ele solicitará o nome da versão. Novamente, não queremos alterar esse valor padrão, então pressionamos Enter. Agora, aqui, podemos escrever a descrição do nosso aplicativo. Por enquanto, eu simplesmente pulo isso. Em seguida, temos o ponto de entrada, que é o nome de arquivo padrão do nosso projeto. Então, quando implantarmos nosso aplicativo, essa plataforma saberá qual é o arquivo principal do nosso aplicativo. Depois disso, temos o comando de teste, o repositório Git e, em seguida, a palavra-chave, o autor e a licença Pressione Enter para tudo isso e veja aqui que obtemos esse objeto que será adicionado ao pacote ao JCNFle e está perguntando: está tudo bem Se você concordar com esses detalhes , podemos simplesmente escrever aqui, y ou sim. E pronto. Veja, aqui temos o pacote JSnFle na pasta do nosso projeto. Se você abrir esse arquivo, veja, aqui obtemos esse objeto com detalhes do aplicativo e, no futuro, também podemos alterar esses detalhes. Agora, se você prestar pouca atenção, quando respondemos ao arquivo GSN do pacote, na verdade não mudamos nada e ainda temos que responder a todas essas perguntas Existe algum truque de atalho para isso? A resposta é sim, temos um atalho para criar pacotes e arquivos Aqui, vamos excluir os Gs e o arquivo do pacote atual. No terminal, anteriormente, escrevemos NPM nele Com isso, precisamos responder a todas essas perguntas. Mas se quisermos pular essas perguntas , escrevemos aqui NPM nele Y para todos, E pronto. Veja, recebemos novamente o pacote DSnfle em apenas um segundo E o objeto também é o mesmo. Resumindo, quando iniciamos qualquer novo projeto nodejs, primeiro precisamos criar o arquivo Gn do pacote com o comando init do NPM 19. Instalando o pacote no projeto: Na lição anterior, eu disse que esse arquivo GSN do pacote tem informações do aplicativo com a lista de pacotes, mas não podemos ver nenhum nome de pacote aqui É porque em nosso aplicativo, ainda não instalamos nenhum pacote. Então, vamos instalar alguns pacotes. Para isso, precisamos executar um comando no terminal. É muito simples. Só precisamos escrever a instalação do NPM, ou podemos usar aqui a abreviatura, que é apenas Aqui, escrevemos o nome do nosso pacote, digamos Express. Além disso, você receberá esse comando na página desse pacote no site do NPM Você também pode copiar a partir disso, e aqui pressionamos Enter. Veja em nossa pasta de projetos, obtemos a pasta de módulos de nós na qual todos os nossos pacotes de terceiros salvam seus arquivos e pastas. E se abrirmos isso, veja, aqui temos muitas pastas e muitos arquivos. Não se preocupe com isso porque, no mundo real, nunca abrimos essa pasta. Ou criamos essa pasta, excluímos essa pasta, mas nunca abrimos essa pasta, não se preocupe. Depois disso, também obtemos o ponto de registro do pacote JSNfle. Packageog dot JSNFle é usado para registrar dependências Em outras palavras, o ponto de registro do pacote jsNfle garante que todos os desenvolvedores e também o sistema de implantação usem a mesma versão do pacote para evitar problemas Além disso, não se preocupe com isso. Quase não tocamos nesse arquivo. E se virmos no pacote o ponto JCNFle aqui na parte inferior, obtemos uma nova propriedade chamada dependências e, nela, obtemos todas as nossas dependências Dependências são a base da qual nossos projetos dependem. Sem esses pacotes, nosso aplicativo não pode funcionar, e é por isso que o chamamos de dependência. Esta é a versão do nosso pacote Express. Se instalarmos outro pacote, esse pacote adicionará essa lista de dependências com sua versão Agora, esta versão é a versão mais recente que os desenvolvedores implantam no site do NPM Mas, às vezes, os desenvolvedores, por engano, implantam uma versão bloqueada ou uma nova versão, introduzem uma nova sintaxe Nesse caso, também podemos instalar versão mais antiga de qualquer pacote NPM Então, aqui no lado direito, temos a versão Stab Veja, aqui podemos ver a história completa desse pacote. Podemos instalar qualquer um desses pacotes. Suponha que queiramos instalar essa versão 4.18 0.1. Então, clicamos nessa versão. Ele abrirá sua página inicial para essa versão específica. E podemos ver aqui que a versão foi alterada e também o comando de instalação foi alterado. Eles adicionam o AdSign e depois escrevem a versão do pacote, simples assim Então, voltando ao código VS aqui, nossa versão atual é essa. Agora, copiamos esse comando deste site e simplesmente o colamos em nosso terminal de projeto e pressionamos Enter. A versão C foi alterada. Então é assim que instalamos pacotes com comando NPM I package name Além disso, aqui podemos adicionar vários nomes de pacotes. E se quisermos instalar versão específica , escrevemos NPM, nome do pacote no número vermelho da versão, e pronto É assim que é simples instalar o pacote no projeto node. E depois de instalar os pacotes, podemos começar a usá-los em todos os arquivos JavaScript deste projeto. 20. Desinstalando pacotes: Agora vamos ver como desinstalar o pacote. Mas antes disso, vamos instalar outro pacote chamado Mongo DB Diga-me qual comando usamos. Usamos NPM install ou I e, em seguida, escrevemos o nome do nosso pacote Mongo DB Você está indo muito bem. Neste pacote dot jCnfle, você pode ver outro pacote na dependência Vamos tentar desinstalar esse pacote. Para isso, precisamos escrever NPM, desinstalar ou também temos abreviatura para isso, que é ONU Em seguida, escrevemos o nome do nosso pacote, que é Mongo DV. Esse comando faz duas coisas. Primeiro, ele removerá esses arquivos e pastas de pacotes específicos da pasta de módulos do nó. Em segundo lugar, ele atualizará os arquivos de configuração, que são o pacote JSN e o packslogt Json Com isso, no futuro, nosso aplicativo não instalará pacotes desnecessários. 21. Instale o pacote como dependência do desenvolvedor: Agora, às vezes, em nosso projeto, queremos instalar o pacote apenas para usar no ambiente de desenvolvimento, não na produção. Por exemplo, temos alguns pacotes de teste que costumavam testar nossa implementação de código. Não precisamos de pacotes de teste em nosso ambiente de produção. Isso aumentará desnecessariamente o tamanho do servidor. No node Jazz, podemos instalar pacotes na dependência do desenvolvedor ou, em resumo, na dependência do dave, o que significa que o pacote só será adicionado em nosso ambiente de desenvolvimento, não na produção Então, em nosso aplicativo, vamos instalar um pacote de teste como dependência Do Para isso, escrevemos NPM. Aqui escrevemos o nome do nosso pacote, que é Mocha. Esse é o comando normal para instalar o pacote. Agora, para instalar o pacote como Do dependency, temos que adicionar a opção aqui, d s Dev e pressionar Enter Agora vamos verificar isso. Coloque o ponto do pacote JCNfle na parte inferior, podemos ver as dependências do desenvolvedor e, nele, temos nosso pacote Podemos instalar qualquer pacote como dependências de desenvolvimento, temos que usar o Dev no final do comando de instalação Mas lembre-se de que isso só adicionará ao ambiente de desenvolvimento. Além disso, se quisermos desinstalar pacotes de dependência dv , usamos o mesmo comando que vimos na lição anterior, NPM Uninstall ou nome do pacote UN, que é Mocha. E pronto. 22. Pacotes desatualizados e atualizá-los: Vamos ver alguns comandos úteis do NPM. Às vezes, em nosso aplicativo, instalamos alguns pacotes que podem ficar desatualizados e o NPM tem sua versão mais recente Por exemplo, nesta seção, instalamos a versão anterior do pacote Express. Agora, como podemos identificar quais pacotes têm atualizações? Para isso, temos um comando no NPM, que está desatualizado. Escrevemos NPM desatualizado e pressionamos Enter. E veja, aqui está a lista. Temos o nome do pacote. É a versão atual, desejada significa versão mais recente do pacote que satisfaz a faixa de versões. Versão mais recente, que é a versão mais recente da tabela desse pacote, location, que é a localização desse pacote, que está na pasta express que não é do módulo. Por fim, depende de qual projeto ou dependência depende desse pacote Com isso, podemos ver rapidamente quais pacotes estão desatualizados em nosso projeto. Agora, atualmente, temos apenas um pacote, mas imagine que estamos trabalhando em grande projeto antigo e aqui temos muitos pacotes desatualizados. Agora, para demonstrar isso, deixe-me instalar outro pacote com uma versão mais antiga. Escrevemos NPM install Mongo Debi na taxa 4,14 0,0. Pressione Enter. Bom. Agora, executamos novamente o comando desatualizado do NPM Veja, aqui temos nossos dois pacotes. Agora você pode se perguntar por que a versão desejada e a versão mais recente são diferentes? Qual é o significado disso? Como eu disse, queria fontes de coluna, que é a versão mais recente do pacote que satisfaz a faixa de versões. Atualmente, temos a versão 4.14 0.0 em nosso projeto. É relacionado apenas à gama de versões quatro. Por exemplo, 4,15 0,1, 4,16 0,0, 4,17 0,1 etc Esse tipo de versão é o intervalo de versão para 4,14 0,0, não 6,15 Mas você pode perguntar: qual é o problema de atualizar nossa versão para a versão 6.15 0.0 lets ? Nós podemos fazer isso. Mas quando os desenvolvedores alteram o número da versão, como a versão quatro para a versão cinco ou a versão seis , eles podem fazer algumas atualizações que podem causar erros no código antigo, de acordo com a versão 4.14 0.0 É por isso que sempre atualizamos nosso pacote para a versão desejada, não para a versão mais recente. Com isso, não interromperemos nosso aplicativo. Agora queremos atualizar todos esses pacotes desatualizados de uma só vez. Temos outro comando para atualizar pacotes desatualizados. O comando é NPM update. É isso mesmo. Ele atualizará todos os pacotes para sua versão mais recente dentro do intervalo específico, mas não atualizará dot Json e packago Json do pacote Veja, no pacote GSN, ainda temos nossa versão antiga chamada pacote Express Agora, até atualizarmos o pacote dot JSN ou packaglot JCNfle, não faz sentido instalar não faz sentido É necessário, precisamos atualizar os cães e o arquivo do pacote. Para isso, usamos outro pacote carregado no NPM, que é o NPM check updates Escrevemos NPM, I e aqui adicionamos G para instalar globalmente esse pacote em nosso sistema Nos outros aplicativos de nós, não precisamos instalar esse pacote. Ele estará disponível globalmente em nosso sistema. Aqui escrevemos o nome do nosso pacote, que é NPM check Updates Certifique-se de escrever o mesmo nome com traço, não com sublinhado Além disso, se você estiver usando MG, no início desse comando global, precisará adicionar um pseudo prefixo Caso contrário, você receberá um erro e depois disso, insira a senha do sistema. Agora podemos simplesmente executar as atualizações de verificação do NPM. Veja, ele verifica o pacote dot jCNfle e diz que nosso Express e Mongo DB Aqui está mostrando a versão mais recente, mas queremos atualizar nosso pacote com a versão desejada. Então, temos que escrever aqui NCU, que é a abreviatura de NPM check updates T para Target. Temos como alvo as versões menores, que são as desejadas. Isso retornará apenas as versões principais. Veja, aqui temos a versão desejada para os dois pacotes. Também na parte inferior, sugere executar o NCT minor para atualizar o pacote J e o arquivo Executamos atualizações de verificação do NPM ou podemos escrever NT, minor e pressionar Enter C, ele mudou a versão nos pacotes e no arquivo. Novamente, ele sugere executar o NPM install para instalar novas versões Escrevemos NPM install ou NPM I e pressionamos Enter e pronto. Todos os nossos pacotes são atualizados, é assim que identificamos pacotes desatualizados e como atualizá-los para sua faixa específica mais recente. Portanto, nosso aplicativo não interrompe com a nova versão do pacote. 23. Remova pacotes não usados do projeto: Às vezes, em nosso aplicativo, podemos instalar muitos pacotes no início do nosso projeto, mas alguns pacotes realmente não usamos, então podemos remover esses pacotes não utilizados porque isso ocupará espaço desnecessário na produção Então, esquecendo a lista de pacotes não utilizados, precisamos de outro pacote chamado DP check, que é a Então, escrevemos a verificação de profundidade do NPM IG. Novamente, estamos instalando esse pacote em nível global. Em todas as aplicações, podemos usá-lo. Além disso, se você for Mcuser, certifique-se de adicionar sudo no início do comando do pacote global e digitar a senha do sistema Agora você pode simplesmente executar here dep check, e ele retornará a lista de dependências não utilizadas e também de dependências dab não Atualmente, não usamos nenhuma dependência ou pacote. É por isso que todos os pacotes de terceiros não são usados. Ao usar o NPM uninstall ou o UN Express Mongo DB, podemos desinstalar todos os pacotes Ótimo. Agora, se verificarmos novamente, não teremos nada aqui, querida É assim que podemos remover pacotes não utilizados do aplicativo node Isso é tudo sobre o gerenciador de pacotes de nós ou NPM. Se você quiser revisar rapidamente o que aprendeu nesta seção, você receberá um resumo em PDF no final de cada seção, para que você possa baixá-lo e recapitular o que Agora, na próxima seção, começaremos a construir nosso primeiro projeto real No Js. 24. Seção 04 — API x API REST: Bem-vindo à quarta seção do curso definitivo de Node JS. Nesta seção, começaremos a trabalhar em nosso primeiro projeto. Então, começamos com o básico, o que é a API RS, configuramos nosso servidor usando o Express JS e, em seguida, criaremos diferentes tipos de solicitação STB, get, post, put e delete Além disso, vemos a validação de dados e muito, muito mais. Então, vamos começar esta seção. Agora, como sabemos, API significa interface de programação de aplicativos e é a maneira de dois programas se comunicarem entre si. Lembre-se do nosso exemplo de restaurante, vamos ver outro exemplo do mundo real. Imagine que o usuário queira se registrar em nosso site, então ele preenche o formulário e o envia. No momento em que eles enviam, chamamos a API para registrar um novo usuário e, no back-end, criamos um novo usuário. Assim, podemos criar muitas APIs para registrar o usuário existente, obter a lista de todos os produtos, adicionar produtos ao carrinho, excluir produtos do carrinho, etc Em palavras simples, a API é usada para transferir dados entre front-end para back-end e back-end para front-end. Nós já sabemos disso. Agora você pode perguntar o que é a API REST. API Rest significa API de transferência de estado representacional. A API Rest é uma forma específica de criar nossas APIs simples. Não se preocupe com o nome. É muito simples. API Rest é a mesma API, mas precisamos seguir algumas regras para criar essa API. Se seguirmos algumas regras, essa API simples se tornará a API restante. Agora vamos ver algumas regras que devemos seguir. Faça uma API restante. Uma regra é definir URL de API separada para cada dado. Por exemplo, suponha que estejamos criando uma API para operações relacionadas ao usuário, como registrar usuário, obter as informações de um único usuário, etc Nesse caso, nossa API deve ser nosso nome de domínio e, em seguida, cortar o usuário para registro E se quisermos obter informações sobre um único usuário , criamos uma URL de API como slash users 123 Aqui 123 é um ID exclusivo do usuário. Da mesma forma que se criássemos uma API relacionada a produtos , nosso URL deveria ser assim: barra produtos, barra produtos, barra 123, barra produtos, barra Adicionar ao carrinho, Então, simplesmente examinando essa URL da API, obtemos a ideia básica relacionada às nossas APIs e, com isso, podemos facilmente fazer alterações e manter nosso aplicativo limpo Outra regra são diferentes tipos de ações, como ler, adicionar, atualizar ou excluir dados Deve usar métodos específicos do SGDP. Agora você pode perguntar quais são os métodos do SGDP. Então, como sabemos, SDDP significa protocolo de transferência de hipertexto e permite que nosso front-end solicite e receba páginas da web e outros recursos de servidores Portanto, somente por causa do SGDP, podemos enviar e receber dados do back-end usando Agora, esse SDDP tem cinco métodos principais. Obtenha, publique, coloque, corrija e delte. Deixe-me explicar isso um por um. O primeiro é o método Get. Usamos o método Get quando queremos apenas obter dados do servidor. Por exemplo, queremos obter todos os detalhes dos usuários, ou queremos obter todos os detalhes dos produtos ou queremos obter detalhes únicos do produto. Nesse caso, definimos nossa API com o método GT. Para entender esses métodos, usaremos a analogia da biblioteca O método Get é como pedir a um bibliotecário que lhe mostre um livro ou vários livros Não se preocupe com a implementação. Veremos todos os métodos passo a passo nesta seção. Em segundo lugar, temos o método post. Usamos o método post quando queremos postar ou enviar alguns dados do front-end para criar novos dados em nosso servidor. Por exemplo, para registrar um novo usuário, precisamos enviar dados do usuário do front-end e isso criará novos dados em nosso servidor. Acho que é como se estivéssemos dando um novo livro para o bibliotecário no livro na biblioteca Em seguida, colocamos o método. Usamos o método Put quando queremos atualizar dados existentes no servidor com novos dados. Por exemplo, se você alterar as informações do seu perfil em um site e salvá-las, uma solicitação de venda será enviada para atualizar seu perfil com os novos detalhes. Acho que é como dar ao bibliotecário uma versão atualizada de um livro para substituir o antigo Em seguida, temos o método de página. Usamos o método de página quando queremos atualizar dados pequenos, não dados inteiros. Por exemplo, se quisermos atualizar apenas nosso endereço de e-mail em nosso perfil sem alterar mais nada, uma solicitação de página poderá ser usada. Acho que é como se estivéssemos dando ao bibliotecário apenas as páginas atualizadas de um livro para atualizar, em vez de substituir o livro inteiro Imagine, aqui temos um objeto de usuário em nosso servidor. Quer atualizar, completar este objeto de usuário e, em seguida, qual método usaremos, usamos o método put. E se quisermos atualizar apenas uma senha desse usuário , qual método usaremos, usaremos o método patch. Você está indo muito bem. O método put é usado para atualização completa de dados e o método patch é usado para pequenas atualizações nos dados existentes. O último método é excluir. E você adivinhou corretamente, usaremos o método delete para excluir dados do servidor. Por exemplo, quando excluímos uma publicação ou um comentário nas redes sociais , uma solicitação de exclusão é enviada para removê-lo do servidor. E para isso, não acho precisemos de uma analogia com a biblioteca, certo? Além disso, não é prático. É como pedir às bibliotecas que removam um livro da biblioteca. Você pode ver que os métodos do SGDB são muito simples. Usaremos esses cinco métodos do SGDP para definir nossos diferentes tipos de API Essas são apenas algumas regras que vemos atualmente, mas não se preocupe, aprenderemos todas essas regras à medida que criamos APIs Agora você pode perguntar por que precisamos da API REST. Por que precisamos seguir as regras para criar API? Seguindo qualquer regra, podemos organizar as coisas, e isso também vale para a API RS. As regras tornarão nossa API mais organizada. Além disso, seguindo as regras da API REST, criamos uma API simples e fácil de usar porque elas usam métodos SDDP específicos para realizar tipos específicos de Além disso, com as regras, podemos criar uma API limpa e sustentável, que qualquer desenvolvedor pode entender e começar a trabalhar nela Por enquanto, não se preocupe com as regras. Como eu disse, você aprenderá essas regras ao criar APIs Celeste começa a ganhar nosso primeiro projeto Node JS. Estou muito animada e sei que você também está. 25. Lista de API de planejamento para o Projeto 01: Agora, antes de começarmos qualquer projeto, é melhor planejar aproximadamente o projeto Ted. Então, como sabemos, nosso primeiro projeto trata de gerenciar a tarefa e, aqui, como é a aparência de seu front-end. Além disso, este é o primeiro projeto do meu curso React JS, e construiremos esse back-end do projeto como nosso primeiro projeto de back-end Não se preocupe, não vamos criar aqui um front-end porque nosso foco principal está no NodeJS e na construção do melhor back-end para Do front-end, só precisamos chamar as APIs. Agora você pode perguntar: como podemos planejar o projeto NodeJS? É muito simples. Esse é o método que usei para planejar meu projeto Bend, mesmo grandes projetos. Em vez de construir o projeto primeiro e depois fazer grandes modificações, é melhor gastar um pouco de tempo planejando antes de iniciarmos nosso projeto. Para o projeto Ben, se criarmos a lista de APIs, isso é muito útil porque o Bend tem quase tudo a ver com APIs Para este projeto, primeiro, precisamos da lista de todas as tarefas, uma API para obter todas as tarefas. Depois disso, precisamos criar API para adicionar uma nova tarefa e, depois disso, podemos atualizar os detalhes da tarefa única, uma API para atualizar a tarefa e, no final, precisamos excluir uma única para fazer, outra API para excluir uma tarefa específica. Atualmente, sabemos que precisamos dessas quatro APIs e criaremos duas, três APIs extras para a prática Se, durante a construção do projeto, precisarmos criar mais APIs , criaremos mais APIs Não há nada de errado nisso. Este é apenas um plano aproximado para reduzir a confusão. 26. Configure um novo aplicativo: Agora vamos criar um novo aplicativo para nosso projeto. Então, abra a pasta na qual você deseja criar o projeto, e eu a chamo faixa de tarefas e simplesmente abro essa pasta no código VS. Esse é o nome do nosso projeto. Isso soa bem? Espero que seja. Se você tiver um nome melhor , também poderá usá-lo. Depende totalmente de você. Agora, o que precisamos fazer para não criar aplicativos JS? Você se lembra que acabamos de fazer isso em nossa seção anterior? Sim. Simplesmente, abrimos nosso terminal e inicializamos nosso projeto usando o NPM nele. Para As, usaremos y aqui. Veja, obtemos o PGSnfle com alguma configuração padrão. Aqui, podemos ver que nosso arquivo principal é index dot js, que é o arquivo executado quando iniciamos nosso aplicativo. Vamos criar o arquivo index dot js e pronto. Aqui neste arquivo, escreveremos código para nosso back-end. 27. Crie um servidor usando o Express: Então, na seção anterior, criamos nosso servidor usando o módulo STTP O problema com o módulo STTP é que temos que definir nossos diferentes endpoints de API nessas instruções I e LSI, que não é muito claro e também não é fácil de manter para grandes projetos É por isso que usamos pacote ou módulo muito popular chamado express dot js. Express Dogs é mínimo e flexível para criar melhores aplicativos de nós. Em palavras simples, usando express dot js, podemos simplificar nossas rotas. Podemos lidar facilmente com solicitações e respostas do STIP, middlewares e Deixe-me te mostrar uma coisa. Aqui está o pacote Express no site da NPMJS. Você pode ver que seus downloads semanais são de quase 37,2 milhões, que é uma loucura e quase 90% dos desenvolvedores de projetos do NoDJS usam É muito importante o Master Express. Antes de tudo, vamos instalar esse módulo em nosso projeto. Abra o terminal, escreva e pressione Install Express. No momento em que estou gravando este curso, sua versão mais recente é 5.1 0.0. Se você quiser ter a mesma experiência que eu estou tendo, então você pode escrever aqui NPM install Express aerate 5.1 0.0 e pressionar Enter Não se preocupe com o Express. É um pacote muito simples. D. Agora queremos usar esse módulo Express neste arquivo js de índice. Você pode me dizer o que temos que fazer? Certo, inseriremos o módulo expresso usando a função require, express, e essa função necessária retornará uma função. Nós simplesmente o armazenamos em uma variável chamada express. Agora, para criar um aplicativo expresso, chamamos essa função expressa aqui, que retorna um objeto e o armazenamos em uma variável chamada aplicativo ou aplicativo. Você pode dar a ele qualquer outro nome, mas provavelmente todos os desenvolvedores o chamaram de app. Vamos usar o aplicativo. Agora, neste objeto de aplicativo, temos muitos métodos úteis. Por exemplo, temos aqui app dot get app dot post, app dot pot. App dot patch, app dot DLD, etc. Você se lembra de onde vemos esses cinco métodos? Eles são métodos SDDP para criar diferentes tipos de API Se quisermos definir nossa API para o método sddPgt , usamos app Se quisermos definir o método de exclusão do SDDP, usamos o app dot Da mesma forma que podemos criar solicitações de post, put e patch. A forma de definir todos esses cinco métodos é a mesma. Ainda assim, veremos todos os métodos nesta seção, um por um. Por enquanto, vamos começar com a solicitação do GAD. Nesse método GAT, no primeiro parâmetro, precisamos escrever o nome do endpoint da API Suponha que queremos definir a API G para URL, SGDP, coluna de barra dupla, host local, coluna 3.000 Agora, qual é o nosso endpoint nesse URL? O Tudos é nosso endpoint de API Isso é o que temos que escrever aqui no primeiro parâmetro. Certifique-se de adicionar a barra de Edward primeiro. Caso contrário, isso não funcionará corretamente. Agora, e se quisermos definir a API get para URL, SDDP, barra dupla, coluna localizada 3.000, que é a URL raiz do Nesse momento, podemos aderir apenas à barra frontal, que representa o ponto final da raiz Agora temos que definir o que acontecerá quando nosso front-end enviar solicitações para o endpoint. Você se lembra, deixe-me te mostrar. Aqui, passamos a função de retorno de chamada e, nela, obtemos dois objetos, solicitação e resposta Essa solicitação tem todos os detalhes sobre solicitação de URL e, com esse objeto de resposta, podemos enviar detalhes relacionados à resposta. Já vimos isso na aula do módulo STP. Agora, o que queremos enviar quando alguém envia uma solicitação nessa API. Por enquanto, simplesmente retornamos um projeto SEND Task Track com pontos de resposta em texto. Quando alguém envia uma solicitação Get nesse endpoint, essa função é executada e, em seguida, ela simplesmente retorna esse texto em resposta, simples como definido Por essas duas linhas, nosso servidor Express é criado, mas temos que executar ou escutar esse servidor em alguma porta. Se não ouvirmos nosso servidor , nossa API não funcionará. Aqui no final, escrevemos o app dot L ISE e simplesmente aqui passamos nosso número de porta no segundo parâmetro, passamos novamente a função Callback, que será executada quando nosso servidor começar a escutar nessa porta Aqui, podemos simplesmente consolar servidor de log de pontos está em execução ou escutando nesta porta 3.000 Salve as alterações e vamos executar nosso arquivo index dot js. Modo de gravação, ponto de índice js. O servidor C está escutando na porta 3.000. Agradável. Agora, volte ao navegador e execute a coluna 3.000 do host local, que é a URL raiz Veja aqui que obtemos o texto do projeto Task Track, que enviamos do nosso servidor Você pode ver que o Express torna nosso código muito simples. Podemos comparar nosso código atual com o código anterior do módulo SGDP O Express torna isso muito simples. Além disso, essa é nossa primeira API. É por isso que escrevemos apenas texto em resposta. Agora, à medida que avançamos em nosso projeto, verdadeira emoção começará 28. Exercício para criar servidor expresso: É hora de fazer um pouco de exercício. Quero que você remova todo o código do arquivo JS de pontos de índice e crie novamente o servidor Express e crie uma API para raiz e ponto. Com este exercício, você se familiarizará com a criação de servidores Express. Literalmente, levará apenas 1 minuto. Tente concluir este exercício e depois observe a solução. Ok. Espero que você resolva o exercício ou tenha tentado resolver isso. Agora vamos ver a solução. Primeiro de tudo, precisamos do módulo Express em nosso arquivo. Exija o Express e armazene-o em uma variável chamada Express. Esse expresso é uma função, então nós o chamamos aqui e ele retornará nosso objeto de servidor ou objeto de aplicativo. Então, vamos armazená-lo em uma variável chamada app. Aqui, criamos nosso servidor Express usando essas duas linhas, mas precisamos ouvir nosso servidor somente para poder executar nossa API. Então, no final, simplesmente adicionamos app dot Lisen e no primeiro parâmetro, o que passaremos? Certo, passamos pelo porto, que é 3.000. E no segundo parâmetro, passamos a função de retorno de chamada e, dentro dela, o servidor de log de pontos do console está sendo executado na porta 3.000 Uma coisa é que eu escuto o servidor antes de adicionar API porque muitas vezes eu esqueci de ouvir o servidor, e isso vai perder muito tempo Eu sempre escuto o servidor assim que crio o servidor. Agora, no meio, podemos definir qualquer coisa em nossa API. Então, para a solicitação Get, adicionamos app dot GAT Primeiro, adicionamos nossa API e ponto e, em seguida, no segundo parâmetro, adicionamos a função de retorno de chamada, que tem dois parâmetros, solicitação e resposta Dentro desse retorno de chamada, simplesmente enviamos texto usando o ponto de resposta SNG Este é o projeto Task Track. Salve as alterações e aqui temos que parar nosso aplicativo do terminal porque ele ainda está executando o código antigo. Novamente, executamos o arquivo node index dot js. Veja, o servidor está ouvindo e, em nosso navegador, recebemos o texto atualizado, muito simples. 29. Criando uma API para obter a lista de todos: Agora vamos criar uma API para obter todas as listas de tarefas. Você pode me dizer qual método SDP devemos usar? Certo, para obter os dados do servidor, usamos o método Get DP. Então, aqui escrevemos o app dot GT. E digamos que queremos dar a essa API o nome de todos. Então passamos aqui slash todos, e depois disso, no segundo parâmetro, passamos a função callback, que tem dois parâmetros request e response Veja, para todas as APIs, essa estrutura permanecerá a mesma Somente essa alteração no método SDP, essa alteração no endpoint e a lógica dentro dessa função web de chamada mudarão lógica dentro dessa função web de chamada mudarão É assim que o Express JS torna nosso projeto simples e limpo. Agora, atualmente, não vamos trabalhar com um banco de dados porque não queremos adicionar complexidade extra ao nosso primeiro projeto. Aprenderemos todas essas coisas passo a passo. Portanto, não se preocupe com o banco de dados. Agora, aqui, temos que enviar toda a matriz todos. No topo, eu defino um dummidata chamado matriz todos e simplesmente adiciono alguns todos nele Aqui, cada tarefa é um objeto com quatro propriedades. ID, vamos citá-lo para uma tarefa, que é um texto de tarefa. Vamos criar todas as APIs para o projeto um. Tags, que são as tags relacionadas à tarefa, que é uma matriz, não apenas vírgula JavaScript. E status a fazer. Essas propriedades, ID, tarefa, tags e status são definidos por noches developer, o que significa como você quer chamá-las, quantas propriedades você precisa, essas coisas você tem que decidir com base em quais dados queremos armazenar e quais dados não queremos Agora vamos duplicar esse objeto mais duas vezes usando Sift mais alter mais seta para baixo ou Sift mais Option mais seta para baixo Sift mais Option mais Alteramos esse ID para duas tarefas para criar EPI para uma lista de todas as tags a fazer, sem Js e status de fazendo Por fim, simplesmente alteramos o ID para três tarefas para planejar o projeto um, o texto JavaScript e o status para concluído. Deseja simplesmente retornar essa matriz como resposta quando alguém envia uma solicitação Gut para a API , que reduz todos e Point O que escrevemos aqui, escrevemos o ponto de resposta SN e simplesmente passamos nossa matriz todos. Salve as alterações e vamos verificar se essa API está funcionando ou não. Abra o terminal, feche o servidor em execução atual usando Control plus C e execute novamente esse arquivo. Agora, no navegador no local do site raiz, simplesmente chamamos slash Todos e Point Veja, aqui temos nossa matriz. É muito simples enviar dados do back-end usando a API G. 30. Configuração do reinício automático do nodemon: Atualmente, quando fazemos alguma alteração em nosso projeto, precisamos fechar nosso servidor em execução anterior e reiniciar nosso aplicativo, o que é realmente irritante Para reiniciar automaticamente nosso aplicativo, temos um pacote chamado nodemon É muito útil. Abra o terminal e escreva NPM install ou IG nodemon. Aqui, usamos o DSG para instalar esse pacote Norman globalmente Caso contrário, teremos que instalar o nor moon em cada projeto de nó. Além disso, se você estiver usando Mac, para instalar o pacote global, você precisará escrever sudo no início do comando e, em seguida, ele solicitará a senha do sistema Agora, como podemos executar o arquivo usando o nó um? Deixe-me te mostrar. No terminal, anteriormente, estávamos executando o arquivo usando node, index dot js. Agora, para o nod M, escrevemos nodemon index dot js. Simples assim. Veja, aqui temos nossa versão do nó M. Ou reiniciando, podemos entrar no RS. Além disso, está nos dizendo que estamos assistindo Path period, o que significa a raiz desse projeto. Depois disso, ele está assistindo extensões como Js, MGs, Cgs, JSON etc Um arquivo que tem esse tipo de extensão, Nod moon está constantemente observando esses arquivos e, se algo mudar nesses arquivos, ele reiniciará nosso aplicativo No final, veja, o nodemon também está executando o Command node index dot js Ao usar o nodemon, não precisamos reiniciar nosso aplicativo Ele será reiniciado automaticamente quando alterarmos algo nesses arquivos com essas extensões. 31. Variáveis de ambiente: Agora, atualmente, estamos configurando manualmente o pod do nosso servidor. Mas no mundo real, esse pod é definido pelo ambiente em que nosso aplicativo está sendo executado. Especificamente, ele é gerenciado pelo provedor de hospedagem ou plataformas de desenvolvimento como render, Heroku, AWS etc. Quando implantamos nosso aplicativo, nessas plataformas, nossa porta de 3.000 pode já estar sendo usada por outro servidor No momento, se codificarmos nossa porta , nosso servidor não funcionará nessa porta e isso nos causará um erro na implantação Então, qual é a solução aqui? É muito simples. Verificaremos uma condição. Se em nosso ambiente de aplicação, variável de porta estiver definida, usaremos essa variável de porta, caso contrário, usaremos nossa porta codificada Deixe-me mostrar que é muito simples. Então, aqui, antes de escutarmos nosso servidor, criamos uma variável chamada port equals to now aqui, como podemos verificar se nosso servidor tem porta em seu ambiente ou Então, para isso, temos um objeto chamado ponto de processo ENV. Este ENV é para o meio ambiente. Nesse ambiente, obtemos todas as variáveis que são definidas pelas plataformas de hospedagem e porta para a variável Port. Portanto, se alguma plataforma de hospedagem quiser definir uma porta diferente , ela armazenará essa variável de processo dot Env dot port Essa é uma convenção comum. Além disso, todos os nomes de variáveis de ambiente são todos em letras maiúsculas, e é por isso que também damos esse nome de variável como porta totalmente maiúscula. Então, só de olhar para isso, sabemos que pode ser uma variável de ambiente. Se essa porta ponto nw do processo estiver disponível, não há problema Mas se não estiver disponível ou definido, teremos que passar nosso valor de porta codificado Adicionamos nosso operador, que é o símbolo par duas vezes, é a chave acima de enter ou return Aqui passamos pelo nosso porto, que é de 3.000. Agora vamos passar essa variável de porta no lugar dessa porta codificada e também alteraremos essa mensagem do console Vamos criar essa string como string de modelo usando acti porque em strings de modelo, podemos acessar facilmente a variável e alterar essas 3.000 com colchetes de dólar Se essa porta de ambiente estiver disponível, usaremos ou, se for falsa ou nula, usaremos essa porta de 3.000 Simples assim. Atualmente, em nosso aplicativo, porta do ambiente não está definida. É por isso que nosso aplicativo será executado continuamente na porta 3.000 Não se preocupe se você estiver um pouco confuso sobre esse processo dot ENV, veremos isso em detalhes nos próximos projetos Deixe-me dar um atalho para configurar o aplicativo Node Primeiro, exigiu o Express, criar o aplicativo expresso, criar essa variável de porta usando essa expressão e escutando o aplicativo expresso na porta. Essas quatro coisas permanecerão as mesmas em todos os aplicativos de nós. Sim, podemos adicionar mais funcionalidades em outras linhas, mas nada mudará nessas quatro linhas. 32. Parâmetros de rota e parâmetros de consulta: Anteriormente, criamos uma API para obter a lista de tudo o que fazer em nosso aplicativo. Mas e se precisarmos obter informações sobre apenas uma pessoa, como fazer com a identificação um ou a identificação três. Para isso, precisamos passar o ID no URL da API. Nosso APIURL tem essa aparência. Todos ON, o que significa que queremos buscar uma para fazer informações cujo ID seja um tipo de variável que passamos em nossa URL é chamado de parâmetro de rota. É muito importante fornecer informações específicas sobre a solicitação da API, como ID, status, data, qualquer coisa. Deixe-me mostrar como podemos definir esse tipo de URL da API e acessar os parâmetros da rota. Adicionamos um novo endpoint da API GAT para slash todo slash. Agora, aqui para definir o parâmetro de rota, usamos dois pontos e damos o nome da nossa variável de rota como ID Esse ID é nosso parâmetro de rota. Podemos chamá-lo de qualquer coisa como fazer ID, mas ID é curto e agradável, então usamos ID e pronto. É assim que podemos definir o parâmetro de rota em nossa URL da API. Vamos acessar esse parâmetro de rota em nossa lógica de API. Novamente, aderimos à função de retorno de chamada com dois parâmetros, solicitação e resposta Agora, dentro dessa função, o que você acha? Em qual objeto, obtemos informações sobre nosso parâmetro de rota, solicitação ou resposta. Oito. Recebemos informações sobre o parâmetro de rota na solicitação. Portanto, solicite PAMs de pontos. Neste objeto perms, obteremos todos os parâmetros da rota e poderemos acessá-los por ID de ponto Veja, aqui também recebemos sugestões automáticas. Agora, vamos simplesmente enviar esse ID em nosso ponto de resposta, salvar as alterações e voltar para o nosso navegador. Vá até o host local, Coluna 3.000, para cortar um S, aqui obtemos o ID Estamos obtendo o parâmetro de rota com sucesso . Agora, aqui está uma coisa. Também podemos passar vários parâmetros de rota em nossa API. Por exemplo, podemos passar o status da tarefa para todo. Agora, no back-end, adicionamos aqui parâmetro de rota. Como podemos fazer isso? Certo. Adicionamos o status slash Clan e como podemos acessar o parâmetro de rota Certo. Usamos request dot Perms dot status Deixe-me mostrar a você toda a rota do objeto Perms. Salve as alterações e, de volta ao navegador, passamos aqui o valor do status após o valor do nosso ID. Certifique-se de que o pedido seja o mesmo que definimos em nossa API, o que significa primeiro ID e depois status. Veja aqui que obtemos o objeto params com essas duas propriedades que definimos na API Agora você pode ter curiosidade. E se não passarmos o status aqui? Vamos ver isso também. Remova o valor do status e veja, aqui não conseguimos fazer nada, que significa que nosso servidor não encontrou a ABI com essa URL Se definirmos parâmetros de rota em nossa API , certifique-se de que passaremos todos os parâmetros de rota na ordem correta. Há outra forma de passar dados em URL, que é usando parâmetros de consulta. Se você estiver usando sites, então, em URL, você pode ver um ponto de interrogação e seguida, passar alguns tipos de variáveis, como tiro igual à data e ordem igual a um C para ascendente Esses são os parâmetros de consulta usados para passar dados em URL. Agora você pode perguntar: qual é a diferença entre parâmetros de rota e parâmetros de consulta? Eles são usados para passar dados em URL, mas os parâmetros de rota são usados para passar dados que são mais necessários, enquanto os parâmetros de consulta são usados para transmitir dados, que são adicionais ou opcionais. Em palavras simples, em nossa API, se o front-end não passar os parâmetros de rota , nossa API nos dará um erro. Mas se não passarmos os parâmetros de consulta , nossa API não nos dará erro. É um detalhe adicional. Por exemplo, se não passarmos todo ID ou status , isso nos dará um erro de que a API não foi encontrada. Mas se não passarmos essas variáveis após o ponto de interrogação , não obteremos erro. Agora, deixe-me mostrar como podemos acessar os parâmetros de consulta em nossa API. Para isso, não precisamos alterar nada na URL da API. E acesse-os diretamente em nossa função de retorno de chamada. Para o parâmetro de consulta, temos outro objeto na solicitação, que é a consulta de pontos de solicitação, e pronto. Não precisamos fazer nada em nosso endpoint. Salve as alterações e dê uma olhada. Veja, aqui temos o objeto de consulta. Os parâmetros de ponto de solicitação são usados para parâmetros de rota e a consulta de pontos de solicitação é usada para parâmetros de consulta Nós os usaremos muito quando criarmos APIs complexas. Eles são muito úteis. 33. Obter um único resultado por ID: Agora vamos ver como podemos retornar single to do pelo seu ID. Para isso, o que usamos como parâmetro de rota ou parâmetro de consulta, usaremos o parâmetro de rota porque essa informação é a mais necessária. Então, removemos esse status de classe do nosso endpoint, não precisamos dele Na função Colvey, precisamos retornar o single to do, cujo ID é igual ao ID do nosso parâmetro de rota Primeiro de tudo, vamos armazenar o parâmetro de rota em uma variável separada. Então, Cs para fazer ID é igual a, como podemos acessar os parâmetros da rota Solicitamos o ID dos parâmetros de ponto. Agora temos que encontrar um único ID para fazer nossa matriz todos, cujo ID seja o mesmo que esse ID para fazer. Que usamos um método de matriz JavaScript, que é find. Todos a matriz dot find, e dentro desse método fino, passamos a função de retorno de chamada, e aqui no parâmetro, obtemos o único objeto a fazer. Então esse T é esse único objeto na matriz Tds E retornamos aqui uma condição se t ID for igual ao nosso ID de tarefa. Se você não conhece esse bom método, deixe-me explicar resumidamente porque é puro conceito de JavaScript. Portanto, esse método fino verificará nossa matriz Tudos e, primeiro, escolherá o primeiro objeto da matriz nessa variável T e, em seguida, verificará a condição O ID de ponto T é o mesmo que o ID de onde fazer. Se for verdade, esse método fino retornará esse único objeto. Por isso, armazenamos contras invariáveis para fazer. R, se essa condição não for satisfeita, ele definirá T como próximo objeto e, em seguida, verificará novamente a condição. E é assim que podemos encontrar uma única coisa para fazer usando esse método fino. Vamos enviar isso para fazer no método SN de ponto de resposta. Salve as alterações e dê uma olhada. Vamos remover esses parâmetros de consulta e, portanto, o valor do status, e aqui não obtemos nada. Por quê? Passamos o ID um e, em nossa matriz de tarefas, também temos que fazer com o ID um. Então, o que está errado? Vamos tentar consolar a única tarefa. Fez as alterações e atualizou a página no navegador. Agora, em nosso terminal VSCO, onde estamos executando nosso servidor, temos nossos Veja, aqui ficamos indefinidos. Portanto, não podemos encontrar todo em nossa matriz de todos, e esse é o erro. Esse erro pode ocorrer porque não estamos comparando os IDs corretamente. Também vamos tentar consolar esse tipo de ID de tarefa usando o tipo de ID do. Isso retornará o tipo de ID da tarefa, salvará as alterações e atualizará a página Volte ao código do VS e veja, aqui temos indefinido para single to do, e obtemos o tipo string what to do ID É por isso que não estamos conseguindo fazer o single, porque aqui nosso ID de tarefa é inteiro e estamos comparando-o com a string Portanto, temos que converter essa string de ID Td em número inteiro. Assim, podemos agrupar essa solicitação dot perms dot ID com parse função Pass integer converterá nossa string em número inteiro Salve os anéis e dê uma olhada. Atualize a página e veja, aqui temos o objeto único para fazer com ID um Se passarmos aqui o ID três, então chegaremos aqui para fazer com o ID três, então está funcionando. Bom. Agora você pode perguntar no parâmetro route, estamos passando um como número inteiro Mas por que na parte de trás pegá-lo como uma corda? Então, a verdade é que tudo o que passamos na URL, é passado como string. Então, se quisermos passar algo como inteiro, temos que convertê-lo no back-end Não podemos passar valores inteiros usando o parâmetro route, e isso também vale para parâmetros de consulta Portanto, lembre-se sempre de definir rota ou parâmetros de consulta , você deve converter seu valor usando o método parse integer ou parse Eu crio esse erro intencionalmente para mostrar o que pode acontecer. Criamos a API e o ID Xs no parâmetro de rota 34. API POST para adicionar um novo Todo: Agora vamos criar uma API de postagem para adicionar um novo objeto pendente. Como sabemos, para criar novos dados no servidor, usamos a API de postagem. Também na solicitação posterior, front-end enviará dados para o servidor. Por exemplo, aqui criamos uma API de postagem para adicionar uma nova tarefa. Portanto, nosso front-end enviará detalhes sobre as tarefas, como tarefas , tags e status, no corpo dessa solicitação. Com essas informações, como podemos adicionar um novo todo em nossa matriz de todos? Não se preocupe, deixe-me mostrar isso na prática. Então, aqui definimos a API post usando app dot post e, no primeiro argumento, passamos nosso endpoint Vamos passar slash todos no segundo argumento, passamos a função de retorno de chamada com dois parâmetros, solicitação e resposta Agora você pode perguntar que esses dois pontos finais são iguais. Como podemos usar essas APIs individualmente? Então, aqui podemos ver que essa API usa o método Get, e a segunda API usa o método post. Quando o front-end enviar solicitação de API nesse endpoint com o método G, essa função será executada e, se o front-end enviar a solicitação de API no mesmo endpoint com o método post, essa função será Veremos como enviar uma solicitação de postagem em apenas um minuto. Agora, como sabemos do front-end, enviamos dados no corpo da solicitação e como podemos obter informações relacionadas à solicitação nessa função? Podemos usar esse parâmetro de solicitação. Nessa solicitação, obteremos todas as informações sobre essa solicitação específica. Aqui temos uma solicitação e, nessa solicitação, temos uma propriedade chamada corpo. Esse corpo tem todos os dados que o front-end envia com a solicitação, que é nosso objeto todo, nós os armazenamos em uma variável chamada todo. E depois disso, basta consol dot log this todo, e também responder dot send this to do Agora, vamos provar, estamos obtendo dados em nossa variável todo ou não. Anteriormente, enviávamos uma solicitação Get simples do URL do navegador porque, por padrão, o navegador envia a solicitação Get para o URL, mas não podemos enviar outro SDDPRquest usando Para isso, precisamos de um código de front-end, podemos usar um software de degustação de API, como o Postman, ou também podemos usar uma extensão de código VS chamada cliente Thunder A partir dessas três opções, a instalação da extensão VSCode é muito mais fácil Portanto, neste curso, provavelmente usaremos o cliente Tender e Postman porque estamos experimentando a API avançada, precisamos Mas não se preocupe, as duas interfaces são iguais. O principal é que devemos poder experimentar nossa API, simples assim. Vá até a extensão final a partir daqui, pesquise o cliente Thunder e instale Agora, em nossa lista de painéis, esse ícone de cliente de licitação foi adicionado. Então, vamos abri-lo. E aqui podemos experimentar nossas APIs para nosso projeto. Então, primeiro, inserimos nossa URL de API, que é SDDP, coluna de barra dupla , host local, coluna 3.000, barra coluna 3.000 E de qual método precisamos, precisamos do método post. Então, selecionamos post a partir daqui e agora temos que passar Todo Object no corpo da solicitação. Então, para isso, selecionamos aqui o corpo e na opção JSON, aqui vamos passar nossos dados no objeto O primeiro campo que precisamos é tarefa. Temos que passar o nome do campo em códigos duplos e também temos que passar o valor em códigos duplos. Essa é uma nova tarefa. Além disso, se você não consegue ver esses preenchimentos corretamente, feche este penal usando Control plus B ou Command plus B. Depois disso, precisamos de outro campo que seja tags, e passamos aqui array, e nele passamos dois valores SGML Status e valor do último preenchimento, digamos, a ser feito. Agora, aqui está uma coisa. Esse nome de preenchimento, que é essa tarefa, status fiscal, esses nomes são definidos pelo desenvolvedor de back-end Qualquer que seja o nome definido pelo desenvolvedor do Bend, o desenvolvedor front-end deve enviar dados com o mesmo nome de campo. Caso contrário, como no back-end buscamos dados do corpo da solicitação Para enviar esta solicitação de postagem, clicamos no botão Enviar. Veja, não recebemos nada e, se verificarmos nosso terminal , também ficaremos indefinidos Por que não estamos recebendo os dados em nosso objeto de corpo de ponto de solicitação, o que estamos fazendo de errado. Quando o front-end envia uma solicitação de postagem, ele envia dados no corpo da solicitação no formato JCN, e foi isso que também fizemos em nossa solicitação de teste Por padrão, o servidor Express não sabe como ler e entender automaticamente esses dados JSN Para o Express, precisamos um tradutor que converta esses dados JSN em um objeto Javascript simples porque não podemos trabalhar diretamente com dados JSN Precisamos convertê-lo em objeto ou matriz, que nosso Javascript possa entender. Para isso, temos um middleware no Express, que funcionará como tradutor Então, depois da variável todos a, adicionamos app dot U e, nessa variável, chamamos nosso middleware express dot JSN e pronto Certifique-se de adicionar esse middleware antes de nossas APIs e também chamar isso de express dot JS Caso contrário, não funcionará. Atualmente, sem esse middleware GSN de ponto expresso, estamos obtendo o corpo do ponto de solicitação Agora vamos salvar as alterações e, novamente, enviar a solicitação de postagem. Veja, agora obtemos o corpo do ponto de solicitação, mesmo que enviamos esse objeto. Portanto, essa é a importância do middleware Express Dot JSn. Agora, basta adicionar esse novo todo em nossa matriz de todos. Então, usamos aqui um método de matriz simples, todos array dot push. Isso adicionará novos dados na última posição da matriz. E aqui no método push, passamos o objeto porque todas as nossas tarefas estão no objeto, e temos que seguir a mesma estrutura do objeto para que o novo faça. Então, primeiro de tudo, precisamos de um ID e como podemos obter o que não o passamos pelo front-end. Então, para identificação, podemos fazer algo assim. Conseguiremos o último a fazer o ID e aumentá-lo em um. Então, para obter a última coisa a fazer da lista, escrevemos a matriz todos no pacote quadrado todos array dot Length, que atualmente é três Mas sabemos que o índice da matriz começa com zero. Então, temos que fazer aqui o comprimento menos um. Portanto, essa matriz Tds entre colchetes, comprimento do ponto da matriz Tds menos um é nosso último objeto a ser e queremos acessar Então, adicionamos aqui o ID e simplesmente o aumentamos em um. Então, se o comprimento da nossa seta for três, então três menos um, que é dois, que é o índice do último elemento E então acessamos seu ID e aumentamos em um, que é quatro, simples assim. Em seguida, preenchemos a tarefa e passamos o valor que obtemos do corpo do ponto da solicitação e para acessar a tarefa e a tarefa do ponto. Em seguida, temos texto e passamos valor para texto de pontos. Por último, temos status, que é o quê? Nós devemos fazer o status de pontos. Agora eu acho que isso pode confundir você. Definimos esse objeto Nut separadamente. C Nu todo é igual a passar isso aqui. E no método push, simplesmente adicionamos essa nova tarefa. Acho que isso parece mais claro. Além disso, uma coisa que eu quero dizer em qualquer API no final da função de retorno de chamada que devemos na resposta dot sg Caso contrário, em nosso front-end, nossa solicitação continua em execução, que faz com que nossa velocidade geral diminua. Portanto, certifique-se de que, em cada API, retornemos algo. Você pode perguntar: o que devemos devolver da solicitação de postagem? A partir da solicitação de postagem, podemos retornar dados adicionados recentemente em nosso servidor no banco de dados. Portanto, nosso front-end obtém todas as informações, como identificação, e as usa como quiser. Então, aqui, simplesmente retornamos essa nova tarefa, salvamos as alterações e damos uma olhada, enviamos a solicitação novamente e vemos agora que estamos recebendo dados com o ID quatro. Se obtivermos tudo o que fazer na solicitação Get, C, obteremos quatro tu dos Então, criamos com sucesso uma solicitação de postagem e adicionamos o novo Tudo em nossa matriz de Tudos Vamos recapitular rapidamente o que aprendemos nesta lição. Então, usamos a solicitação de postagem para criar novos dados no servidor e obtemos esses novos dados do corpo da solicitação de postagem enviada pelo front-end. Para provar isso, usamos essa extensão de cliente de licitação e enviamos nossos dados no JCNFmat que é o formato comum Agora, no back-end, precisamos converter esses dados em um formato Javascript simples, e é por isso que usamos Express D JCNMddleware e os adicionamos Sem esse Express dot JCNMddleware, estamos recebendo o corpo do ponto da solicitação Depois disso, adicionamos os novos dados em um objeto separado com todos preenchidos e, em seguida, simplesmente os inserimos na matriz de Tudou e, no final, retornamos os novos dados adicionados do ponto de resposta SN Simples assim. Agora, na próxima lição, melhoraremos essa solicitação de postagem. 35. Como validar dados do usuário: Atualmente, nosso front-end está enviando os dados que eles desejam enviar. Mas e se alguém não enviar os dados necessários, como texto do Tas, matriz de texto ou status. Sem eles, não podemos adicionar dados incompletos em nosso armazenamento. É ruim para nosso aplicativo. Então, nessa condição, temos que adicionar validação de dados em nossa API. Portanto, no início de nossa API, verificaremos se o front-end está passando todos os dados necessários ou não. Se não estiver transmitindo os dados adequados , interrompemos a solicitação imediatamente com a mensagem de erro adequada. Deixe-me mostrar o que quero dizer. Aqui, depois de obtermos os dados do corpo do ponto da solicitação, adicionamos uma condição simples. Se a tarefa todo dot não estiver disponível, retornaremos o erro daqui. Portanto, nos colchetes de Cali, escrevemos que a tarefa de envio de pontos de resposta é necessária Agora, aqui está uma coisa. Mesmo se escrevermos aqui response dot send, nosso código restante também funcionará. Para parar de executar o código a partir daqui, temos que adicionar here return. Sem esse retorno, nosso código restante será executado de qualquer maneira. Não se esqueça de adicionar devolução. Agora vamos duplicar isso que eu bloqueio mais duas vezes usando Sift plus alter mais seta para baixo ou Sift plus opção mais seta para baixo Sift plus opção mais Agora, simplesmente alteramos a condição do texto para fazer texto com pontos e alteramos a mensagem de erro. Os textos são obrigatórios. E, finalmente, para fazer o status de ponto, o status é necessário. Além disso, aqui podemos verificar mais condições, como o texto deve ser uma matriz ou o valor da tarefa deve ter mais de três caracteres, etc Por enquanto, não queremos essa complexidade, então vamos experimentar essa implementação. Salve as alterações, abra o sabor da postagem e simplesmente removemos esse preenchimento de tarefas. Envie a solicitação e veja, aqui estamos recebendo esta mensagem. A tarefa é obrigatória. Linda. Agora, front-end, só precisa exibir essa mensagem de erro no formulário ou em qualquer lugar que eles queiram exibir. Dessa forma, podemos validar manualmente nossos dados de campos de entrada Mas esses são apenas três preenchimentos. Imagine que temos de sete a oito campos e, para cada campo, queremos validar os dados Então, temos que escrever isso se a condição for sete a oito vezes. Existe alguma outra maneira de fazer isso? Sim. Tenha uma biblioteca especial para validar os dados do usuário A primeira é alegria. Essa é uma das bibliotecas de validação de dados mais populares e robustas em node JS, e também usaremos joy para validação de dados neste curso. Além disso, há outra biblioteca como yap e validator dot js Você pode usar qualquer uma dessas bibliotecas. Pessoalmente, gosto da alegria e usaremos a alegria no próximo projeto. Atualmente, nosso foco principal é criar APIs coletivas, o que significa criar, ler, atualizar e excluir APIs 36. Passagem do código de status: Agora, quando retornamos um erro do servidor, é melhor também passarmos o código de erro com essa mensagem de erro. Por meio desse erro ou código de status, nosso front-end obtém informações sobre o sucesso ou a falha do SDDPRquest Talvez você já saiba disso ou talvez tenha visto esse erro. Por exemplo, quando não encontramos uma página da web, você sabe que alguns sites exibem uma página 404 não encontrada Esse 404 é o código de erro ou status de não encontrado. Veja o erro ou o código de status mais comum do SDDPRquest. O primeiro é 200, que significa todo o. Esse é o código de status padrão enviado pelo nosso aplicativo expresso. Em nossa solicitação também, você pode ver aqui que estamos obtendo o status 2000. Em seguida, temos o código 201, o que significa que foi criado com sucesso. Se criarmos novos dados em nosso servidor, poderemos retornar esses dados com o código de status 201. Você diz em qual método HTTP, podemos retornar o código de status para 01, escrever? Na solicitação de postagem, se nossos dados forem criados com sucesso. Em seguida, temos o status 400, o que significa uma melhor solicitação feita pelo front-end. Isso inclui algumas solicitações de acesso ausentes , inválidas ou não autorizadas E sim, para validação de dados, retornaremos uma mensagem de erro com esse código de status 400. Em seguida, temos 404, o que significa não encontrado Suponha que estejamos enviando solicitação de obtenção para obter o single relacionado ao ID dez. Agora, isso não está disponível em nossos dados. Então, nesse momento, podemos enviar resposta com o código de status 404 Outro código de status importante é 500, o que significa erro interno do servidor. Suponha que recebamos algum erro ao criar o novo para fazer neste servidor. Então, nesse momento, retornaremos resposta com o código de status 500. São muitos códigos de status, mas, por enquanto, esses são os mais úteis. Não se preocupe com a prática, você se lembrará de todos esses códigos de status. Agora, para passar o código de status com nossa resposta, podemos adicionar aqui vários cursores. Então, pressione Alt ou Option e simplesmente clique onde queremos vários cursores. E aqui adicionamos o status de ponto e, nesse código de status, queremos passar dados inválidos Passamos de 400 e pronto. Pressione SCAP para remover vários cursores e para que possamos passar o código de dados com nossa solicitação Além disso, se criarmos dados com sucesso , retornaremos a resposta com o Stas 201. Guarde o queijo chan e dê uma olhada. Envie a solicitação novamente e veja, aqui temos o código de status do erro, 400 solicitações inválidas. Adorável. 37. res.send e res.json: Até agora, estamos enviando a resposta usando o método response dot send. Mas esse método Sen de ponto de resposta é usado para fins gerais, o que significa que nesse método de ponto de resposta SN, podemos enviar qualquer tipo de conteúdo, como texto simples, SDML ou também podemos passar Agora, quando criamos a API no node, maioria das vezes queremos retornar dados no JSNFMat porque é muito mais fácil Aqui na resposta, temos outro método chamado de ponto de resposta JSON Isso converterá automaticamente nossos dados no JCNFmat e também definirá o tipo de conteúdo do cabeçalho como JSON de barra de Não se preocupe se você não souber sobre o tipo de conteúdo do cabeçalho, veremos isso na próxima seção. Usaremos o envio de pontos de resposta para respostas simples, sejam texto, SDML ou objetos, e usaremos o ponto de resposta JSN quando quisermos garantir que a resposta esteja no formato JSN e formatada adequadamente para clientes JSN e formatada adequadamente Ambos funcionam quase da mesma forma. Mas para dados JSN, ponto de resposta GSN é mais conveniente Na primeira solicitação do GAD, queremos enviar um texto simples Usamos aqui o ponto de resposta SN. Depois disso, queremos enviar o array to do, para possamos usar ar response dot JSN em seguida. Além disso, queremos enviar o objeto e, em seguida, o que usaremos Usamos o ponto de resposta JSN, vamos também remover esse console. Não precisamos de consoles em nosso servidor. É só para testar. Em seguida, aqui estamos retornando um erro. Primeiro, alteramos o envio com JSN JSON, e JSN é melhor passarmos esse erro Envolva essa string em um objeto e simplesmente adicione a propriedade da mensagem e dois pontos O mesmo que fazemos para esse erro e também para esse último erro. E quando criamos com sucesso um novo objeto a fazer , estamos retornando o novo objeto a fazer. Então, também mudamos a areia com JSON. Certifique-se de não passar texto sem formatação no método JN de resposta. Isso lhe dará um erro. Salve as alterações e, no teste anterior, vá para a seção de cabeçalho. Aqui temos vários detalhes, mas, por enquanto, precisamos desse tipo de conteúdo. Veja, ele está configurado para texto STML. Agora vamos enviar outra solicitação de postagem inválida. Veja, aqui obtemos o objeto que enviamos com a propriedade de mensagem e, agora, se verificarmos nosso tipo de conteúdo, veremos que ele está definido como JSON Use o envio de pontos de resposta para texto simples ou DML e use o ponto de resposta JSN para enviar dados GSN 38. Atualize um Todo único com solicitação de PUT: Agora vamos criar uma API para atualizar nossa única tarefa. Suponha que queremos atualizar o texto da tarefa ou atualizar o status. Então, aqui queremos atualizar pequenos detalhes sobre nossos dados atuais, ou também podemos atualizar todas as informações. Então é melhor usarmos aqui put request. Além disso, você pode usar seu método de página. Está totalmente bem. Então app dot pot 0.2 slash Todos. Agora, aqui precisamos do ID de tarefas que queremos atualizar. Adicionamos aqui o parâmetro de rota, calm ID. Depois disso, adicionamos função de retorno de chamada com solicitação e resposta Agora, primeiro, vamos obter o parâmetro ID. CSid é igual à ID dos parâmetros de ponto da solicitação . Sabemos que esse ID é string, então o envolvemos com a função de análise inteira Nossa primeira tarefa é descobrir qual elemento da matriz tem esse ID. E então, por meio desse índice de elementos, podemos alterar outros valores com muita facilidade. Então, para encontrar o índice, usamos o método todos array dot find index. Aqui, obtemos um único objeto para fazer isso e, em seguida, passamos condição T ID deve ser igual ao nosso parâmetro ID Essa expressão retorna o índice do elemento, então nós a armazenamos em uma variável chamada to do index. E se o usuário passar o ID, que não está disponível em nossa matriz? No momento, esse valor do índice todo se tornará menos um porque esse método de índice fino retornará menos um se você não descobrir que ele faz o Aqui passamos se a condição para fazer o índice é igual a menos um Em seguida, retornamos o ponto de resposta status 404, que não foi encontrado e, em seguida, o ponto Json e enviamos o objeto com a mensagem de propriedade e simplesmente retornamos aqui a mensagem para não Certifique-se de adicionar aqui esta devolução. Ótimo. Suponha que tenhamos encontrado um índice de tarefas e, em seguida, precisamos atualizar os campos desse elemento com nossos novos dados passados com a solicitação da API. Então, no topo, primeiro obtemos dados do corpo do ponto de solicitação e armazenamos esse objeto na variável todo. Agora, em vez de definir três variáveis diferentes, podemos usar aqui a desestruturação de objetos No lugar do nome da variável, podemos simplesmente adicionar colchetes CLI e escrever nossos nomes de propriedades que foram passados no corpo do ponto da solicitação Primeiro, obtemos a tarefa, depois o texto e depois o status. E é isso. Essa única linha de código funciona da mesma forma que essas três linhas de código. Agora, na atualização, nem toda vez que mudamos de tarefa ou apenas alteramos dados. Podemos alterar qualquer uma dessas três propriedades, e nosso front-end deve passar apenas as propriedades no corpo da solicitação que eles desejam alterar. Então, aqui podemos fazer algo assim. Se a tarefa estiver disponível, atualizamos a matriz para que a tarefa de ponto de índice seja igual à tarefa. Portanto, se essa tarefa estiver disponível no corpo da solicitação, somente a linha atualizará a propriedade da tarefa. Vamos duplicar essa condição I mais duas vezes. Vamos substituir essa tarefa por tags, tags e tags. Além disso, esse status, status, aqui está o status, e pronto. Além disso, aqui está faltando uma coisa. Você pode me dizer, temos que retornar a resposta no final desta função. Ponto de resposta Json e aqui enviamos nosso objeto atualizado para fazer Todos matriz em pacote quadrado, todo índice. Salve as alterações e vamos experimentar essa implementação. Então, vá para o Thunder Client e crie uma nova solicitação, escreva nosso endpoint, que é SDDP Local host, coluna Aqui passamos todo o ID. Digamos que um. Altere esse método Get para o método put e vamos passar os dados no corpo da solicitação. objeto com a propriedade tarefa e valor para isso é a tarefa atualizada. E simplesmente envie a solicitação. Veja, aqui estamos obtendo os dados atualizados. E se passarmos aqui o ID dez e enviarmos a solicitação , obteremos aqui uma mensagem de erro não encontrada. Você pode ver como é simples criar um PI. Portanto, se você quiser salvar seu teste, pressione Control pluss ou Command pluss e, a partir daqui, também podemos renomear nossa solicitação de teste Update todo 39. Exercício excluir tudo específico: Agora é hora de exercícios interessantes. Você precisa criar uma API para excluir o específico a fazer usando seu ID Esse é um exercício muito fácil. O exercício o ajudará a aprender rápido e também a aumentar sua confiança. Mesmo que você não consiga concluir todo o exercício, pelo menos tente resolvê-lo, pois é assim que você sabe em qual parte precisa trabalhar mais. Experimente e então qual é a solução. Então, espero que você resolva esse exercício ou pelo menos tente resolvê-lo. Agora vamos ver rapidamente a solução. Então, aqui definimos uma nova API usando o app dot Tilt porque estamos excluindo dados aqui, endpoints para fazer slash Callan ID, solicitação de retorno de chamada, resposta e função de seta Primeiro de tudo, obtemos o ID do parâmetro route. Portanto, Const ID é igual a solicitar parâmetros de ponto ID de ponto e simplesmente envolvê-lo com a função parse integer Essa prática de análise de números inteiros é muito útil porque, quando estou aprendendo o node Jaz, repito muito esse erro Certifique-se de não repetir esse erro. Aqui também, primeiro, temos que encontrar o índice do objeto todo, que tem esse ID. Então, a partir do método Put, copiamos essa linha variável e também copiamos essa condição para não encontrada e a inserimos em nosso método delete Agora, depois disso, temos que simplesmente remover esse todo específico da nossa matriz de todos. Então, para isso, usamos o método todos array dot splice. Nisso, temos que passar dois argumentos. Primeiro, qual índice queremos remover, que é isso para fazer index. segundo argumento é quantos elementos queremos remover desse índice. Suponha que temos o valor de índice dois e aqui passamos três. Esse método de emenda removerá três elementos com o índice dois e também removerá o elemento com os índices três e quatro No nosso caso, queremos apenas remover esse único elemento, passamos aqui um e, no final, simplesmente retornamos o ponto de resposta Json e aqui passamos a mensagem de sucesso, objeto com propriedade de mensagem e valor dois excluídos com sucesso Salve as alterações e também vamos testar essa solicitação de exclusão. Crie uma nova solicitação, altere o URL para STP, coluna com barra dupla, host local, coluna 3.000, barra, estúdio. Vamos excluir a tarefa com o Selecione o método de exclusão. Aqui, não queremos passar nada em nosso corpo de solicitação, envie essa solicitação. Veja, aqui recebemos uma mensagem de sucesso, o que significa que nossa tarefa 1 foi removida da nossa matriz de tarefas. Agora, se enviarmos novamente a solicitação com o mesmo ID, veja, aqui não somos encontrados. Y. Você pode ver que criar APIs não é muito difícil E nesta seção, criamos as APIs get, post, put, delete, todas crud Então, espero que você entenda como usar o Express e criar APIs elevadas com o Express Agora, na próxima seção, aprenderemos alguns conceitos avançados do Express, a próxima seção. 40. Seção 05 — introdução ao Middleware: Bem-vindo à quinta seção do definitivo de NodeJS Esta seção trata conceitos avançados de expressos e nós. Começamos com middleware, vários tipos de middleware, como trabalhar com diferentes ambientes como desenvolvimento ou produção, mecanismos de modelos e profissional mais completa do aplicativo Node Vamos começar com o middleware. O que é middleware Em expresso, middleware é uma função que chama a próxima função de middleware ou envia uma resposta para finalizar a solicitação atual Em palavras simples, qualquer função que chame a próxima função de middleware ou envie uma resposta para finalizar a solicitação, essa função é Agora deixe-me te fazer uma pergunta. Pense nessa função de retorno de chamada que passamos aqui. Podemos chamar essa função de middleware? Sim, porque essa função está enviando uma resposta para finalizar essa solicitação do Gad Quando nosso front-end envia solicitações para qualquer endpoint de API, essa solicitação passa por um túnel ou pipeline no qual todas as nossas funções de middleware são colocadas Esse pipeline é chamado de pipeline de processamento de solicitações. Suponha que aqui definamos o middleware um, o middleware dois e o último middleware três enviará enviará Agora, quando o front-end envia uma solicitação de API, primeiro, essa função de middleware one será executada Depois disso, passaremos nossa solicitação para o middleware dois do NST e, após concluir a execução, o middleware dois passará essa solicitação para o middleware três, que enviará a nossa solicitação para o middleware dois do NST e, após concluir a execução, o middleware dois passará essa solicitação para o middleware três, que enviará a resposta. Nosso servidor manterá esse pedido. Se obtivermos um erro no middleware um, outros dois middlewares Simples assim. Aqui estão algumas tarefas comuns para middleware Primeiro, ele é usado para registrar os detalhes da solicitação. Além disso, é usado para verificar se o usuário que enviou a solicitação está logado ou não Esse é o caso de uso mais comum e melhor do middleware. Não se preocupe, veremos isso na seção de autenticação do usuário. Agora, a última tarefa comum do middleware é passar os dados recebidos. Nós já terminamos. Lembre-se de que pressionar ponto JCN é uma função de middleware, que passa os dados recebidos para o formato JSON e, em seguida, passa nossa solicitação para a próxima função de middleware, que é essa que passa os dados recebidos para o formato JSON e, em seguida, passa nossa solicitação para a próxima função de middleware, que é formato JSON e, em seguida função principal . Agora você pode perguntar por que precisamos desses middlewares? Podemos escrever todo o código em uma única função? Para isso, imagine que estamos criando Bend para aplicativo de mídia social. Tenha uma API usada para criar uma nova postagem. Agora, queremos definir condições para essa solicitação. Somente usuários logados podem criar uma nova postagem. Se o usuário não estiver logado, retornaremos um erro Faça login com sua conta Agora temos outra API que é usada para adicionar curtidas em uma única postagem. Nesta API, também queremos a mesma condição em que o usuário deve fazer login. Aqui, temos que adicionar novamente o mesmo código. Agora, em vez de repetir esse código de verificação bloqueado, podemos defini-lo em uma função de middleware e simplesmente adicionar esse middleware para Dessa forma, não precisamos repetir nosso código. Usando middleware, dividimos nosso código em pequenos pedaços, que tornará nosso código limpo e mais Além disso, por meio de middleware, podemos impedir solicitação de usuários indesejados para acessar as rotas protegidas Para recapitular rapidamente, middleware é uma função que, chamada próxima função de middleware envia uma resposta à solicitação atual Podemos ver que o middleware é muito útil para qualquer aplicativo de nó Então, na próxima lição, veremos como criar middlewares 41. Criando middleware personalizado: Agora vamos criar nosso próprio middleware personalizado. É muito emocionante e simples. Então, aqui em nosso aplicativo, já adicionamos express dot Json Middleware usando app dot U. Agora, depois disso, adicionamos outro método abdtuUse, e nele, adicionaremos nossa Portanto, esse método ABDTuse é usado para adicionar middleware globalmente ao nosso Agora, dentro desse método de uso, passamos a função de retorno Essa função Colbec tem três parâmetros, resposta de solicitação e next Agora você pode perguntar, nós conhecemos a solicitação e a resposta. Mas qual é o próximo parâmetro? Esse próximo parâmetro é usado para chamar a próxima função de middleware Agora, dentro dessa função de retorno de chamada, escrevemos nossa lógica. Digamos que queremos que o console registre pontos de extremidade e métodos de solicitação Na string do modelo, adicionamos colchetes C, método de ponto de solicitação e URL de ponto de solicitação de caixa de dólar Agora, aqui está uma coisa. Em todos os middlewares personalizados, que definimos, na última parte, temos que chamar essa Caso contrário, nossa solicitação ficará presa nesse middleware e o usuário não receberá a resposta Deixe-me mostrar isso na prática. Salve as alterações e volte para nosso cliente tunder. Deixe-me abrir essa solicitação e enviar a solicitação. Oh, desculpe, eu esqueci de executar este aplicativo usando o nodemon Verifique se o aplicativo também está sendo executado no terminal. O ponto de índice do Nodemon é bom. Agora enviamos essa solicitação. Veja se está sendo processado. E se abrirmos nosso terminal, C, aqui obtemos o console dessa solicitação, o que prova que nossa função de middleware Portanto, nosso pipeline atual de processamento de solicitações é assim. Primeiro, expressamos o middleware adjacente, depois temos o middleware personalizado e, em seguida, temos a última função de middleware que retorna a depois temos o middleware personalizado e, em seguida, temos a última função de middleware que retorna a resposta. Quando não chamamos aqui a próxima função de middleware, nossa solicitação fica aqui nesse middleware e ela nos mostra o estado de processamento, que torna todo o nosso É por isso que lembre-se sempre de que, em cada middleware personalizado, é necessário chamar a próxima função de middleware ou retornaremos Aqui, chamamos a próxima função de middleware, salvamos as alterações e damos uma olhada Agora, se enviarmos novamente a solicitação, veja, aqui obtemos a resposta e, no console, também obtemos o registro da solicitação. É muito simples definir nossa função de middleware personalizada Eu sei que essa é uma função de middleware muito básica, mas no futuro, criaremos um middleware personalizado que verifica se nosso usuário está logado Além disso, quando definimos nosso middleware usando o método app dot use, esse middleware será aplicado a todas as chamadas de API, assim como esse middleware express 42. Construído no Middleware: Express, temos muito poucos middlewares embutidos. Já usamos um dos middlewares integrados , que é express dot Esse middleware passa dados do corpo da solicitação para o formato JSN Sem usar esse middleware, não podemos colocar dados no corpo do Dot da solicitação Você se lembra que não recebemos nada solicitando o corpo de Dot. Agora, outro middleware embutido útil é o URL codificado. Esse é um middleware embutido semelhante , como express dot Middleware Express dot JSN usado para passar JSNData e middleware codificado de URL de ponto para transmitir dados codificados de URL. Esse formato de dados codificado por URL geralmente é usado quando os dados são enviados por meio formulários SML simples usando o método post Em palavras simples, esses dois middlewares são usados para extrair dados da solicitação Quando o ErQuest tem JCNData, o Express usa o JCN Middleware e quando nossa solicitação tem dados em formato codificado de URL, o Express usa esse middleware codificado de URL JCN Middleware e quando nossa solicitação tem dados em formato codificado de URL, o Express usa esse middleware codificado de URL. As funções de middleware simplificam o processo de acesso aos dados da solicitação, então não precisamos analisá-los manualmente de uma forma simples Agora vamos ver como adicionar middleware codificado em URL em middleware codificado em URL em nosso aplicativo. É muito simples. Adicionamos aqui app.us e, dentro disso, chamamos a função codificada Express dot URL Salve as alterações e vamos ver se esse middleware está funcionando ou Vamos para a solicitação postal. Anteriormente, enviávamos dados usando esse formato JSON. Agora, aqui temos outra opção que é codificada em formulário. Aqui, passamos dados em um par de valores-chave, como tarefa, e aqui adicionamos nosso texto. Essa é uma nova tarefa codificada. Depois disso, queremos passar texto, que é matriz, e nele passamos SDML e CSS E, finalmente, queremos passar o status, o que é fazer. Agora, vamos simplesmente enviar essa solicitação. Veja, aqui temos novos dados criados com o status 201, nosso URL codificado está funcionando. Mas espere um minuto. Aqui temos essa sintaxe estranha dessa matriz. Na verdade, não é matriz. Nosso servidor armazena essa matriz como string. Veja, ele é codificado em códigos duplos, o que significa que é string Por que isso acontece. Quando queremos passar uma matriz ou objeto em formato codificado de formulário, precisamos adicionar configurações adicionais em nosso middleware Aqui no middleware codificado por URL, adicione um objeto com uma única propriedade estendida para true. Guarde isso. E na solicitação de postagem, em vez de passar essa matriz em um único campo, temos que passá-la em diferentes preenchimentos Assim como nosso nome de matriz é tags, escrevemos tags e aqui adicionamos colchetes, que indicam que é uma matriz, e depois passamos valores em vários preenchimentos Primeiro, escrevemos DML. Depois disso, adicionamos outro par de valores-chave, novamente, tags, pacote quadrado e escrevemos outro valor CSS Por fim, passamos tags, pacote quadrado e JavaScript. Agora você entende por que os desenvolvedores param de usar esse formato codificado de formulário O JSNFmat é muito mais fácil de passar e saborear. Veja, agora temos nossa matriz de texto. Além disso, vamos ver se removemos a propriedade estendida do middleware enquanto ela está funcionando ou não. Eu só quero ver. Oh, não está funcionando. Veja, aqui estamos recebendo textos obrigatórios, o que significa que não estamos recebendo textos. Nas versões anteriores do nó, isso pode funcionar. Mas como estamos usando a versão mais recente do nó dela , ela não está funcionando, então é melhor torná-la verdadeira, simples assim. Você pode ter dúvidas sobre qual middleware devemos adicionar em nosso projeto node JS? Codificado com pontos expressos JCN ou URL expresso. No mundo moderno, 90% dos desenvolvedores estão usando o JSNFMat para dados O JSNMddleware é comum. Mas se você não souber em qual formato, seu front-end enviará dados de solicitação, JSN ou formulário codificado , adicionar os dois middlewares 43. Compartilhando arquivos estáticos do servidor: Vamos ver outro middleware embutido que é usado para enviar arquivos estáticos do servidor Se você não conhece arquivos estáticos , os arquivos estáticos são simplesmente ativos que são necessidades de front-end, como arquivos SDML, arquivos CSS, arquivos JavaScript, arquivos de texto, imagens, patas, PDF etc Eles são chamados de estáticos porque nosso servidor não modifica ou processa esses arquivos antes de enviá-los ao cliente. Por exemplo, temos o logotipo da nossa empresa no servidor. Enviaremos esse arquivo de logotipo para nosso front-end e o front-end será exibido no site. Agora você pode pensar que temos um arquivo estático no servidor. Como podemos compartilhá-lo? Não se preocupe, é muito simples. Deixe-me te mostrar isso. Aqui usamos app dot ug. Agora, para compartilhar os arquivos estáticos do servidor, precisamos usar outro middleware embutido chamado press dot Dentro dessa função, temos que passar o nome da pasta que queremos compartilhar. Mais comumente, os desenvolvedores o chamavam de público. Você pode chamá-lo do que quiser, mas público é uma convenção comum. Você pode perguntar: não temos essa pasta pública em nosso projeto, então precisamos criá-la chamada pública. Certifique-se de escrever o mesmo nome que você deu à sua pasta e também certifique-se de que pasta esteja disponível na raiz do projeto, não em nenhuma outra pasta. Agora, para demonstração, adicionaremos aqui qualquer tipo de arquivo ou imagem. Então aqui eu tenho essa imagem. Eu faço o download e adiciono na minha pasta pública. E vamos renomear esse arquivo como Fire Watch ou qualquer coisa que você queira chamá-lo Bom. Agora, ao definirmos nossa pasta pública como estática, podemos acessar todos os arquivos que estão disponíveis dentro dessa pasta. Então, abra um navegador e aqui escrevemos nossa URL base, barra 3.000 da coluna host local E depois disso, podemos escrever nome do arquivo que queremos acessar, firewach dot P. Se extensão do arquivo de imagem for PNG ou JPG, você precisará escrever a mesma extensão de arquivo Aqui, eu não recebo o arquivo. O que está errado? Oh, esquecemos de salvar essas alterações. Agora, novamente, tente acessar esse arquivo. Veja, aqui temos nossa imagem. Então, adicionaremos todos os nossos arquivos estáticos à pasta pública e poderemos acessá-los diretamente aqui. Nosso front-end usará esse URL para mostrar imagens, peões ou qualquer coisa Além disso, em nosso aplicativo, podemos definir uma ou mais de uma pasta estática. Como alguns desenvolvedores gostam de adicionar a pasta Assets, podemos duplicar esse middleware e simplesmente substituir o nome da pasta por Apenas certifique-se de que a pasta esteja disponível na raiz. Agora, muitos desenvolvedores gostam de adicionar prefixo ao caminho do arquivo estático Atualmente, estamos acessando nossos arquivos estáticos diretamente após a coluna 3.000 do host local Ao adicionar um prefixo, ficará assim. Coluna do host local 3.000, barra Barra estática firewatch web P ou coluna do host local 3.000 OTRs firewatch web P, ou coluna do host local 3.000 OTRs Deixe-me mostrar como podemos fazer isso. Para isso, basta adicionar nosso prefixo antes do middleware estático expresso ATR se as mudanças mudarem se atualizarmos nossa página, veja, não obtemos aqui um arquivo estático Temos que adicionar Autar na URL e agora obtemos nossos arquivos estáticos É assim que podemos compartilhar arquivos estáticos do servidor. Agora, deixe-me fazer um pequeno exercício. Adicione um arquivo estático na pasta chamada assets e simplesmente acesse esse arquivo no navegador com o perfil de prefixo Eu sei que você pode fazer isso, então eu não estou te mostrando a solução. É muito simples. 44. Middleware de terceiros útil: Vamos ver alguns middlewares úteis de terceiros. Nós os chamamos de middleware de terceiros porque ele é criado por terceiros O primeiro é Morgan. Esse middleware é o middleware de terceiros mais popular para registrar o SDDPRquest para Agora, quando eu estava aprendendo que o Node tem, eu tenho essa pergunta. Por que os desenvolvedores querem registrar a solicitação do SDP? O que eles obterão simplesmente registrando a solicitação do SDP? Eu sei que você tem a mesma pergunta. Quando registramos a solicitação do SDP usando o Morgan, podemos acompanhar qual API está chamando por mais tempo Qual API está demorando mais para responder, quantas chamadas de API são preenchidas, depura a API fraca e muitos outros benefícios Normalmente, ao registrar a solicitação do SDP, os desenvolvedores podem monitorar, depurar e melhorar suas APIs Agora vamos ver como podemos registrar a solicitação do SDP usando o Morgan Aqui está um pacote Morgan. C, tem 4 milhões de downloads mensais, o que é insano. E, como sabemos, usamos esse comando para instalar o pacote Morgan. Então, basta copiar isso e parar nosso aplicativo com Control plus C e colá-lo em nosso terminal. Bom. Agora vamos executar novamente nosso aplicativo. Agora, em nosso aplicativo, criamos esse middleware de log personalizado Não precisamos disso, então podemos comentar esse código. Agora, para usar o Morgan, primeiro precisamos importá-lo em nosso aplicativo. Então, no topo, condenar Morgan é igual a exigir Morgan. E na parte inferior, adicionamos o ponto U do aplicativo e, dentro disso, chamamos essa função Morgan. Dentro dessa função Morgan, podemos passar um formato predefinido de solicitação de registro Por exemplo, combinamos o Dev for Development para obter mais detalhes, comuns, minúsculos, etc Se você quiser ver todos os detalhes , confira esta página do pacote. Aqui, você obtém todas as informações sobre formatos. Agora, em nosso código, simplesmente adicionamos aqui códigos duplos. Veja, aqui temos sugestões. Combinado, comum, curto, pequeno por enquanto, vamos para Dev Save the changes e dê uma olhada Agora acesse qualquer API no terminal. C, aqui temos os detalhes da solicitação. Primeiro, obtemos o método SDDP, depois o endpoint, depois o status, o tempo de resposta e o tamanho da Com esses dados, podemos melhorar nossas APIs. Se enviarmos novamente a solicitação, veja, obteremos um novo log. Então é assim que Morgan nos ajudará. Agora, o próximo middleware de terceiros é o capacete. É outro middleware popular, e todos nós sabemos o que os capacetes fazem em nossa Ele protege nossa cabeça de acidentes, e é isso que o middleware de capacete É uma excelente opção para aprimorar a segurança do nosso aplicativo com configuração mínima. Além disso, é comumente usado em ambientes de produção. Muitos aplicativos de nós usam esse middleware. Então, procuramos aqui o capacete. Aqui temos esse pacote. Vamos instalar esse pacote. Abra o terminal, pare o aplicativo, cole o comando aqui. E se você quiser instalar a mesma versão que estou usando , você também pode adicionar aqui a versão e pressionar Enter. Capuz. Vamos executar nosso aplicativo novamente. Agora, para usar esse pacote, primeiro, nós o importamos na parte superior. Então, capacete Const, igual a dois, requer capacete. E na parte inferior, antes de nosso outro middleware, adicionamos o app dot g e simplesmente chamamos aqui de capacete Middleware. E é isso. Isso adicionará automaticamente cabeçalhos seguros que protegerão nosso aplicativo Express Além disso, quero esclarecer uma coisa. Quando adicionamos middleware em nosso aplicativo, Express os adiciona na mesma ordem em que adicionamos em nosso código Por exemplo, atualmente o Express, adicione o middleware de capacete primeiro no pipeline de processamento de solicitações, depois JSON, depois codificado em URA, depois estático e depois O pedido também é importante para o middleware. 45. Como programar de acordo com o ambiente: Agora vamos ver como podemos codificar de acordo com nosso ambiente de aplicativos. Por exemplo, atualmente nosso aplicativo está em processo de desenvolvimento e, quando implantamos nosso aplicativo, ele estará no ambiente de produção. Agora, quando nosso aplicativo está em fase de desenvolvimento, só então queremos habilitar o middleware Morgan para nosso Então, primeiro de tudo, precisamos conhecer o ambiente atual. E sim, sabemos disso da mesma forma que tentamos conhecer o porto. Assim, podemos simplesmente consultar o processo de log de pontos ENV, e aqui acessamos dollar Cully Brackets, progress dot env dot node underscore ENV Esse nó sublinhado ENV é o nome da variável, igual a essa porta Vamos ver o que temos aqui. Salve as alterações e aqui ficaremos indefinidos. Por quê? Porque inicialmente nosso ambiente não é o desenvolvimento de STS. Agora, no Express, temos outra forma de conhecer o ambiente atual, que é usando o app dot gat E dentro desse intestino, temos que passar ENV para ambiente. Este aplicativo dot gt ENV retornará o mesmo resultado desse processo dot nw dot node underscore Mas quando não configuramos ambiente node underscore, nesse momento, esse aplicativo dot gt ENV retornará, por padrão, o desenvolvimento, o que é ótimo, Deixe-me te mostrar. Então, aplicativo de log de pontos do console ENV Colchetes em dólares, ponto de aplicativo Get ENV. Salve os Gengs e veja, aqui temos o desenvolvimento Mesmo assim, nosso ponto de processo ENV é indefinido. Agora, queremos adicionar esse middleware Morgan apenas se estivermos no ambiente de desenvolvimento Então, podemos codificar assim. Aqui adicionamos a condição I, app dot Get ENV Você também pode usar o processo dot NV, mas precisa alterar a condição de acordo com isso Agora é igual ao desenvolvimento. É verdade, só então adicionamos esse middleware. Nós os movemos para dentro deste blog do If. Agora, para indicar, adicionamos aqui outro registro de pontos do console, acrescentou Morgan. Bom. Salve os genes e, no terminal, veja, aqui adicionamos Morgan. Agora vamos mudar nosso ambiente para produção para ver se Morgan está adicionando ou não. Em primeiro lugar, paramos a execução do nosso aplicativo. Para definir a variável de ambiente, escrevemos: dólar ENV, coluna, nó, sublinhado ENV é igual a em códigos, passamos a produção Se você é usuário de Mac ou Linux , deve escrever aqui export, space, node, underscore ENV é igual à produção Certifique-se de escrever o nome e o valor corretos da variável de ambiente . Pressione Enter. Agora vamos executar nosso aplicativo novamente nodemon index dot js. Veja, aqui não adicionamos Morgan. É assim que mudamos nosso ambiente de aplicativos e código de acordo com isso. Vamos mudar novamente o ambiente para o desenvolvimento. Portanto, dólar ENV, nódulo do cólon, sublinhado EN V é igual a desenvolvimento Ou para Mac ou Linux, export, node, underscore ENV é igual a desenvolvimento E se verificarmos nossa inscrição novamente, veja, aqui temos Morgan adicionado. 46. arquivo env e pacote dotenv: Até agora, estamos definindo variáveis de ambiente usando dollar ENV ou o comando export no terminal Mas há outra maneira simples de definir essas variáveis usando o arquivo DOT ENV Neste arquivo NV, podemos simplesmente adicionar todas as nossas variáveis de ambiente como porta igual a 3.000 ou node underscore ENV Ou também podemos definir aqui a URL do nosso banco de dados. E muitos desenvolvedores usam essa abordagem para definir variáveis em vez de defini-las no terminal. Esse arquivo ENV mantém as informações confidenciais de nossos aplicativos , como credenciais, fora do nosso código, o que é uma boa prática de segurança Agora, esse arquivo ENV é um arquivo de texto simples. Podemos carregar sua variável em nosso aplicativo de nó, para que possamos usá-la e codificar de acordo com isso. Para usar essas variáveis de ambiente na aplicação de nós, temos um pacote chamado dot ENV Não se preocupe com apenas uma linha de código, podemos usar essas variáveis de ambiente. Vamos instalar esse pacote. Ponto de instalação do NPM ENV. Bom. Agora, em nosso índice de pontos sile na parte superior, temos que adicionar apenas uma linha require dot NV e, em seguida, aqui chamamos o método dot config e pronto Não precisamos fazer nenhuma outra coisa. Além disso, a vantagem dessa abordagem é que podemos acessá-los mesma forma usando process dot nw dot porD e process dot nw dot node Vamos executar esse aplicativo. Bom. Veja, atualmente estamos no ambiente de desenvolvimento, e é por isso que adicionamos Morgan. Agora, para te mostrar, eu mudo a porta para 8.000. Não use a porta 5.000 no MAG porque ela já está sendo executada em seu sistema e mudamos o ENV para produção Salve isso e agora precisamos reiniciar manualmente nosso aplicativo, porque Norman só reinicia nosso aplicativo quando os arquivos com essas extensões são alterados Veja, nossa porta foi alterada para 8.000, mas o que é isso? Nosso ENV é o mesmo de antes, que é desenvolvimento. Mas no arquivo ENV, nós o configuramos para a produção. Você consegue adivinhar? É porque na última lição, codificamos o valor ENV de sublinhado do nosso nó usando o dólar ENV Então, nosso aplicativo, lembre-se dessas configurações. Portanto, lembre-se sempre de que quando temos um arquivo DOT ENV e também definimos nossa variável de ambiente usando o terminal, nosso aplicativo de nó dá mais prioridade ao valor do terminal Para resolver esse problema, podemos simplesmente remover o valor ENV do sublinhado do nó Então escreva, remova, path, ENV, dois pontos, nó, sublinhado Ou se você for usuário de Mac ou Linux, escreva unset, space, node, underscore ENV e pressione Enter Agora reinicie o aplicativo. Veja, aqui temos a produção. E se no arquivo ENV, alterarmos ENV para desenvolvimento, salvamos as alterações e reiniciamos nosso aplicativo usando nod Veja, aqui temos o desenvolvimento porque adicionamos Morgan. 47. Diferentes configurações para diferentes ENV: Atualmente, estamos alterando manualmente nossas variáveis de ambiente porque elas são apenas duas. Mas no mundo real, podemos ter mais de duas variáveis de ambiente. Como se tivéssemos uma URL de banco de dados diferente no desenvolvimento e uma URL diferente na produção. Da mesma forma, podemos ter uma chave secreta para autenticação, etc Agora, quando temos essas muitas variáveis de ambiente, é difícil alterá-las manualmente. Agora, como podemos resolver isso? Para resolver esse problema, podemos criar dois arquivos ENV separados, dot-nw dot development e dot nw dot Production Você pode até mesmo criar testes ponto a ponto. Nesses dois arquivos, definiremos nossas diferentes variáveis de ambiente. Depois disso, em nosso index dot js, podemos simplesmente colocar uma condição se nosso ambiente de nó está em desenvolvimento e, em seguida, carregamos o arquivo de desenvolvimento dot nw dot E se nosso ambiente estiver degustando, carregamos esse arquivo de degustação de pontos NV Simples assim. Deixe-me te mostrar isso na prática. Aqui, criamos um novo arquivo chamado dot nw dot Development. Neste arquivo, definimos várias variáveis de ambiente. A primeira é que a porta é igual a 3.000. K é igual a fazer sublinhados secretos. Também podemos adicionar o sublinhado do nó. ENV é igual ao desenvolvimento, e pronto Agora vamos criar mais um arquivo chamado produção de pontos novos E dentro disso, adicionamos Pd igual a 8.000 K é igual a pro qi e último, um nó e um quadrado E e V é igual à produção Salve isso e agora, no ponto de índice s, precisamos apenas adicionar a condição. Então, no topo, aqui, primeiro criamos uma variável chamada arquivo ENV igual a, e aqui, para usar operadores ternários, passamos a condição se o ponto do processo nw passamos a condição se dot node underscore NV primeiro criamos uma variável chamada arquivo ENV igual a, e aqui, para usar operadores ternários, passamos a condição se o ponto do processo nw dot node underscore NV for igual à produção. Se for verdade, nosso arquivo ENV deve produzir pontos por pontos Definimos um arquivo de desenvolvimento dot nw dot como nosso arquivo de ambiente Agora, simplesmente neste método de configuração, temos que passar o objeto com o caminho da propriedade para o arquivo ENV Condição muito simples. E aqui para mostrar outra variável NV, aqui usamos console dot log, processamos dot nw dot Vamos verificar se está funcionando ou não. Atualmente, estamos adicionando Morgan. Agora vamos interromper nosso aplicativo. Dollar ENV, dois pontos, nó, sublinhado ENV é igual à Se você é usuário de Mac ou Linux , precisa usar export, node, underscore, EN V é igual à produção Agora vamos começar nosso aplicativo. Veja, aqui estamos no ambiente de produção porque Morgan não foi adicionado, e aqui obtemos a chave Pro e nossa porta também é alterada para 8.000 para que, usando arquivos ENV diferentes, possamos definir diferentes variáveis de ambiente 48. Mecanismos de template em aplicação de nó: Vamos ver o mecanismo de modelos no nó. Este tópico é um pouco antigo e não é comumente usado no mundo moderno. Então, vamos entender o que é um mecanismo de modelos. Basicamente, o mecanismo de modelos é uma ferramenta que nos permite criar páginas SDML dinâmicas Então, em vez de escrever manualmente o STML para cada página, podemos criar um modelo e, usando o mecanismo, podemos inserir dados automaticamente nesse modelo Em seguida, envie o arquivo SGML gerado para o navegador do cliente. Suponha que queiramos criar um site de blog de estilo antigo em que todos os blogs tenham o mesmo layout, mas apenas o conteúdo seja diferente. Agora, não queremos criar manualmente um arquivo SGML para cada postagem do blog Isso seria demorado e ineficiente. Em vez disso, podemos usar um mecanismo de modelo para criar um único modelo para o layout do nosso blog, e o mecanismo de modelo exibirá dinamicamente o conteúdo do blog com base nos dados que fornecemos de forma simples Existem muitos mecanismos de modelos no Jaz, mas o mais popular é o PUG e o outro é Ambos funcionam da mesma forma. Somente a sintaxe deles é diferente. Deixe-me te mostrar sobre o PUG. Então, em nosso terminal, escrevemos NPM install PugOR se você quiser instalar a mesma versão, depois escrevemos no vermelho três pontos zero ponto três Bom. Agora, em nosso arquivo JS de pontos de índice, temos que definir o mecanismo de visualização, que é o mecanismo de modelo, para PUG Então, escrevemos aqui app dot set. Aqui, queremos configurar o mecanismo, então escrevemos o mecanismo de visualização. E no segundo parâmetro, simplesmente passamos o PUG Então, nesta linha, definimos o PRG como nosso mecanismo de visualização ou modelo. Agora temos que criar um modelo para nossa página SDML no POG. Então, em nosso aplicativo, criamos uma pasta chamada views. Certifique-se de escrever o mesmo nome das visualizações. E dentro deles, podemos criar um arquivo chamado template dot POG Você pode usar qualquer nome de arquivo. Realmente não importa. Aqui, temos que escrever código na sintaxe Perg, que é muito semelhante à nossa Aqui vamos começar com HTML. Observe que aqui eu não estou usando colchetes angulares para etiquetas. Dentro do SDML, podemos ter uma cabeça, então a escrevemos como essa estrutura de árvore Dentro da cabeça, podemos adicionar um título aqui, queremos obter o valor do título dinamicamente Escrevemos o nome da nossa tag igual, e aqui escrevemos o nome da variável que passamos no tempo de execução Título. Não se preocupe, eu vou te mostrar tudo. Agora, depois da cabeça, sabemos que podemos adicionar a etiqueta corporal, então nos movemos na mesma linha paralela da cabeça e adicionamos o corpo No PRG, não precisamos fechar a tag. Agora, no corpo, podemos adicionar H, uma tag igual ao título e, depois disso, adicionar um parágrafo igual Modelo simples para blog. Você pode ver que essa é uma sintaxe muito mais limpa do que o SDML normal. Muitos desenvolvedores gostam, mas muitos não gostam. Salve esse arquivo e vamos ver como podemos renderizar página SDML e passar essas variáveis dinamicamente Anteriormente, definimos uma API para rota raiz simples na qual simplesmente retornamos o ponto de resposta Send. Este é um projeto de controle de tarefas. Agora, no lugar do texto simples, vamos renderizar nosso modelo Perg Aqui no local da resposta dot Send, escrevemos response dot Render. E essa função usa dois argumentos. primeiro é o nome do arquivo ou modelo que queremos renderizar. Nesse caso, é template, e o segundo argumento é o objeto com as variáveis e seu valor que definimos nesse template. Então, primeiro de tudo, título para, digamos, o blog 1. Depois disso, vamos para o template engine, e o conteúdo para facilitar o pug é muito bom, não sei Salve as alterações e, no navegador, vamos para a coluna 3.000 do host local Erro de conexão: talvez tenhamos esquecido de iniciar aplicativo node one index dot js Ah, atualmente está no ambiente de produção. Vamos configurá-lo no ambiente de desenvolvimento. Portanto, o dólar ENV pode sublinhar que ENV é igual a codificar o desenvolvimento Ou se você for usuário de Mac ou Linux, poderá usar export, node underscore ENV é igual a development Certifique-se de não passar aqui os códigos e, em seguida, iniciaremos o aplicativo. Veja, ele está ouvindo em 3.000 e se atualizarmos nossa página, veja, aqui temos o modelo Perg O título é blog one. O título e o conteúdo também são os mesmos que passamos. Então é assim que podemos renderizar um arquivo SDML no servidor e depois enviá-lo para o navegador do cliente Não acho que as empresas modernas estejam usando essa forma porque a maioria das empresas usa Rag, angular ou view para front-end 49. Como limpar a estrutura de aplicação de código: Atualmente, se virmos nosso arquivo JS de pontos de índice, parece que realmente estragamos nosso código Tudo parece muito confuso e não pode ser mantido. Então, vamos estruturar nosso aplicativo de nós, que é usado no mundo real. Então, atualmente, adicionamos todas as APIs relacionadas ao arquivo JS de ponto de índice único Imagine que em outro aplicativo de comércio eletrônico, temos outro conjunto de APIs para usuários. Temos outro conjunto de APIs para recursos relacionados a cartões. No momento, não podemos adicionar todas essas APIs no mesmo arquivo index dot js A solução é que podemos criar uma pasta separada chamada routes e, nela, adicionaremos arquivos para cada conjunto de APIs Criamos uma nova pasta chamada routes. Essa é uma prática comum para a estrutura do aplicativo. Agora, aqui, criamos um novo arquivo chamado todos dot js, no qual definiremos todas as rotas de API relacionadas a todos. Primeiro de tudo, vamos cortar todas as rotas do arquivo JS de pontos de índice. E cole no arquivo todos dot js. Agora você pode perguntar no arquivo index dot js na parte superior, temos a instância do aplicativo e, usando isso, definimos diferentes rotas de API. Mas aqui, no arquivo JS todos dot, não temos essa instância do aplicativo. Então, como podemos definir rotas aqui? Você pode dizer que podemos recriar a instância do aplicativo, mas isso não é possível. Isso não vai funcionar. Então, no expresso, temos outra instância chamada roteador, pela qual podemos definir a API e os pontos da mesma forma que somos APIs usando a instância do aplicativo Aqui, primeiro inserimos express const Express é igual a require Express Agora, neste expresso, temos outro método chamado Roteador, que retornará a instância do roteador, e é por isso que o armazenamos em uma variável chamada roteador. Agora, vamos simplesmente substituir essa instância do aplicativo por essa instância do roteador. Portanto, selecione este aplicativo e pressione Control plus D ou Command plus D, que selecionará todas as instâncias do aplicativo e a substituirá pelo roteador. Bom. Agora, definimos nossas rotas em um arquivo diferente. Mas como nosso arquivo index dot js saberá, essas rotas queremos adicionar em nosso aplicativo. Para isso, temos que exportar essa instância do roteador desse arquivo e adicioná-la ao arquivo index dot js. Simples assim. Então, você se lembra de como podemos exportar variáveis do arquivo do nó? Certo, usamos o módulo dot exports igual ao roteador. Salve esse arquivo e, no arquivo index dot js, vamos remover esses blocos. Não precisamos deles e adicionamos aqui ponto g do aplicativo para adicionar essas rotas em nosso aplicativo. Aqui na primeira posição, adicionamos o prefixo do roteador, o mesmo desse arquivo estático Na maioria das vezes, os desenvolvedores gostam de adicionar aqui a API slash. Depois disso, no segundo argumento, passamos nossa instância de roteador do arquivo todos dot js. Então, na parte superior, importamos esse roteador usando a função require. E aqui passamos o caminho do nosso arquivo, que é slash out todos Agora, como sabemos, essa função require retornará a instância do roteador, para que possamos armazená-la em uma variável chamada todos routes. E na parte inferior, aqui, passamos pelas rotas de Tudous. E pronto. Além disso, descobri que precisamos dessa matriz Tudous no arquivo Tudos Então, nós o recortamos daqui e colamos em nosso arquivo Tudous. Salve as alterações e vamos verificar se nosso aplicativo está funcionando bem ou não. Lembre-se de que, para que todos possam fazer rotas, precisamos adicionar o prefixo API antes dos endpoints. Envie a solicitação. Veja, está funcionando. Agora, uma última mudança que eu quero fazer é em nosso TudsRoute, podemos ver que estamos adicionando Tudos antes de cada Portanto, geralmente podemos passar essa barra todos no prefixo do arquivo index dogs Guarde esses. Agora, no arquivo todos dot js, podemos remover slash todos do endpoint Além disso, removemos todos os endpoints da API. Guarde isso e estamos prontos para ir. Também podemos remover essas linhas indesejadas. Nós não precisamos deles. Veja, agora nosso arquivo js de pontos de índice parece limpo e mais fácil de manter Seguiremos essa estrutura de aplicação pelo resto do nosso curso. Então, aqui nossa Seção cinco acabou. Você pode ver rapidamente o resumo em PDF e recapitular toda a seção em dois a 3 minutos. Nos vemos na próxima seção 50. Seção 06 — Assíncrono x síncrona: Bem-vindo às seis seções do curso definitivo, não de JS. Esta é a seção repressora alguns tópicos do AdvancevScript, como síncrono versus assíncrono , função de retorno de chamada, promessas infernais de retorno de chamada e espera assíncrona chamada, promessas infernais de retorno de chamada de alguns tópicos do AdvancevScript, como síncrono versus assíncrono, função de retorno de chamada, promessas infernais de retorno de chamada e espera assíncrona. Muitos desenvolvedores estão confusos nesses tópicos, então é melhor entendermos isso. Portanto, se você já está confuso nesses tópicos e deseja dominar o node js , nas próximas seções, você enfrentará muitos problemas. É melhor aprender esses tópicos, que podemos chamar de JavaScript assíncrono antes de nos aprofundarmos nos aplicativos de Em todos os aplicativos de nós, usamos muito esses tópicos. Vamos aprender esses tópicos. São simples e fáceis de aprender. Além disso, se você já está confiante nesses tópicos , pode pular esta seção Depende totalmente de você. Agora, antes de começarmos a aprender conceitos de JavaScript assíncrono, vamos entender a diferença entre assíncrono Isso nos ajudará a entender melhor. O que é síncrono? Programação síncrona significa que nosso código é executado linha por linha Cada linha deve ser concluída antes de passarmos para a próxima linha. Em palavras simples, a programação síncrona é como seguir uma receita passo a passo Cada etapa deve ser concluída antes de passar para a próxima. Se uma etapa demorar muito, teremos que esperar até que a execução termine e então poderemos continuar. Por exemplo, estamos preparando um bolo para a festa de aniversário. Agora, há um processo passo a passo para, digamos, primeiro misturamos os ingredientes, depois colocamos no forno para assar e, finalmente, decoramos o bolo. Aqui, temos que seguir as etapas linha por linha. Não podemos começar a decorar o bolo diretamente sem assar. Temos que ir na etapa um, etapa dois e na etapa três. Esse é o exemplo síncrono. O código síncrono também é chamado de código de bloqueio. Deixe-me mostrar o comportamento de bloqueio ou exemplo de código de bloqueio em JavaScript. Então, para praticar esses tópicos, criamos uma nova pasta na pasta de projetos chamada JavaScript assíncrono e abrimos essa pasta no Agora, dentro dessa pasta, criamos um arquivo JavaScript simples chamado index dot js. Bom. Agora, aqui escrevemos três linhas de console. Então, registro de pontos do console. Primeiro passo, comece. Outro registro de pontos do console. Etapa dois e último, registro de pontos do console. Etapa três e vamos executar esse código. Então, no terminal, escrevemos node, index dogs. Veja, estamos obtendo a saída linha por linha. Primeiro, temos a etapa um, depois a etapa dois e, em seguida, a etapa três. Agora você pode dizer que não podemos ver o comportamento de bloqueio desse código. Como podemos ver isso na prática? Atualmente, estamos obtendo essa saída sem bloqueio porque nem uma única linha leva mais tempo para ser executada, cada linha é executada imediatamente. Vamos adicionar um pequeno bloco nesse código. Aqui, depois do Console one, criamos uma função chamada fetch data Nessa função, fingiremos que estamos buscando dados do banco de dados Como sabemos, a busca de dados do banco de dados pode levar de dois a três segundos ou mais do que isso Por enquanto, apenas adicionamos um pouco de atraso usando quatro loops vazios, que podem levar algum tempo para serem executados. Aqui, seja I igual a zero, I menor que um e nove vezes zero e I mais. Simplesmente, não queremos fazer nada neste ciclo de outono, então abra colchetes fechados Agora, essa linha pode levar um ou 2 segundos para ser executada e, depois disso, movemos a segunda etapa do console cima e, aqui mesmo, os dados são buscados Aqui, antes da terceira etapa, chamamos essa função de dados fah Você consegue adivinhar o que obtemos na saída? Vamos ver. Salve as alterações e vamos executar esse arquivo. Veja, após a primeira etapa, nosso código para um pouco para que nossa função seja executada. Depois disso, obtemos os dados obtidos e, em seguida, a etapa três. Aqui, por um tempo, podemos ver o comportamento de bloqueio do nosso código JavaScript, que é chamado de código JavaScript síncrono Agora você pode adivinhar o que é assíncrono. Também em assíncrono, nosso código é executado linha por linha. Mas, para seguir em frente, não precisamos esperar para concluir essa tarefa. Podemos iniciar uma tarefa e, se levar mais tempo , podemos passar para a próxima linha. Em palavras simples, a programação assíncrona é como fazer várias coisas ao mesmo tempo e não esperar que cada linha termine a execução antes de iniciar a Você pode iniciar uma tarefa e, enquanto espera que ela seja concluída, pode fazer outra coisa. Por exemplo, você está preparando um barril e também assistindo a este curso Então você coloca o bolo no forno para assar, mas esse cozimento pode levar de dez a 15 minutos. Então, nesse momento, você pode fazer outras coisas em vez de apenas esperar o bolo assar. Então você começa a assistir este curso. E se você gosta deste curso, então, nesse momento, você pode compartilhar este curso com seus amigos. Da mesma forma, se definirmos nosso código de soma usando JavaScript assíncrono, se essa linha levar mais tempo para ser executada, nosso código JavaScript não ficará lá Ele avançará no código e quando essa linha terminar sua execução , ela executará essa linha. Podemos fazer várias coisas em JavaScript assíncrono sem esperar apenas uma linha para concluir sua tarefa Essa é a diferença fundamental entre JavaScript síncrono e assíncrono Por padrão, nosso código JavaScript é síncrono, mas o Javascript fornece alguns métodos pelos quais podemos tornar nosso código assíncrono para realizar tipos específicos Além disso, como sabemos, o node é popular porque pode aplicar a natureza assíncrona Agora, deixe-me mostrar como podemos transformar nosso código síncrono ou bloqueio em código assíncrono ou Aqui, no lugar desses quatro loops, que mantém nosso código ocupado, podemos adicionar outro método para adicionar atraso. Adicionamos o tempo limite definido. Esse método usa dois argumentos. A primeira é a função e a segunda é um tempo de atraso. Por exemplo, passamos aqui 10.000 milissegundos, o que é 10 segundos. Agora, em primeiro lugar, simplesmente passamos a função e, dentro dela, movemos essa etapa para o console de busca de dados Após 10 segundos, esta função testará os dados do console. Agora, você consegue adivinhar a saída desse código? Vamos ver. Veja, primeiro temos o primeiro passo. Depois disso, em segundo plano, nossa função está sendo executada, mas isso não impediu nosso código. Nosso código continua sendo executado na etapa três e, quando esses 10 segundos terminarem, obtemos a etapa dois pés de dados. Portanto, esse é o código sem bloqueio ou assíncrono. Código síncrono, aguarde até que uma linha conclua a execução e o código assíncrono, aguarde essa linha em segundo plano e continue Você pode perguntar qual é o melhor síncrono ou assíncrono Na minha opinião, ambos são úteis. Ninguém é melhor. Ambos têm propósitos diferentes. O síncrono é ótimo quando precisamos que a tarefa seja executada em uma ordem específica ou quando a tarefa é rápida e sem bloqueio Oferece simplicidade e previsibilidade. Ser assíncrono é importante para tarefas demoradas, como tratamento de arquivos, acesso ao banco de dados ou solicitação de rede, nas quais não queremos bloquear o encadeamento principal do No aplicativo node, usaremos JavaScript assíncrono Queremos realizar operações sem bloqueio, como fazer consultas ao banco de dados, chamadas de API, ler e gravar arquivos sem congelar O principal é que nosso aplicativo deve funcionar sem bloqueio, o que proporcionará aos nossos usuários uma experiência rápida e excelente. Então, como sabemos, por padrão, nosso código JavaScript é síncrono Mas o JavaScript fornece alguns métodos pelos quais podemos tornar nosso código assíncrono para fazer tipos específicos de A primeira é usando a função de retorno de chamada. Outro método é usar promessas. Nesta seção, aprenderemos profundamente sobre esses métodos. 51. Callbacks em Javascript: Agora vamos entender o retorno de chamada em JavaScript. Então, o que é a função de retorno de chamada? Uma função de retorno de chamada é uma função que é passada como argumento para outra função e executada após a conclusão de uma tarefa específica Deixe-me explicar seu retorno de chamada usando o cenário do mundo real. Suponha que você esteja pedindo sanduíche na lanchonete com seu telefone, então ligue para a lanchonete e faça Eles dizem que levará 20 minutos para preparar e entregar. Então você desligou a ligação e fez outras coisas em vez de apenas esperar pelo sanduíche Agora, quando o sanduíche fica pronto, o entregador toca sua campainha e te dá aquele sanduíche simples Então, nesse caso, você liga para a lanchonete e faz seu pedido é como iniciar uma tarefa assíncrona Depois disso, eles dizem que levará 20 minutos. Esse é o atraso na tarefa assíncrona. Então você desligou e fez outras coisas em vez de apenas esperar pelo sanduíche Esse é o comportamento de não bloqueio, o que significa que nosso código continua sendo executado. Quando o sanduíche estiver pronto, o que significa que nossa tarefa assíncrona foi concluída, o entregador toca sua campainha e lhe dá o que significa que nossa tarefa assíncrona foi concluída, aquele sua campainha e Essa é a função de retorno de chamada que está sendo executada quando a tarefa assíncrona Portanto, uma função de retorno de chamada é passada como argumento para outra função e também é executada após a conclusão de uma tarefa específica Em palavras simples, tudo o que quisermos fazer após a conclusão da tarefa assíncrona, passaremos na Agora, se você está trabalhando ou aprendendo Javascript há muito tempo , aposto que você já usou a função de retorno de chamada em seu código Só que você não sabe que essa função é chamada de ColwcFunction Por exemplo, você se lembra que na função de tempo limite definido na primeira posição, passamos a função que é executada após algum atraso E você está correto, essa função que passamos como argumento é chamada de função de retorno Da mesma forma que passamos função de retorno de chamada na função de intervalo definida Deixe-me dar outro exemplo. Em quase todos os métodos de matriz, passamos funções de retorno Como no método de forragem, método mapeamento, método de filtro Em todos esses métodos, passamos a função de retorno Além disso, em nosso projeto anterior, passamos a função de retorno de chamada no app dot get app dot post, app dot pot, delete e em todos os métodos Lembre-se de que elas também são chamadas de funções de retorno de chamada. Agora, para uma compreensão básica, vamos criar uma função e passá-la como função de retorno de chamada, porque no node, precisamos passar muitas funções de retorno de Então, vamos remover esse código. Se você quiser assistir ao código anterior na parte inferior desta lição, você receberá a pasta Resources Zip. Faça o download e descompacte. Na pasta de recursos, você receberá links do Gita para todos os códigos, seção por seção Então você pode obter referência a partir disso. Então, primeiro de tudo, escrevemos o log de pontos do console. Começar. Agora, criamos aqui uma função chamada fetch student, na qual fingiremos que estamos buscando dados do banco de dados Então, para simular o atraso na busca de dados, adicionamos aqui novamente, definimos a função de tempo limite E na primeira posição, o que passamos? Certo, não apenas a função, passamos a função de retorno Então, estamos passando aqui função usando a sintaxe da função de seta A função de seta é outra forma de definir a função e é muito mais limpa para funções de retorno Agora, no segundo argumento, passamos milissegundos, digamos 3.000 E aqui no tempo limite definido, consultamos o log de pontos buscando aluno no banco de dados Agora vamos chamar essa função fetch student aqui depois da linha do console Para torná-lo mais realista, também passamos aqui a carteira de estudante, que é a identificação do aluno que queremos buscar. Digamos que um. Agora, quando concluirmos a coleta de dados, após 3 segundos, queremos retornar os dados do aluno Então, retornamos o objeto do aluno com o ID. Aqui obtemos ID como parâmetro e simplesmente passamos esse mesmo ID aqui. Além disso, nosso aluno tem o nome de Harley, e digamos que queremos seu número de matrícula, suponha 500 Estamos fingindo que estamos obtendo esse objeto estudantil do banco de Agora, quando chamamos essa função, aqui obtemos os dados do aluno, para que possamos simplesmente armazená-los na variável chamada student. Para verificar, basta constar dot log, student e passar aqui este aluno No final, simplesmente consultamos o log de pontos e, agora, você consegue adivinhar o que obteremos na saída Obteremos os dados do aluno ou não? Vamos ver. O ponto de índice do nó é. Veja, aqui começamos, aluno indefinido, e então estamos obtendo dados do banco de dados. Deixe-me explicar o porquê. Quando chamamos essa função well stud com o ID one, em primeiro lugar, o tempo limite definido é executado, que executará esse trecho de código após 3 segundos Agora, no momento, não obtemos nada da função. É por isso que tinha um valor indefinido na variável student Nosso código JavaScript continuou sendo executado. É por isso que fazemos com que o aluno indefina e, depois de 3 segundos, a função de tempo limite definido consolará essa linha de busca Agora, o problema é: como podemos executar esse código e obter os dados do aluno? Qual é a solução aqui? Para resolver isso, usamos função de retorno de chamada e faremos isso na próxima lição 52. Resolvendo o problema usando retorno de chamada: Então, na lição anterior, obtemos o erro undefined student Agora, vamos resolver esse problema usando a função de retorno de chamada. Em primeiro lugar, não precisamos armazenar o resultado na variável student. Agora, para resolver esse problema, faremos poucas mudanças na função estudantil do Fed. Então, depois do ID, passamos sua função de retorno de chamada como parâmetro E no local de retorno do objeto estudante da função, chamaremos essa função ou chamaremos de volta essa função e simplesmente passaremos o objeto aluno nela. Eu sei que é um pouco confuso. Veja esta lição e você entenderá muito bem os retornos de chamada Agora, como estamos acessando a função de retorno de chamada como parâmetro, temos que passar essa função como segundo argumento quando estamos chamando a função fair student Então, aqui passamos a função, e dentro dessa função, podemos simplesmente mover esse aluno do console. Agora, de onde tiramos esse objeto estudantil. Certo, aqui temos o objeto aluno no parâmetro porque quando estamos chamando essa função de retorno de chamada na função de estudante rápida, estamos passando o objeto estudante aqui, e esse objeto estudante, acessamos diretamente aqui neste parâmetro de retorno de chamada Vamos ver se isso está funcionando ou não. Então, ponto de índice do nó Js. Veja, primeiro começamos e depois de 3 segundos, obtemos dados do banco de dados e, em seguida, usando a função de retorno de chamada, imprimimos esse objeto estudantil, e é exatamente isso que queremos Aqui está nosso código anterior e atual. No lugar de retornar os dados da função fat student, chamamos outra função para log de pontos do console, os dados do aluno. Essa linha de console só será executada quando essa função de retorno de chamada for chamada Por meio dessa técnica de função de retorno de chamada, tornamos nosso código assíncrono Agora, para deixar isso claro no lugar dessa função, usamos a sintaxe da função de seta Removemos a palavra-chave da função e, entre os parênteses e os colchetes GLY, adicionamos Veja, agora nosso código parece simples e dessa forma é muito útil no node porque, como você percebe, sempre passamos uma função de retorno de chamada como esta Em vez de declará-lo separadamente, definimos diretamente aqui. Você pode ver que, usando o método de função de retorno de chamada, podemos lidar com tarefas assíncronas Anteriormente, usamos essa notação Colbec para definir rotas de API Então essa é a função de retorno de chamada. A função de retorno de chamada é apenas um nome da função que passamos como argumento para outra função e é executada após a conclusão tarefa, especificamente a tarefa assíncrona Simples assim. Agora vamos adicionar um pouco de dificuldade a isso. Suponha que, a partir desse número de matrícula do aluno, desejemos obter os detalhes do resultado Depois dessa função fetch student, criamos uma nova função chamada Get result Parâmetro, adicionamos o número de inscrição porque, usando isso, buscaremos o resultado do banco de dados Agora, dentro dessa função, simplesmente retornamos o objeto com propriedades, ID do resultado para o número de inscrição, que obtemos no parâmetro, e depois disso, a porcentagem para, digamos, 70 Agora, como sabemos, estamos novamente buscando o resultado do banco de dados, o que significa que isso levará tempo novamente, e é por isso que essa função é importante para nós Então, para simular o atraso, aqui adicionamos a função de tempo limite definida e, dentro dela, a função de retorno de chamada e, novamente, aguardamos 3.000 milissegundos Agora, nessa função de tempo limite definida, movemos esse retorno e, como sabemos, esse retorno não tem significado Temos que passar esse resultado para a função de retorno de chamada. Como fizemos aqui. Então, função de retorno de chamada e simplesmente envolva esse objeto de resultado com parênteses da função de retorno Além disso, antes disso, podemos consultar resultado da busca do log de pontos do banco de Bom. Agora, onde chamamos essa função de resultado Gad, pense nisso Sim, podemos chamar a função de resultado Gad nessa função de retorno de chamada porque obtemos a inscrição no objeto aluno e também podemos chamá-la aqui na função obtemos a inscrição no objeto aluno e também podemos chamá-la fetch Mas como essa função tem tudo a ver com a busca de dados, é por isso que não queremos misturar as coisas Então, chamamos a função de resultado Ga na função de retorno No primeiro argumento, passamos o número de matrícula, que é o ponto E do aluno E o que passamos no segundo argumento, passaremos a função de retorno de chamada aqui Agora, aqui no parâmetro, obtemos o objeto resultante que passamos aqui e simplesmente consolamos o resultado do log de pontos com o resultado. Além disso, precisamos obter esse retorno de chamada a partir do parâmetro. Salve as gangues e vamos calcular essa pontuação. Aqui, primeiro obtemos os dados do aluno e, depois de 3 segundos, obtemos o resultado desse aluno. Então, deixe-me mostrar rapidamente o que está acontecendo aqui. Então, primeiro de tudo, o console inicial funciona, e então chamamos essa função de estudante de outono. Mas, devido a essa função de tempo limite definida, ela não será executada imediatamente Então, nosso código avança e simplesmente consola essa extremidade. Agora, após 3 segundos, o tempo limite definido executará o código que está disponível dentro de oito Então, chamamos a função Callback e simplesmente passamos Object. De onde obtemos essa função de retorno de chamada. Certo, obtemos isso do parâmetro, e onde definimos essa função de retorno de chamada, ela está aqui na função fat student, e é por isso que obtemos os detalhes do aluno primeiro Agora, depois de obtermos os detalhes do aluno, chamamos outra função, que é o resultado G. Portanto, essa função de resultado G será executada e, devido ao tempo limite definido, ela novamente levará 3 segundos para ser executada E dentro disso, chamamos outra função de retorno de chamada, e onde definimos essa função de retorno de chamada, sim, aqui, e finalmente, aquela função de retorno de chamada consola esse resultado, e é isso que está acontecendo Se, sem a função de retorno de chamada, quisermos executar nosso código na mesma ordem, podemos fazer isso Temos um aluno indefinido e, por causa disso, nem conseguimos obter resultados Agora você entende por que eu coloquei tanto peso na função de retorno de chamada Porque se você se confundir com a função de retorno de chamada, como você pode se concentrar no nó de aprendizagem 53. Inferno de retorno: Atualmente, neste código, adicionamos essa função de retorno de chamada dentro de outra função de retorno de chamada Agora imagine se tivermos outra tarefa assíncrona, digamos, resultado da atualização Dentro disso, passamos o ID do resultado do ponto de resultado e a função de retorno de chamada será executada após a atualização do resultado Recebemos aqui o resultado atualizado. Você pode ver que nosso código parece confuso e difícil de ler porque aqui temos muitas funções de retorno de chamada aninhadas umas nas outras . Deixe-me remover todos esses consoles para que possamos ver claramente, aqui obtemos retornos de chamada aninhados Essa situação é chamada de inferno de retorno de chamada, onde temos muitas funções de retorno de chamada aninhadas umas nas outras, o que dificulta a leitura e o gerenciamento do código Se tivermos o mesmo código em síncrono , ficará assim Primeiro, chamamos a função justa do aluno e armazenamos seus dados na variável do aluno. Da mesma forma que chamamos a função Obter resultado e aprovamos o número de matrícula desse aluno Por fim, chamamos função atualizada do aluno e passamos o ID do resultado, que queremos atualizar. Você pode ver que o código síncrono é muito simples e fácil de ler e gerenciar Agora você pode perguntar: qual é o problema com o inferno do retorno de chamadas Veja, mesmo se tivermos um retorno de chamada, nosso código funcionará. O problema é que é difícil ler e gerenciar porque, no mundo real, podemos ter mais de três retornos de chamada aninhados Então, de cada vez, será muito difícil ler, gerenciar e até mesmo escalar. Portanto, precisamos tornar nosso código fácil de ler. É muito simples. Só temos que criar nossa função anônima, que é a função que não tem nome. Converta essas funções de retorno de chamada anônimas em funções nomeadas Em palavras simples, no lugar de definir essa função de retorno de chamada aqui, nós as definiremos separadamente e passaremos o nome dessa função aqui Vamos adicionar nossos consoles novamente e remover essa última função Acabamos de adicioná-lo para um retorno de chamada de demonstração. Aqui criamos uma função chamada cost, print student. Podemos chamá-lo de qualquer coisa, e estou usando aqui as funções de seta no texto porque é fácil usar a função de retorno de chamada Agora podemos recortar essa função de retorno daqui e colá-la no lugar dessa função de seta Bom, e no lugar dessa função de retorno de chamada, simplesmente passamos a função print student Certifique-se de não ligar para a função estudantil impressa aqui. Só precisamos passar a função como parâmetro, e essa função de estudante de impressão será executada aqui como a função de retorno de chamada Agora, vamos converter rapidamente essa função de retorno de chamada anônima em função nomeada Portanto, o resultado de impressão de Cons é igual a, e aqui simplesmente colamos essa função de retorno E no lugar disso, passamos o resultado da impressão. Veja, agora nosso código parece limpo e fácil de manter. Para recapitular rapidamente, quando temos funções de retorno de chamada aninhadas, temos um problema de recuperação de chamada, que é difícil de ler e gerenciar Qual é a solução? Certo, convertemos nossas funções de retorno de chamada anônimas em funções nomeadas. Simples assim. 54. Promessa em Javascript: Na lição anterior, vemos como lidar com tarefas assíncronas usando Mas nessa implementação, obtemos esse problema de ajuda de retorno e também resolvemos esse problema com uma função nomeada Agora, minha pergunta é: quantas novas funções criamos? Imagine que temos dez funções de retorno de chamada aninhadas e, em seguida, precisamos criar dez funções nomeadas antes de chamarmos nossa função principal Existe alguma outra maneira de lidar com tarefas assíncronas? Sim, existe outra maneira de usar a promessa. O que é promessa? Uma promessa é um objeto especial que é capaz de manter o resultado de uma operação assíncrona Em outras palavras, promessa é a promessa de fornecer o resultado da operação assíncrona ou, se a operação assíncrona falhar, ela retornará um erro. Por enquanto, aprendemos promessas no novo arquivo chamado promise dot js. E então atualizamos nosso código anterior com a implementação do Promises. Então, primeiro, criamos uma promessa e depois veremos como consumir essa promessa. É muito simples. Então, para criar uma promessa, escrevemos uma nova palavra-chave e depois prometemos. Agora, essa promessa é uma classe e usa um argumento que é uma função com dois parâmetros. Então, aqui, o primeiro parâmetro é resolver e o segundo parâmetro é rejeitar e função de seta. Agora, dentro dessa função, podemos realizar nossa tarefa assíncrona Então, aqui, novamente, estamos assumindo que estamos obtendo dados do banco de Então, escrevemos aqui, definimos a função de tempo limite e passamos a função de retorno de chamada e 3.000 Agora imagine que aqui obtemos nossos dados do banco de dados. Então, criamos uma variável chamada aluno igual ao objeto, digamos, ID para um e nome para Agora, aqui chamamos de resolver porque obtemos os dados com sucesso e passamos aqui esse aluno. Aqui, nossa promessa está pronta. Agora vamos fazer essa promessa invariável chamada PR for Bom. Agora vamos ver como podemos consumir essa promessa. É muito simples escrevermos PR, que é essa promessa, dot, e aqui temos dois métodos principais, then e catch. Portanto, quando criamos uma promessa, ela está, por padrão, no estado pendente. E se concluirmos a tarefa assíncrona, promessa estará resolvida ou E se houver um erro, prometa no estado rejeitado. Isso é chamado de ciclo de vida da promessa. Aqui, nossa promessa é cumprida porque chamamos aqui de função de resolução. Então, quando a promessa é cumprida, obtemos nossos dados nesse método. Agora, armazenamos nossos dados nesse parâmetro de resultado e, em seguida, basta consultar o log de pontos desse resultado. Então, vamos executar esse arquivo. Node promete dot gs, veja, depois de 3 segundos, obtemos esse resultado. Agora imagine que, por algum motivo, não obtemos dados do banco de dados. Aqui, criamos uma variável chamada status e a tornamos falsa. Aqui, adicionamos condições. Se o status e meu sistema desligados automaticamente, deixe-me iniciá-lo novamente. Sim, estou de volta, então vamos continuar. Se o status for verdadeiro, executamos essa função de resolução, caso contrário, simplesmente chamaremos aqui a função de rejeição. Agora, para uma melhor prática, toda vez que queremos retornar um erro, criamos um novo erro e passamos nossa mensagem de erro aqui. Essa é uma mensagem de erro. Salve as alterações e vamos executar esse arquivo de promessas dot js. Veja, temos esse erro aqui. Agora vamos consumir esse erro, mesma forma que obtemos aqui dados no método then. Depois desse método, adicionamos outro método chamado cache e, dentro dele, também passamos a função de retorno de chamada Aqui obtemos um erro no parâmetro e consultamos o log de pontos desse erro. Salve isso e vamos executar esse arquivo novamente. Veja, recebemos esse erro aqui, e é assim que podemos consumir promessa usando o método then e catch. Podemos ver que, em vez de usar função de retorno de chamada para fazer algo após a tarefa assíncrona, podemos usar a promessa para realizar essa tarefa podemos usar a promessa para realizar assíncrona e, em seguida, simplesmente consumir essa a função de retorno de chamada para fazer algo após a tarefa assíncrona, podemos usar a promessa para realizar essa tarefa assíncrona e, em seguida, simplesmente consumir essa promessa. Resumindo, se nossa promessa for resolvida, esse método then será executado e, se nossa promessa for rejeitada, esse método de cache será executado, simples assim. Se você está preocupado com a criação da promessa , não se preocupe com a prática, você se sentirá confortável com ela. Deixe-me dizer uma coisa. No mundo real, 99% do tempo, consumimos apenas promessas. Apenas algumas vezes precisamos criar uma promessa. Agora, na próxima lição, vamos lidar com nosso código de recuperação de chamada usando promessas. Vai ser divertido. 55. Substituir chamadas por promessas: Vamos lidar com nosso código Callback L usando promessas. Você pode baixar o código do Callback hel abaixo desta lição Escrevemos esse código na lição quatro. Copie o código e cole-o em outro arquivo callbacltjs ou também na pasta resources e dentro da pasta assíncrona, você obterá esse Você também pode adicionar isso ao seu projeto. Agora, como sabemos, prometemos definir nossa tarefa assíncrona E aqui temos as duas tarefas assíncronas em duas funções separadas Agora, em vez de remover essas funções, podemos simplesmente retornar uma nova promessa dessa função. Não se confunda. Deixe-me mostrar o que quero dizer. Então, aqui, na função estudantil sentida, simplesmente retornamos aqui uma nova promessa. Agora, o que passamos nessa promessa, passamos aqui a função, que tem dois parâmetros, resolver e rejeitar. Agora, nesta função, o que fazemos corretamente, realizamos aqui uma tarefa síncrona Então, movemos essa função de tempo limite definida aqui usando as teclas alter ou option e aro. Agora, aqui não precisamos desse retorno de chamada. No local do retorno de chamada, passamos nossos dados na função resolve e também não precisamos de retorno de chamada no parâmetro Agora vamos fazer o mesmo nesta função de resultado do Gad. Então, retornamos a promessa e passamos aqui a função com dois parâmetros, resolver e rejeitar. Se você não quiser escrever essa linha inteira, deixe-me mostrar um atalho para isso Então, aqui escrevemos uma nova promessa sem espaço e selecionamos essa sugestão. Veja, aqui temos nossa nova promessa. Não mostrei isso anteriormente porque quero que você se sinta confortável com as promessas. Agora vamos mover esse código assíncrono também na função e no local do callba, retornamos esses dados no método resolve e, do topo, removemos esse do topo, Agora vamos consumir essa promessa. Na parte superior, comentamos esse código anterior no qual vivenciamos o inferno do retorno de chamadas Agora, aqui, primeiro chamamos função estudantil justa e identificação passiva de uma Essa expressão retornará essa promessa. Vamos armazenar essa promessa em uma variável chamada PR. Aqui temos nossa promessa nessa variável de relações públicas. Agora só temos que consumir essa promessa. Parte. Qual método usamos aqui, usamos o método ponto e depois. Aqui passamos a função. Aqui, obtemos parâmetros, dados, ou podemos chamá-los de estudante de qualquer coisa, função de seta e o que queremos fazer se tivermos dados de alunos. Nós simplesmente queremos chamar a função Get result e passar aqui Student dot Enrollment porque aqui temos a propriedade de inscrição Certifique-se de escrever a mesma propriedade que você escreveu e fez. Então é assim que consumimos a primeira promessa. Além disso, em vez de armazenar essa promessa em uma variável, aqui podemos escrever diretamente essa expressão. Você fica confuso com isso, então não se preocupe, você pode armazenar a promessa na variável e depois consumi-la. Essa é a prática comum, e é por isso que eu mostro aqui. Agora, como sabemos, essa função de resultado do gat também retornará a promessa Como podemos consumir essa promessa? É muito simples. O lugar de escrever o método dez aqui, podemos escrevê-lo depois do nosso primeiro método de dez. Agora, o que obtemos dessa promessa, resultado, função de seta e simplesmente o resultado do log de pontos do console até esse resultado. Salve as alterações e vamos executar nosso arquivo Callback Hel. A ajuda de retorno de chamada do Node não é. Bom. Veja, primeiro, ele buscará os dados dos alunos Depois disso, buscamos o resultado e depois imprimimos o resultado. Assim, podemos ver que, usando essas promessas, nosso código parece mais limpo e fácil de ler. Agora, se tivermos outra função em callBal semelhante a essa, retornamos aqui, essa nova função e a chamamos Agora, quando chamamos essa função e a retornamos, podemos adicionar aqui outro método diferente, simples assim. Alguns alunos podem ficar confusos sobre essa chamada da função get result. Eles perguntam o que está acontecendo aqui? Explique esse código em detalhes. Então, aqui, eu novamente chamo essa função fetch student e simplesmente passo aqui e consumo essa promessa usando o método then E aqui temos os dados dos alunos. Quando obtemos os dados do aluno, podemos passar a função de seta normal com colchetes C. Agora, dentro desses colchetes CL, não temos nenhum código. Só queremos retornar a função Obter resultado com a inscrição de pontos do aluno Então, como queremos apenas retornar essa linha, podemos remover esses colchetes C e também podemos remover a palavra-chave return Essa é a maneira mais curta de retornar algo da função de seta. Então, quando queremos retornar uma linha da função de seta , escrevemos diretamente após a seta. Aqui estamos retornando essa função. Toda essa expressão está retornando uma nova promessa. Assim, podemos armazená-lo em uma nova variável chamada novo PR. Agora vamos consumir essa promessa também. Escrevemos newpar dot the e, em seguida, obtemos o resultado, função de seta e, simplesmente, o log de pontos do console, resultado e imprimimos aqui esse resultado Agora, no local desse novo PR, podemos escrever toda essa expressão? Claro. No lugar do novo PR, colamos essa expressão. E foi isso que fizemos aqui. Agora, como prática recomendada, quando prometemos que a promessa também pode retornar um quando prometemos que a promessa erro usando o método de rejeição. Portanto, é melhor lidar com esse erro. Para isso, temos outro método, que é o cache. Também vemos isso na lição anterior. Então, aqui também adicionamos o método de cache. Aqui obtemos o objeto de erro e simplesmente consolamos esse Agora, para testar, simplesmente adicionamos rejeição na função de resultado do gat antes do método de resolução e passamos aqui o novo erro e a mensagem de erro, resultado não encontrado Salve as alterações e dê uma olhada. Vamos executar esse aplicativo novamente. Está corrigindo dados. Veja, aqui temos o resultado não encontrado. Se obtivermos um erro em alguma dessas promessas, esse método de esboço será executado Simples assim. Deixe-me comentar esse método de rejeição. É só para testar. Espero que todas as suas dúvidas estejam claras. Agora, na próxima lição, veremos outra maneira mais fácil de escrever esse mesmo código. 56. Async:await em JavaScript: Agora, como podemos ver no Calbecl após essa função get result, estamos consumindo outra promessa Agora imagine que neste Colbecl após essa função get result, estamos consumindo outra promessa Para isso, temos que adicionar outro método diferente, e isso também pode ser um pouco confuso Vamos tornar esse código mais simples usando async e await. O que é peso assíncrono? peso assíncrono é uma forma de escrever como código síncrono Ao usar o peso assíncrono, podemos consumir promessas de uma maneira muito mais fácil Então, primeiro de tudo, chamamos aqui função estudantil justa e simplesmente passamos aqui o ID 1. Agora, essa função retornará uma promessa que está inicialmente no estado pendente porque, nessa promessa, estamos executando uma tarefa assíncrona Portanto, podemos esperar aqui que essa promessa seja resolvida usando a palavra-chave Awight Então, awight pausa a execução do código até que a promessa Depois que a promessa é resolvida, ela retorna os dados. Agora, quando obtemos dados, podemos armazená-los na variável const student Agora temos o objeto do aluno, então podemos chamar Get result e passar aqui student dot Enrollment Essa função também retornará a promessa, então novamente adotamos a palavra-chave Await para essa promessa, get resolve e isso também retornará dados Resultado constante. Depois disso, simplesmente escrevemos o log do CLO Parkansa com nome da propriedade, resultado e Agora você pode ver, usando uma palavra-chave de peso, que podemos escrever código assíncrono que parece código síncrono parece Deixe-me comentar esse código anterior. Salve isso e vamos executar esse código novamente. Node, pontos de chamada. Veja, aqui começamos a buscar dados do banco de dados, depois obtemos o resultado e, no final, obtemos Portanto, nosso código está funcionando de forma síncrona porque nosso código está bloqueando aqui essa extremidade Agora, como prática recomendada e para tornar esse código assíncrono, temos que sempre usar esse await dentro assíncrona porque, na função normal Então, aqui criamos uma função chamada resultado de impressão. E simplesmente mova esse código dentro dessa função. Agora você pode perguntar que essa é a função simples, mas um peso só é válido na função ASN. Então, como podemos transformar nossa função simples em função de atuação? É muito simples. Só precisamos adicionar a palavra-chave ASN antes da função. E depois disso, simplesmente chamamos essa função de resultado de impressão. Caso contrário, como funcionará. Faça as alterações e vamos verificar isso. Execute novamente nosso arquivo. Bom. É atraente e, veja aqui, obtemos o resultado e também não está bloqueando esse fim Podemos ver que, usando async e await, podemos escrever nosso código assíncrono que parece um código síncrono. podemos escrever nosso código assíncrono que parece um código síncrono. Isso é mais legível e claro do que o código anterior. Agora, e se essa promessa escrever um erro usando o método de rejeição? Aqui, removemos o comentário do método de rejeição. Vamos ver como podemos lidar com erros no método at assíncrono Portanto, para lidar com erros em asyncawt, precisamos usar o método try and catch Também é simples. Deixe-me te mostrar. Então, primeiro de tudo, adicionamos try e, nos colchetes Gy, movemos nosso código Agora, se algo der errado nesse triplog, nosso código será movido diretamente para o bloco de cache Então, adicionamos aqui o bloco de cache, e esse bloco de cache tem um parâmetro chamado erro. E sim, é o mesmo erro promessa escrita na função de rejeição. No colchete CLI, podemos simplesmente consultar o log de pontos desse erro Agora vamos ver se está funcionando ou não. Salve isso e vamos executar esse arquivo mais uma vez. Veja, aqui temos um erro. Então, em termos simples, se ocorrer algum erro neste triplog, esse bloco de captura será executado Agora, alguns estudantes podem perguntar. Parece que esse 08 está impedindo que nosso código avance. E sim, é verdade, mas isso só é verdade para isso como função. Aqui temos o console e depois dessa chamada de função. Então, na saída, começamos e nossa função será chamada. Nessa função, primeiro, ele chamará de função justa do aluno, que retorna uma promessa. Portanto, um peso pausará a execução do código até que a promessa seja resolvida Portanto, nosso código não avançará apenas nessa função, mas avançará fora da função. E é por isso que, após o início, obtemos N. Então, se tivermos outras linhas, ele também as executará. se preocupe, Asyncawd é uma forma de escrever código assíncrono que parece código síncrono, mas nosso código mas nosso Para recapitular rapidamente, quando prometemos, podemos usar uma palavra-chave de peso Um peso pausa a execução até que uma promessa seja resolvida e só possamos usar um peso na função assíncrona Para tratamento de erros em um método syncowt, usaremos try and catch blog Se recebermos qualquer erro no blog seco , nosso método de cache será executado de forma simples assim. É assim que podemos consumir promessas de uma forma muito mais fácil do que esse método T and catch. A escolha é sua, o que você quer usar. Ambos funcionam da mesma forma. Depende totalmente de você o que você deseja usar. Além disso, se no Async e no AD você quiser adicionar o blog TryCatch, basta escrever Tricach e Veja, aqui temos o Tri Case Block. Espero que você aprenda muito esta seção ou que esses conceitos sejam atualizados Sem esclarecer esses conceitos, não podemos usar os aplicativos BG Se você estiver assistindo continuamente a este curso, faça uma pausa de cinco a 10 minutos, tome um pouco de ar fresco e nos vemos na próxima seção. 57. Seção 07 Noções básicas de MongoDB: Bem-vindo à sétima seção do curso definitivo sem JS. Até agora, em nossos projetos, estamos definindo dados em uma matriz JavaScript simples. Mas o problema com essa abordagem é quando reiniciamos nosso servidor ou aplicativo, nossos dados são redefinidos para um valor definido e perdemos nossas alterações em nossos dados. Agora, nesse momento, o banco de dados entra em cena, então vamos armazenar nossos dados no banco de dados. Existem muitos tipos de opções de banco de dados, como MySQL, SQL lite, Mongo Dib, etc Mongo DB é o banco de dados mais usado com aplicativos de nós, e é isso que aprenderemos neste curso Agora, uma coisa que quero esclarecer é que, depois de concluir este curso, você não dominará completamente o Mongo DB porque Mongo Di B em si é um curso de quatro a 5 horas, mas tentarei abordar o máximo de tópicos possível Portanto, nesta seção, começaremos com os princípios básicos do banco de dados e, em seguida, avançaremos para criar, ler, atualizar e excluir os dados com exercícios Estou muito animada e espero que você também esteja. Então, vamos mergulhar nessa seção. 58. Introdução ao banco de dados: Agora, antes de começarmos a aprender o Mongo Deb, é melhor aprendermos alguns termos básicos do banco de dados Então, como você deve saber, o banco de dados é uma coleção organizada de informações estruturadas chamadas dados e é armazenada no computador ou na nuvem. Nas escolas antigas, nosso professor usava um livro ou registro para acompanhar a frequência dos alunos Isso é banco de dados, mas está em papel duro. No mundo de hoje, usamos sistema de computador para armazenar esses dados, para que possamos acessá-los a qualquer hora e de qualquer lugar Todos nós sabemos disso, certo? Agora, existem dois tipos de banco de dados. O primeiro é banco de dados SQL ou banco de dados relacional, e o segundo não é banco de dados SQL ou banco de dados não relacional Eles diferem na forma como organizam, armazenam e gerenciam dados. Deixe-me explicar isso um por um. Portanto, SQL significa linguagem de consulta estruturada. O banco de dados SQL é bem organizado, preenchendo armários. Esses dois dados em tabelas usando várias colunas e linhas como essa. Podemos ver que essa é uma estrutura muito organizada. Cada coluna da tabela representa preenchimento diferente de dados, como nome, endereço de e-mail, número de telefone e senha, e cada linha da tabela é um novo conjunto de usuários. Temos que passar dados de um único usuário para todas essas colunas, e é por isso que é uma tabela organizada. Agora, por outro lado, nenhum banco de dados SQL é como um quadro flexível onde podemos organizar os dados da maneira que quisermos. Em nenhum banco de dados SQL, não temos tabelas porque elas não seguem uma estrutura estrita baseada em tabelas ou esquemas bancos de dados SQL armazenam dados em formatos mais flexíveis, como documentos DSN ou pares de valores-chave Por exemplo, se tivermos os mesmos dados do usuário, podemos armazená-los assim no par de valores-chave. Não precisamos fornecer todos os campos para cada usuário, e é por isso que podemos chamá-lo esquemas ou estrutura flexível de esquema As opções populares para SQL são mesquleQtOracle, etc. Onde no NoSQL, temos Mongo DiBrds Pode perguntar quando escolhemos SQL e quando não optamos por nenhum banco de dados SQL. Portanto, depende do tipo de dados com os quais você está lidando e do que seu aplicativo precisa. Usamos SQL, se quisermos que nossos dados sejam estruturados e organizados em tabela. Além disso, se precisarmos executar consultas complexas para análise ou se a consistência dos dados for usada, usaremos o banco de dados SQL Por outro lado, não usamos SQL Se quisermos que nossos dados sejam não estruturados ou semiestruturados, exceto pelo rápido crescimento de dados, exceto pelo rápido crescimento de dados, precisamos de flexibilidade em nosso modelo de dados, nosso aplicativo é em tempo real ou big data, então não usamos nenhum banco de dados SQUL Por exemplo, estamos criando aplicativos de comércio eletrônico, que têm muitos recursos, como o usuário pode fazer upload de avaliações, sugestões de produtos em que nossos dados não são estruturados ou semiestruturados, e também os usuários podem dar avaliações em grande número No momento, qual banco de dados devemos escolher? Certo, usamos aqui, nenhum banco de dados SQL. Vamos dar mais um exemplo. Suponha que estamos construindo um sistema bancário onde precisamos dados rigorosos e transações financeiras precisas. Qual banco de dados devemos escolher? Certo, use aqui SQL. Então, isso realmente depende do tipo de dados com os quais estamos lidando e do tipo de aplicativo que queremos criar. Na maioria das vezes, sua equipe lhe dirá qual banco de dados você deve adicionar ao seu aplicativo. Então não se preocupe com isso. Muitos desenvolvedores realmente não sabem a diferença entre SQL e sem SQL. Você sabe, certo? Em muitos aplicativos de nós, escolha padrão dos desenvolvedores é o Mongo DB, que é o banco de dados sem Squal E se você quiser se tornar um desenvolvedor MSTech, isso é para o Mongo Neste curso, eu adiciono o MongoDB como banco de dados. Não se preocupe, aprenderemos o MongoDB passo a passo. 59. Instale o MongoDB no Windows: Vamos instalar o Mongo DV no Windows e, se você tiver o MG, poderá pular esta lição Em primeiro lugar, acesse mongodib.com. Agora vá até esses produtos e selecione Community Edition. Acesse a comunidade de downloads. Role para baixo. E aqui podemos selecionar a versão Mongo Di B. Na minha recomendação, por favor, não a altere. Em seguida, podemos selecionar nossa plataforma e, em seguida, você pode selecionar o pacote. Não se preocupe com isso, clique em Baixar. Veja, o download foi iniciado. Agora, depois de concluir o download, abra essa configuração e ela solicitará permissão de instalação. Permita isso. Clique em Avançar. Aceite o acordo. Clique em Concluir. Depois disso, a partir daqui, podemos mudar nosso caminho de instalação. Mas se você não tiver nenhum motivo, não o altere. Basta clicar em Avançar. Certifique-se de selecionar essa bússola Mongo DB, que é o aplicativo do MongoDB, na qual você pode visualizar todas as tabelas do banco e editá-las Clique em Avançar e instale. Isso levará cerca cinco a 10 minutos porque também estamos instalando o Mongo DB compass Agora, depois de concluir esta instalação, vamos verificar isso. Abra o prompt de comando, escreva Mongo D e pressione Enter. Recebemos esse erro: o Mongo D não é reconhecido como um comando interno ou externo Então, para resolver esse erro, precisamos acessar novamente o site do Mongo Db e aqui nos principais produtos e ver todos os produtos nas ferramentas Agora, role para baixo nesta página e aqui temos a opção de célula. Então selecione-os agora, clique em Baixar, role para baixo. E aqui baixamos novamente essa configuração. Agora, depois de concluir o download, abra a pasta de download e extraia o zip que acabamos de baixar. Bom. Agora, abra essa pasta e, na pasta bin, obtemos esse arquivo Mongos Então, basta copiá-los e abrir os arquivos de programa da unidade C. Servidor MongoDB, 8.0 B, e aqui colamos Este Mongos é nossa célula Mongo DB. Agora temos que fazer uma última etapa, que é definir esse caminho para o caminho do ambiente. Portanto, copie esse caminho no início, pesquise a variável de ambiente e abra a edição das variáveis de ambiente do sistema. Deixe-me fechar as coisas. Agora, clique nessas variáveis de ambiente e, nas variáveis do sistema, selecione o caminho e clique em Editar. Agora temos que adicionar esse caminho de compartimento aqui, então clique em Novo e acompanhe esse caminho. Clique em OK. Ok, e tudo bem. Agora, novamente, abra o prompt de comando. Escrevemos mangas e pressionamos Enter. Obteremos a célula Mongo DB, então instalaremos o Mongo DB com sucesso em nosso sistema Agora, deixe-me fazer um rápido tour essa bússola Mongo DB Quando abrimos essa bússola pela primeira vez, precisamos inserir nossa cadeia de conexão, que é nosso host local, a coluna 27017 Você pode escrever essa string de conexão, que eu adicionei, e clicar em Salvar e conectar. Veja, aqui podemos ver nosso banco de dados e também podemos ver tabelas e A podemos ver documentos. 60. Conecte o MongoDB com o aplicativo Node: Então, instalamos o Mongo Di B em nosso sistema. Agora vamos conectar esse Mongo Di B com o aplicativo node. Então, para aprender Mongo Di B, criaremos um novo projeto porque eu não quero que você se confunda com o projeto tastak anterior Adicionaremos Mongo Di B como exercício nesse projeto. Vai ser divertido. Então, por enquanto, na pasta de projetos, criamos uma nova pasta, digamos Mongo demo, nome estranho, mas é bom para aprender Vamos abrir essa pasta no código VS. Agora, para inicializar este projeto, abrimos nosso terminal e escrevemos NPM nele I. Bom. abrimos nosso terminal e escrevemos NPM nele I. Bom. E aqui criamos um novo arquivo, index dot gs. Agora, em aplicativos de nós para gerenciar e trabalhar com o MongoDB, usaremos uma biblioteca muito popular, que é Em palavras simples, usando a biblioteca Mongoose, podemos trabalhar facilmente com o Mongo Vamos instalar esta biblioteca usando o NPM install Mongoose, se você quiser obter o mesmo resultado que eu estou obtendo neste curso, então aqui na taxa Bom. Agora, para usar essa biblioteca, primeiro, nós a importamos usando a função necessária. Aqui passamos o mangusto e o armazenamos na variável const mongoos armazenamos na variável const Agora, esse objeto mangusto tem muitos métodos. Um deles é connect, então mongoos dot Aqui temos que passar a URL do banco de dados Mongo DB que queremos conectar Abrimos aqui, o aplicativo de bússola MongoDB. Aqui podemos ver que temos a string de conexão, que é o host local, coluna 27017 Em nosso código, escrevemos códigos, Mongo DB, coluna, barra dupla, host local, Coluna 27017, que representam o banco de dados Mongo Deb local, que representam o banco de dados Mongo Deb local barra frontal, e aqui escrevemos nosso nome específico de coleção de banco de dados, digamos que Mongo Demo esse não é o nome do aplicativo, é o nome do banco de dados. Não se preocupe, veremos isso nas próximas seções. Agora, essa expressão retorna uma promessa, e você se lembra, como podemos lidar com a promessa? Podemos usar o método then and catch, ou podemos usar async Atualmente, não temos promessas aninhadas, então, para simplificar, podemos usar o método here, then Se você quiser usar o ASN e o Aviate, precisará criar uma nova função ASN Então, aqui adicionamos esse método de dez, que significa que o conectamos com sucesso à função de seta e simplesmente consolamos o log de pontos, Mongo Dib se conectou Portanto, pode acontecer que algo dê errado, como perda da conexão com a Internet, ou banco de dados não encontrado ou algum tipo de erro na cadeia de conexão. Nesse momento, teremos um erro nessa promessa. Então, também adicionamos aqui o método catch, e aqui obtemos o objeto de erro. E nós simplesmente consolamos o log de pontos, conexão do Mongo DB falhou Coma aquele objeto de erro. Então, basicamente, estamos dizendo ao Mongoose, conecte nosso aplicativo a esse banco de dados local, Mongo Agora você pode perguntar, não criamos esse banco de dados de demonstração do Mongo Como o Mongoose pode conectar nosso aplicativo a esse banco de dados Isso nos dará erro? E a resposta não, não nos dará erro porque se esse banco de dados Mongo demo não estiver disponível em nosso sistema, Mongoose criará um novo banco de dados chamado Mongo demo, e se esse banco de dados já estiver disponível, ele simplesmente o usará Agora, se esse banco de dados for conectado com sucesso, registraremos a mensagem de sucesso e, se nossa conexão falhar , registraremos esse erro. Salve as alterações e vamos executar nosso aplicativo usando o nodemon index dot Veja, aqui temos uma conexão bem-sucedida. Então é assim que conectamos o Mongo Di Be ao nosso aplicativo de nós usando o método Mongo dot connect Agora, deixe-me dizer uma coisa. Anteriormente, o Mongo Di Be costumava ter uma forma antiga de se conectar ao banco de dados, mas não era perfeita, e os desenvolvedores tinham algum problema com isso Em alguns códigos antigos, você verá essas opções passadas com a conexão. Essas opções servem apenas para lidar melhor com a conexão. Você pode usar o novo analisador de URL para true, que diz ao Mongoose que use a maneira moderna de se conectar ao Além disso, usamos a topologia unificada para True, que diz ao Mongos que gerencie as conexões de uma forma mais suave e estável Agora, na nova versão do Mongo Di, essas opções estão ativadas por padrão, então não precisamos passá-las aqui. Eu te falei sobre isso, se você vê esse tipo de código, não se confunde com isso. Agora, na próxima lição, criaremos nosso primeiro esquema de documentos 61. Importância do esquema: Antes de armazenarmos nossos dados em nosso banco de dados, é melhor definir a estrutura de lixo para esses dados Por exemplo, queremos registrar um novo usuário em nosso site. Então, ele preenche o formulário com nome, e-mail, número de telefone e senha E quando clicamos em registrar, armazenamos esses detalhes em nosso banco de dados. Agora, como desenvolvedores, sabemos que às vezes o usuário se esqueceu de escrever o nome ou esqueceu de escrever o e-mail ou O usuário pode esquecer qualquer coisa. Portanto, para evitar isso, definiremos a estrutura de lixo para esses dados, o que significa que podemos definir o nome obrigatório, o e-mail como campo exclusivo, e-mail como campo exclusivo que significa que cada usuário deve usar um endereço de e-mail exclusivo O número de telefone pode ser qualquer coisa ou o usuário também pode pular essas informações e a senha também é necessária Agora, se o usuário não passar o nome ou escrever um e-mail errado , seus dados não serão armazenados em nosso banco de dados. Retornaremos um erro para esse usuário, e é assim que podemos evitar dados indesejados e desnecessários sejam armazenados em nosso banco de dados. É por isso que definir a estrutura é importante e essa estrutura é chamada de esquema Você pode perguntar na aula de introdução ao banco de dados, eu disse que Mongo DB or no SQL são os esquemas ou a estrutura flexível do esquema, e o SQUL é a estrutura baseada em esquema, e agora estou dizendo Por quê? Sabemos que, no MongoDB, armazenaremos dados no par de valores-chave Suponha que, em nosso exemplo anterior, algum usuário passe o nome do campo, e-mail , como endereço de e-mail ou nome como nome de usuário, então como podemos gerenciar esse tipo de dados? MongoDB tem um esquema flexível, o que significa que não precisamos definir o No entanto, definir um esquema fornece consistência, validação e previsibilidade, que são cruciais na maioria dos aplicativos de nível de produção Um esquema nos ajuda a evitar dados indesejados ou sujos. Além disso, ao definir o esquema, podemos escrever a lógica de consulta com mais clareza Agora você pode perguntar ao Mongo Di B se há esquemas ou esquemas flexíveis Como podemos definir a estrutura no MongoDB? A resposta é que o Mongo DB não impõe o esquema de seus dados. Mas usando outras ferramentas como o Mongoose, podemos definir o esquema para nossos documentos do Mongo Além disso, se você estiver familiarizado com SQL, temos uma tabela, suponha usuário, e nessa tabela, temos linhas para cada usuário. Agora, no Mongo Di B, essa tabela é chamada de coleção. Essa linha pode ser chamada de documento. Não se confunda quando eu uso palavras como coleção e documento. Eles são muito parecidos com a tabela e a linha. Para recapitular, podemos definir um esquema para nossa coleção Mongo Dew para melhor uso Agora, na próxima lição, veremos como podemos definir o esquema para nossa coleção Mongo Dew 62. Definindo o esquema para o documento: Vamos ver como podemos definir o esquema usando mangas. Então, para isso, usamos o novo esquema de pontos de manga, que é uma classe Agora, neste parêntese, adicionaremos um objeto com nosso nome de preenchimento e estrutura para esse Por exemplo, primeiro precisamos do nome, da coluna e aqui escrevemos o tipo de dados que queremos armazenar. Então, por nome, queremos armazenar o stream. Certifique-se de escrever como em maiúsculas. Agora, depois disso, podemos ter e-mail e isso também queremos em string. Agora, como eu disse antes, queremos armazenar o e-mail como um valor exclusivo para cada documento ou linha. Então, como podemos definir essa singularidade aqui? Simplesmente, no lugar dessa string, passamos o objeto. Esse objeto tem várias propriedades. Primeiro, queremos definir o tipo desse preenchimento, que é string, e então temos outra propriedade que é única e a definimos como verdadeira. Portanto, se já temos um e-mail para um usuário, esse mesmo e-mail não pode ser usado para outro usuário. Depois disso, digamos que temos telefone e passamos aqui o objeto, e definimos o tipo como número. Agora, aqui não queremos tornar esse preenchimento necessário. O usuário também pode pular este telefone preenchido. Então, aqui não passamos nada. E se quisermos apenas passar a propriedade de tipo para o preenchimento, podemos escrever diretamente como esse número. Mas eu gosto de seguir uma sintaxe consistente, então deixo isso como está Mas no campo de nome no lugar dessa string, simplesmente adicionamos objeto com tipo à string e também queremos tornar esse campo obrigatório Nós adicionamos aqui, obrigatório para verdadeiro. Certifique-se de que aqui escrevemos obrigatório, não obrigatório. Não tenho certeza se only require está funcionando ou não. Além disso, sempre armazenamos nosso ID EML em minúsculas e também podemos definir isso aqui em minúsculas como verdadeiro Você pode ver que definir o esquema não é difícil. É muito simples. Agora, depois disso, temos a senha e queremos armazená-la como string e é o campo obrigatório Diga-me quais propriedades devemos adicionar aqui. Certo, adicionamos aqui o tipo à string e required a true. Você está indo muito bem. Agora, depois disso, esse usuário pode ter hobbies, que podem ser várias coisas Então, queremos armazená-lo em uma matriz. Digite entre colchetes, que é matriz, e nisso, queremos uma string simples Portanto, nossos hobbies podem se parecer com essa matriz de cordas. Agora, depois disso, podemos verificar qual usuário de origem foi verificado ou não, e definimos seu tipo como Bullion, o que significa verdadeiro ou falso E, por padrão, queremos armazenar o usuário como não verificado. Então, para isso, temos outra propriedade chamada default. Passamos o valor padrão como falso. É assim que definimos o esquema para nossa coleção Mongo DB. No esquema, temos vários tipos de esquema, como string, número, booleano, data, objeto, matriz, ID do objeto, que veremos no futuro, B para armazenar dados binários misturados com qualquer tipo de Se você quiser conhecer todos os tipos de esquema e suas propriedades, visite esta documentação do mangoose Nesta página, obtemos todas as informações. Agora, na próxima lição, veremos como aplicar esse esquema para coleta 63. Criando modelos: Na lição anterior, criamos esse esquema de usuário. Agora, como podemos definir qual coleção deve seguir esse esquema Para isso, precisamos criar um modelo. Então, primeiro de tudo, armazenamos esse esquema em uma variável chamada esquema do usuário Agora, para aplicar esse esquema de usuário, precisamos criar um modelo Então, escrevemos aqui Mongoose dot Model. Dentro disso, na primeira posição, passamos o nome singular da nossa coleção, que é aqui usuário. Então, esse usuário se tornará a coleção de usuários. Se quisermos criar uma coleção chamada post, que é plural, então aqui, temos que escrever nome singular dessa coleção, que é post Agora, no segundo argumento, passaremos nosso esquema para essa coleção de usuários, que é esse esquema de usuário Agora, essa expressão retornará o modelo para coleta de usuários. Então, nós o armazenamos em uma variável chamada usuário. Você pode me dizer por que estou usando essa convenção de pascal ou por que uso U como modelo de usuário É porque esse usuário é uma classe e, usando essa classe ou modelo de usuário, faremos muitas coisas. Simplificar o modelo é como um modelo para criar e trabalhar com documentos em uma coleção Mongo Deb Define a forma dos nossos dados usando um esquema e fornece uma maneira de interagir com essa coleção Em termos simples, o modelo nos permite criar novos documentos com base no esquema, ler dados da coleção, atualizar documentos existentes e também excluir documentos da coleção Resumindo, sem modelo, não podemos fazer nada com a coleção Mongo Di Bi Não se preocupe, veremos tudo isso nas próximas aulas. Atualmente, deixe-me mostrar como podemos criar um novo usuário usando esse modelo de usuário. Então, para criar um novo usuário, escrevemos novo usuário e, dentro disso, passaremos nosso objeto de usuário. Portanto, o primeiro campo dessa coleção é nome e valor de passagem como código mais U. Você pode escrever seu nome Em seguida, temos o código de e-mail, digamos, em did gmail.com Atualmente, estamos escrevendo esses valores manualmente , mas no mundo real, nosso usuário do front-end escreverá esse valor e o enviará usando a solicitação de postagem. E no back-end, lidaremos com essa solicitação de postagem e, dentro da lógica de solicitação de postagem, escreveremos essa nova expressão de modelo. Então não se preocupe com isso. Em seguida, temos o telefone, que pode ser qualquer coisa 23, 51, 552 Em seguida, temos a senha. Certifique-se de escrever aqui o mesmo nome de preenchimento que definimos no esquema Senha para a string 123, quatro, cinco, seis, 78. E hobbies para organizar, e aqui eu adiciono aprendizado, ensino e rastreamento Para o último campo, já definimos o valor padrão em nosso esquema, então não precisamos passar esse preenchimento aqui É assim que podemos criar um novo usuário ou documento da coleção. Aqui, nós o armazenamos em uma variável por novo usuário. Agora, atualmente, esse novo usuário está disponível apenas localmente. Na próxima lição, veremos como podemos armazenar esse novo usuário em nosso banco de dados. 64. Salvando um novo dado: Então, aqui temos novos dados do usuário. Agora vamos armazená-lo em nosso banco de dados. Portanto, esses novos dados do usuário têm um método, que é o dot CV. Ao usar esse método de salvamento, podemos armazenar esses novos dados do usuário em nosso banco de dados. Agora, salvar os dados no banco de dados é uma tarefa assíncrona, o que significa que pode levar algum tempo para salvar novos dados no banco de dados E é por isso que essa expressão retorna uma promessa. Você pode aderir, aguardar e, quando nossos dados forem armazenados com sucesso no banco de dados, eles retornarão o objeto de usuário armazenado do banco de dados, para que possamos armazená-lo em uma variável chamada dados armazenados e simplesmente consolar o log de pontos com os dados armazenados Agora, como sabemos, quando queremos usar await, precisamos de uma função acing e somente dentro dessa função, podemos usar Caso contrário, nosso código bloqueará as próximas linhas. Aqui, antes desse novo objeto de usuário, criamos uma nova função de atuação chamada create user E dentro dessa função, podemos simplesmente mover esse novo usuário e salvar o método. E, no final, chamaremos essa função de criação de usuário. Agora, não salve o arquivo, ele executará automaticamente esse arquivo. terminal, eu paro nossa ligação de nós usando Control plus C. Agora salve as alterações e vamos ver se isso está funcionando ou não. No terminal, executamos esse arquivo usando node index dot js. Não use here nodemon porque só queremos executar esse arquivo index dot js uma Se usarmos o nod M e mudarmos algo em nosso arquivo, um novo usuário sempre será criado Veja, aqui obtemos novos dados do usuário com nossos preenchimentos e, no final, também obtemos o ID de sublinhado, que é o ID exclusivo deste documento, gerado pelo Mongo DB. Usando esse ID, podemos fazer Além disso, temos aqui o sublinhado para zero. É isso? Esse sublinhado é usado para piora de documentos Quando criamos um novo documento, Mongoose adiciona o sublinhado preenchido e o define como zero Agora, cada vez que um documento específico é atualizado, mangas aumentam o sublinhado preenchido Por enquanto, não se preocupe com isso. Além disso, podemos ver esses dados no aplicativo de bússola Mongo DV Veja no banco de dados local, aqui não obtemos nosso banco de dados, clique nos pontos da árvore e atualize Veja, agora temos o banco de dados Mongo Demo. Dentro disso, temos a coleção de usuários, que criamos usando o modelo, e nessa coleção, temos nosso primeiro documento com ID exclusivo e também temos nossos preenchimentos Digamos que essa matriz Obs, que é um par de valores-chave, chave é o índice desse elemento e valor é nossa string Obtemos dados do banco de dados em nosso arquivo JS de pontos de índice e, em seguida, obtemos uma matriz normal de string. Está apenas aparecendo aqui no par de valores-chave. Além disso, veja, por padrão, definimos esse valor verificado como falso. E sim, podemos alterar os dados desse aplicativo. Então, para recapitular rapidamente, primeiro, criamos um novo objeto de usuário usando esse modelo de usuário e, em seguida, podemos simplesmente usar o método Lots para salvar este documento Agora, vamos tentar armazenar os dados de outro usuário porque precisamos desses dados nas próximas aulas. Mudei o nome dele para Halley, envie um e-mail para Halley em direct Se você quiser mudar alguma coisa e puder alterar o número de telefone, a senha, Harley 123 e os hobbies, digamos, codificação, gravação e rastreamento . Salve as alterações e, em nosso terminal, executamos o node index dot js. Bom, veja, aqui temos novos dados. Se verificarmos nossa bússola Mongo Di B, não obteremos dados aqui Então, atualizamos a partir daqui e vemos aqui que obtemos nossos novos dados. É assim que funcionam os dados em nosso banco de dados. Se seguirmos isso passo a passo , é muito simples. 65. Consulte os dados: Agora vamos ver como podemos consultar os dados. Mas você pode perguntar: qual é o significado da consulta? A consulta é simplesmente uma solicitação de informações do banco de dados. Em palavras simples, uma consulta é apenas uma forma de solicitar ao banco de dados dados específicos com base em determinadas condições. Por exemplo, da nossa coleção de usuários, queremos obter dados de todos os usuários. Primeiro, escrevemos o modelo dessa coleção, que é o ponto do usuário, aqui obtemos vários métodos de consulta. Temos que encontrar por identificação e encontrar um. Além disso, temos outros métodos excelentes para atualizar, excluir e substituir. Não se preocupe com eles. Nós os veremos nas próximas aulas. Atualmente, focamos apenas nessa descoberta, que é usada para encontrar vários documentos de nossa coleção. Portanto, temos o Fine n , que é usado para buscar apenas um único documento da coleção Também temos o Fine by ID, que é usado para buscar documentos por meio de seu ID exclusivo Atualmente, queremos buscar vários documentos, então usamos aqui dot Find Agora, essa expressão também retornará uma promessa. Podemos usar aqui o método then, ou podemos usar Ising await Nesse caso de uso, ain await é mais simples e nos ajuda a escrever um núcleo limpo Aqui, criamos uma nova função ing chamada get users e simplesmente movemos esse await dentro dessa função Agora, isso retornará os dados de todos os usuários da coleção de usuários. Nós o armazenamos em uma variável chamada usuários e o Consol registra os dados desses usuários Também no lugar dessa função creatuser, chamamos GTUsersFunction e a movemos para baixo dessa função Agora vamos ver se estamos recebendo dados ou não. Salve as alterações. E vamos executar esse aplicativo usando node index dot gs. Veja, aqui temos uma matriz de dados de dois usuários. O primeiro é o código PlusU e depois a Harley. Adorável. É assim que buscamos todos os dados da coleção Agora, vamos tornar isso mais interessante. Suponha que queremos encontrar apenas os usuários cujo nome é Harley Então, para fazer isso, passamos o objeto no método fino. Aqui, podemos definir várias condições no par de valores-chave. Esse é um nome que dois codifica Harley. Isso encontrará os dados de todos os usuários cujo nome é Halley. Além disso, aqui podemos passar várias condições, como Es verificados como falsos, etc Essa consulta verificará se o nome é Halle e se o valor verificado é falso ou não Se ambas as condições forem verdadeiras, somente então obteremos os dados desses usuários. Diga isso e vamos executar nosso aplicativo. Veja, aqui temos uma matriz vazia. Por quê? Como podemos ver em nosso banco de dados, temos o nome Halle e também foi verificado se está definido como falso Então, por que não estamos recebendo esses dados. Aqui na propriedade do nome, passamos Halle em minúsculas Mas no banco de dados, H é maiúsculo. Então, vamos mudar essa condição, ver quais são as mudanças e vamos executar nosso aplicativo mais uma vez. Veja, aqui temos nossos dados. Portanto, lembre-se de que, se passarmos uma string como condição, certifique-se de escrever com distinção entre maiúsculas e minúsculas. Bom. Agora, atualmente, estamos obtendo dados com todos os preenchimentos. E se quisermos apenas buscar o nome de usuário e os hobbies? Então, para isso, após esse método fino, podemos adicionar o método select e dentro dos códigos, passamos o nome dos nossos campos separados por espaço. Escrevemos hobbies de namespace. Se quisermos outros campos , também podemos passar aqui com espaço. Por enquanto, não queremos isso. Salve as alterações e vamos executar nosso aplicativo. Veja, aqui temos apenas nome, hobbies e ID de sublinhado que são adicionados automaticamente pelo Mongo Além disso, se de nossos dados quisermos apenas remover um ou dois preenchimentos, como aqui, queremos que todos os dados, exceto a senha, sejam verificados Então, no lugar desses nomes de preenchimento, passamos menos senha, espaço, menos é Salve as alterações, abra o terminal e vamos executar nosso arquivo. Veja, aqui temos todas as falhas, exceto a senha e o Es verificados. Simples Agora vamos fazer essa consulta um pouco mais avançada. Suponha que tenhamos 100 dados do usuário e queiramos buscar esses dados, mas como podemos buscar 100 dados em uma única matriz É melhor buscarmos os primeiros dez dados e, depois disso, outros dez dados Então, aqui removemos essa condição porque queremos todos os dados e após a seleção, adicionamos limite dentro dela, podemos passar o número de registros que queremos ver. Digamos que dez. Salve as alterações, abra o terminal e vamos executar nosso aplicativo. Veja, aqui temos dois registros porque só temos dois registros. Se tivermos 20 registros, obteremos apenas os primeiros dez registros. Além disso, como temos limite, também pulamos o método Aqui, passamos o número de dados que queremos pular. Se tivermos 20 registros e aderirmos ao salto cinco , ele pulará os primeiros cinco registros e exibirá de seis a 20 Esse método de limite e salto é muito útil para paginação e consulta Não se preocupe, eu adicionei uma aula separada para isso. Por enquanto, basta entender que Skip e limit estão disponíveis. Então, vamos remover isso. Bom. Agora, finalmente, também podemos encurtar nossos dados por qualquer preenchimento. Suponha que desejemos encurtar nossos dados de usuário pelo nome preenchido. Então, podemos escrever aqui um ponto curto, e dentro disso, passamos objeto, e aqui passamos o nome do nosso campo, que é nome, e aqui podemos passar dois valores, um, que é para ordem crescente e menos um para ordem decrescente Vamos passar os dois um por um. Primeiro, salve isso e vamos executar nosso aplicativo. Veja, temos usuários em ordem crescente, que significa de A a ZD. Se alterarmos isso para menos um, salve isso e vamos executar nosso arquivo novamente Veja, aqui temos a ordem decrescente, que é de Z a A, e é por isso que ele exibe har primeiro e depois o código, Deus o abençoe Não se preocupe, eu lhe darei PDF detalhado desta seção. Você pode revisar esses métodos o mais rápido possível. 66. Operadores de comparação no MongoDB: Vamos aprender sobre operadores de comparação em Mongodib. Operadores de comparação são usados para comparar valores no banco de dados com os valores que especificamos na consulta, e isso é muito importante quando estamos trabalhando com dados, especialmente dados baseados em números. Por exemplo, imagine que, nos dados de nossos usuários, preenchemos a idade e queremos buscar dados de usuários cuja idade seja 18 a 30 anos maior que 18 ou menor que 50 Pode ser qualquer coisa. Quando queremos fazer algo assim, precisamos de um operador de comparação. Existem muitos operadores de comparação no Mongo Deb. Primeiro, temos o EQ em dólares, que é igual a. Em seguida, temos o dólar N, que não é igual ao dólar GT, que é maior do que o dólar GT E. Você consegue adivinhar Certo, maior ou igual ao dólar LT, que é menor que um dólar LT por menos ou igual ao dólar E. Isso é usado para combinar qualquer um dos valores na lista. A idade deve ser 18, 22, 25, Pode passar vários valores na matriz. E, finalmente, temos o dólar NIN que não corresponde a nenhum valor na matriz, e é o oposto do dólar N. Os operadores de comparação são muito simples Deixe-me mostrar onde devemos escrever operadores de comparação. Então, para tornar isso prático, vamos adicionar o campo H para esses dois documentos. Então, Pan Mongo será uma bússola e vá para a coleção do usuário Aqui, podemos modificar cada documento usando esse ícone de edição. Em qualquer parte do campo. E no lado esquerdo, temos ícone de adição para adicionar um novo campo. Selecione adicionar novo campo e aqui escrevemos nosso nome de preenchimento, que é idade, e passamos o valor, digamos dez. Atualmente, esse tipo de valor é string, mas podemos alterá-lo a partir daqui e configurá-lo para o número inteiro 32 Veja, agora é inteiro. Além disso, adicionamos um novo campo para o segundo documento, nome do preenchimento, idade e valor, digamos 20. Quando mudamos um tipo para inteiro 32 e clicamos em Atualizar. Código. Agora, em nosso código, anteriormente, como podemos ver, se você quiser adicionar uma condição para nossa consulta, então adicionamos esse preenchimento no objeto aqui, como idade até dez. Isso buscará os dados de todos os usuários cuja idade seja de 0 a dez. Deixe-me fazer uma pergunta em que podemos escrever nosso operador lógico. Porque, como podemos ver, por condição, temos que passar um par de valores-chave nesse método find. Portanto, a solução está no lugar desse valor codal rígido dez, podemos escrever nosso operador de comparação em outro objeto Não se confunda, veja isso. Então, no lugar de dez, adicionamos o objeto e simplesmente escrevemos operador de comparação como chave nesse subobjeto Digamos que o dólar GTE, que é maior ou igual a, e maior ou igual 18. Então, isso significa simplesmente encontrar todos os usuários cuja idade seja maior ou igual a Basta substituir esse valor codificado dez pelo objeto e, dentro do objeto, usamos o operador de comparação Agora, deixe-me lhe dar uma pequena tarefa. Vamos remover todo esse objeto do método fino. Queremos buscar todos os usuários com menos de 18 anos. Aqui, adicionamos o objeto e, primeiro, adicionamos em qual campo queremos aplicar a condição, que é idade. E em vez do valor real, passamos aqui o objeto porque queremos usar o operador de comparação e, dentro dele, usamos dólar T para menos e menor que até 18. Simples assim. Salve esse arquivo e, para o método find, podemos executar nosso aplicativo usando o nodemon index dot js porque isso não mudará nada no Veja, aqui temos um usuário cuja idade é menor que 18 anos. Você pode ver que precisamos passar Objeto com operador de comparação no local do valor real. Além disso, esses seis primeiros operadores são muito simples, mas muitos estudantes confundem esse operador com e não com o operador. No local do valor, aqui temos que passar uma lista de valores. Então, deixe-me mostrar esses dois operadores. Suponha que queiramos buscar somente usuários com 18, 20 ou 30 Então, quando queremos comparar vários valores para um campo , usamos dólar no operador. Então, no lugar do dólar LT, usamos dólar in. No local do valor, passamos uma matriz de valores, 18, 20, 30. Simples assim, salve as alterações e dê uma olhada. Veja, aqui temos um usuário com 20 anos porque passamos 20 nesta matriz. Agora, dólar NN é o oposto de dólar em. Eu chamo isso de inside, o que significa usuários de patches cuja idade não é 18, 20 ou 30. Salve as alterações e veja, aqui temos um usuário com dez anos. Então é assim que passamos operadores de comparação no Mongo DV. Lembre-se de que, em condições normais, passamos aqui preenchimento com valores, mas para operadores de comparação, passamos aqui preenchimento com objeto e, dentro desse objeto, adicionamos nosso operador de comparação. 67. Operadores lógicos no MongoDB: Vamos ver os operadores lógicos. Portanto, os operadores lógicos nos permitem combinar várias condições em nossa consulta. Em palavras simples, eles nos ajudam a solicitar mais complexos do banco de dados. Não se preocupe Existem apenas alguns operadores lógicos e eles também são simples como operadores de comparação. primeiro operador lógico é dólar R. Usaremos o operador quando tivermos várias condições e quisermos, se alguma condição for verdadeira, retornar esses dados. Por exemplo, queremos buscar usuários com 30 anos de idade ou que tenham 30 anos de idade ou Nesse caso, queremos que qualquer condição seja verdadeira, e é por isso que usamos aqui o operador. Deixe-me mostrar isso na prática. Eu comento esse código anterior e escrevo que o custo dos usuários é igual ao await user dot Find E nesse método de busca, passamos Objeto, e nesse objeto, simplesmente adicionamos dólar ou operador. Agora você pode pensar em um operador de comparação no local do valor, mas estamos usando o operador lógico no local da condição. Deixe-me te dar minha trigonometria para lembrar. Como sabemos, sempre comparamos valores, e é por isso que temos que escrever operador de comparação no local do valor. Mas implementamos operadores lógicos para condições, e é por isso que temos que escrever operadores lógicos no local das condições. Quando comecei o Mongo Deb, eu me lembro dessa maneira. Como sabemos, queremos adicionar aqui várias condições e o que usamos para várias condições, usaremos array. Agora, dentro dessa matriz, adicionamos nossas condições em um objeto individual. Então, a idade do objeto é 30 ou passamos outro nome de condição H. Se alguma condição for verdadeira, obteremos os dados do usuário. As mudanças e dê uma olhada. Veja, aqui temos o usuário Halley porque seu nome é Halley A idade do usuário é igual à nossa condição ou não. Isso não importa. Se alguma condição for mesclada, obteremos esses dados Simples assim. Agora, suponha que queiramos nossa consulta. Essas duas condições devem ser verdadeiras, o que significa que a idade do usuário deve 30 e o nome também deve ser Halley Nessa situação, em que queremos, todas as condições devem ser verdadeiras. Usaremos o operador final. Então, no lugar desse operador, passamos por um operador. Agora, você consegue adivinhar a saída? Certo, não obtemos nada porque não temos dados em que a idade é 30 e o nome é h. Veja, aqui temos uma matriz vazia. Agora, deixe-me mostrar um atalho para escrever isso e o operador Quando queremos que todas essas condições sejam verdadeiras, já escrevemos a mesma consulta no início do tópico da consulta. Podemos transmitir diretamente essas condições no método find, como este. Ambos funcionam da mesma forma. Mas quando queremos usar o operador, precisamos seguir essa sintaxe Agora, depois do operador final do dólar, temos outro operador lógico que é o dólar NR, ou chamamos de NR lógico Por exemplo, queremos encontrar usuários que não tenham 30 anos e não tenham o nome Harley, o que significa que ambas as condições Para isso, no local desse operador final, passamos pelo operador NR. As mudanças e veja, aqui obtemos dados com o nome de Deus te abençoe porque, para esses dados, ambas as condições são falsas, e é por isso que obtemos esses dados Mas para nossos dados do segundo usuário, essa condição de nome é verdadeira, então não obtemos esses dados de forma simples. Agora, o último operador lógico que temos é dólar zero ou noz lógica Esse operador de nó lógico é um pouco diferente porque usamos apenas o operador not com operadores de comparação e expressões regulares Não se preocupe com a expressão regular. Veremos isso na próxima lição. Por enquanto, vamos ver, operador de dólar zero. Suponha que desejemos encontrar usuários cuja idade não seja igual a 30 anos. Novamente, eu comento essa sintaxe e escrevo novamente custo do usuário é igual a um ponto de busca do usuário de oito pontos Objeto, e primeiro, adicionamos preenchido para o qual queremos adicionar a condição, que é H. Agora, no local do valor, passamos o objeto com o operador dólar nu. Escrevemos operador de noz de dólar no local do valor porque operador de dólar zero está diretamente relacionado ao valor, não às condições Agora, o que queremos é que a idade não seja igual a 30, temos idade e também zero, mas não temos igualdade Adicionamos o outro objeto com o operador dólar, o que significa igual, e simplesmente passamos aqui Salve as alterações e dê uma olhada. Veja, aqui temos os dois usuários porque a idade de ambas não é igual a 30. Você pode ver que é muito simples. Deixe-me te mostrar mais uma vez. No operador de comparação, estamos escrevendo assim. Coluna de idade, dólar é igual a, maior ou menor que qualquer operador desejamos usar para seu Agora, aqui, queremos apenas adicionar o operador not, simplesmente envolvemos esse objeto com outro objeto e adicionamos aqui o operador dólar zero e dois pontos simples assim Sei que isso é um pouco confuso, mas não se preocupe se você não lembrar da sintaxe dos operadores Fornecerei minha folha de dicas no final desta seção para que você possa usá-la quando trabalharmos em Isso é tudo sobre operadores lógicos. Se você estiver assistindo continuamente ao curso, poderá fazer uma pequena pausa na tela, ouvir música ou fazer uma nova caminhada. Nos vemos na próxima aula. 68. Expressão regular no MongoDB: Agora vamos ver as expressões regulares. O que é expressão regular? Uma expressão regular é uma forma de definir padrões de pesquisa para cadeias de caracteres. Por exemplo, queremos encontrar todos os usuários cujos nomes comecem com edge ou queremos buscar todos os usuários cujo e-mail tenha gmail.com no final do Nesses casos, usaremos expressões regulares ou alguns desenvolvedores as chamaram de jx É muito útil em sugestões automáticas ou consultas de pesquisa. Deixe-me te mostrar de forma prática. Aqui eu comento essa consulta anterior. Além disso, remova consultas antigas e escreva uma nova consulta Cast users equals to await Aqui, passamos o objeto e em qual propriedade queremos aplicar o padrão de pesquisa. Vamos tentar o nome. Agora, no local do valor, passamos a expressão regular. Aqui está a sintaxe da expressão regular. Padrão de barra: barra. Então, com base nesse padrão, faremos muitas coisas. Suponha que desejemos encontrar todos os dados de usuários cujo nome comece com Então, no local desse padrão, usamos o símbolo Kerat, que significa começar com, e aqui passamos cptalH Essa consulta encontrará todos os usuários cujo nome comece com maiúscula. Portanto, se quisermos encontrar usuários cujo nome termine com qualquer letra , eu duplico essa linha e, no lugar desse quilate, escrevemos dólar Esse dólar significa acabar com. Portanto, essa consulta retornará todos os dados cujo nome termine com U. Agora, deixe-me dar uma pequena tarefa Queremos encontrar usuários cujo e-mail termine com gmail.com. É muito simples. Alteramos esse nome de preenchimento para e-mail e, simplesmente no local, escrevemos gmail.com dollar Vamos ver se obtemos os resultados ou não. Veja se as mudanças e C obtemos os dois usuários porque ambos têm gmail.com Agora deixe-me te mostrar uma coisa legal. No Mongo Di B Compass, altero o e-mail do segundo usuário no lugar do Eu escrevo para o Gmail, com. Salve isso e vamos ver o que temos. Salve esse arquivo. E veja aqui, temos, novamente, os dois usuários. Você pode se perguntar, mesmo esse e-mail não termine com gmail.com, por que ainda estamos recebendo esses dados do usuário O que há de errado com nossa expressão regular? Na expressão regular, esse período pode corresponder a qualquer caractere, o que significa que o JavaScript o corresponderá a qualquer caractere. E é por isso que, se passarmos qualquer caractere no local desse período, obteremos esses dados. Agora podemos perguntar: e se quisermos comparar período com período? Não como qualquer personagem. É muito simples. Pouco antes do período, usaremos a barra invertida Agora, o JavaScript comparará esse período como período, não como qualquer caractere. Salve as alterações e veja, aqui temos apenas o primeiro usuário. Além disso, esse padrão diferencia maiúsculas de minúsculas. Se algum usuário tiver um e-mail em maiúsculas, como gmail.com , não o incluiremos nessa lista Então, para remover a distinção entre maiúsculas e minúsculas, precisamos apenas adicionar I no final da nossa expressão regular. Agora, e se quisermos encontrar usuários cujo e-mail contenha Harley Não comece com Halle nem termine com Halley. A Harley pode estar em qualquer lugar. Então, nesse caso, simplesmente escrevemos nossa palavra no local do padrão sem adicionar sótão ou dólar Então, se quisermos encontrar usuários com a palavra exata, digamos desenvolvedor na descrição, não parte de outra palavra como desenvolvedor, queremos apenas desenvolvedor. Nesse caso, escrevemos um padrão como esse. Aqui, no lugar desse padrão, escrevemos essa palavra, que é desenvolvedor, e antes e depois dessa palavra, adicionamos B invertido, B invertido, o que representa o limite dessa Essas são algumas expressões regulares comuns e úteis. Se você quiser aprender mais sobre padrões de expressões regulares, use este artigo e leia sobre outros padrões porque é puro JavaScript. Além disso, na versão atual do Mangodib, poucos desenvolvedores usam o dollar RejxOperator no lugar de adicionar padrões diretos Ambos funcionam da mesma forma. Eu gosto dessa versão do Sater, mas você também pode usar esse operador Rjx Depende totalmente de você. 69. Conte e estime a quantidade de documentos: Suponha que desejemos contar o número de documentos disponíveis na coleção do nosso usuário. Eu dupliquei essa consulta e comento a consulta anterior. Agora, quando queremos contar apenas o número de documentos , no lugar desse método fino, passamos o método count Documents. Essa consulta funciona da mesma forma que antes. Recebemos vários dados na saída. No método Count documents, passamos nossas condições ou também passamos operadores lógicos, operadores de comparação, expressões regulares, mesma forma que o método find. método Find retorna os dados reais, enquanto o método Count documents retornará o número do documento. Vamos verificar isso. Veja as mudanças e dê uma olhada. C, aqui obtemos zero porque não há dados para essa condição. Agora, às vezes, não queremos adicionar nenhuma condição, apenas queremos a contagem total de documentos. Nesse momento, podemos remover esse objeto, salvá-lo e ver, aqui obtemos o número total de dados dos usuários. Agora, atualmente, nossos dados são muito pequenos. Imagine que queremos contar o número de produtos para grandes aplicativos de comércio eletrônico Deseja exibir o número total de produtos disponíveis na plataforma no painel de administração. No momento, não precisamos da contagem de texto que mostre o número total de produtos. Agora, naquele momento, podemos usar outro método para contar o número estimado de documentos, que é a contagem estimada de documentos. Como o próprio nome sugere, essa é uma contagem estimada. Assim como contar documentos, podemos passar esse método de contagem estimada de documentos logo após o nome do modelo. Agora você pode perguntar: qual é a diferença entre esses dois? A primeira é que a contagem de documentos retorna o número exato, mas a contagem estimada exibe a contagem aproximada Outra diferença é que podemos passar condições ou filtros no método de contagem de documentos. Mas no método de contagem estimada de documentos, não podemos aprovar nenhuma condição. Só pode contar a coleção completa. Portanto, a contagem de documentos é um pouco lenta do que a contagem estimada de documentos. Então, para resumir, usamos documentos de contagem quando precisamos aplicar filtros ou queremos obter a contagem de saídas Por outro lado, usamos a contagem estimada de documentos quando precisamos uma estimativa rápida e aproximada do número total de documentos na coleção. 70. Paginação e consulta infinita: Vamos ver como podemos criar paginação ou consulta infinita. Antes de vermos a consulta, é melhor entendermos como a paginação e a rolagem infinita Suponha que estejamos trabalhando em um grande aplicativo de comércio eletrônico. Neste aplicativo, podemos ter 1.000 ou 10.000 produtos como a Amazon. Agora, no momento, temos todos os produtos detalhados em uma única chamada de API. Isso levará mais tempo e a carga em nosso servidor também aumentará. Então, em vez de obter todos os dados em uma única solicitação como desenvolvedor do Bond, podemos dividi-los em páginas como se tivéssemos apenas oito ou dez dados em uma única solicitação. Se o usuário precisar de mais dados , buscaremos os próximos dez dados Não se preocupe em como criaremos essa API. Por enquanto, basta entender como funcionam a paginação e a rolagem infinita Aqui está o exemplo de paginação no front-end. Na primeira página, temos apenas oito dados. Depois disso, quando clicarmos no botão da segunda página, obteremos os próximos oito dados. Simples assim. Deixe-me mostrar também um exemplo de rolagem infinita. Aqui temos oito dados e, quando chegarmos ao final da página, ele carregará outros oito dados do back-end. Veja, isso é muito legal. Agora, pense em linguagem humana, que está acontecendo aqui. Não se preocupe com o código. Pense no que está acontecendo. A paginação e a rolagem infinita funcionam quase da mesma forma. Em ambas as técnicas, buscaremos dados em pequenas quantidades, conforme necessário Apenas na rolagem infinita, mantemos nossos dados anteriores Nessa paginação, substituiremos os dados anteriores. Mas o back-end das duas técnicas permanecerá o mesmo. Deixe-me explicar com um exemplo de 20 registros. São 20 registros por vez, queremos mostrar apenas quatro registros. Podemos definir a página variável por dados para quatro. Recebemos quatro registros daqui e podemos marcá-los como página um. Agora, se os usuários rolarem ou até mesmo passarem para a segunda página, ignoraremos os dados da página um, o que significa que pularemos quatro dados por página e, em seguida, buscaremos outros quatro registros Em seguida, quando o usuário rolar novamente ou passar para a terceira página, pularemos os dados da página um e da página dois Matematicamente, pularemos a página atual, que é três menos um em cada página de dados, que significa que dois em quatro é igual Ignoramos os primeiros oito dados e buscamos outros quatro, que são dados por página Toda vez que aumentamos nosso número de página, pulamos a página atual menos um para dados por página e buscamos outros dados, que são o número de dados por Diga-me quantas vamos pular quando passarmos para a quarta página Certo, vamos pular quatro menos um, que é três em quatro, que é 12 Ignoramos os primeiros 12 registros e buscamos outros quatro dados. Simples assim. No Mongoose, temos o método skip, que vimos anteriormente, e também temos limite para apenas a busca e Então, aqui removemos essa consulta porque ela pode criar confusão. Agora escrevemos const users equals to await user dot. Encontre aqui, não queremos passar Agora, após o método fino, adotamos o método Skip e, dentro dele, temos que passar quantos dados queremos pular Por enquanto, passamos diretamente zero porque, na primeira página, queremos pular zero dados Depois disso, quantos dados queremos em nossa única página? Certo, queremos enviar quatro dados. Então, adicionamos aqui outro método chamado limite e passamos aqui quatro. Essa consulta funciona na primeira página. Agora, vamos fazer com que essa consulta funcione para todas as páginas. Então, quando você pesquisa uma página para duas e chama essa API, simplesmente pulamos os primeiros quatro dados E para isso, criamos a fórmula em nosso exemplo. Então, no topo, definimos variável. A página atual é igual a, digamos, dois. E depois disso, outra variável chamada de dados por página é igual a quatro. Atualmente, como podemos ver, codificamos esses valores Mas no mundo real, esses valores são passados pelo front-end. E você sabe por qual front-end envia esses detalhes? Alguma suposição? Certo, o front-end enviará esses detalhes usando parâmetros de consulta. Suponha que nossa API de produtos tenha esta aparência, API de barra, produtos de barra, ponto de interrogação, página atual seja igual a dois e os dados por página sejam iguais a quatro ou dez, qualquer coisa que nosso desenvolvedor de front-end Mas, por enquanto, não quero adicionar essa complexidade. É por isso que codificamos esses valores aqui. Agora, neste método kip, passamos parênteses, página atual menos um em E no limite, o que vamos passar, né, passamos dados por página e pronto. Deixe-me salvar isso para que possamos ver isso claramente. Ótimo. Agora, se verificarmos nosso terminal, obteremos uma bandeja porque, em nosso banco não temos mais do que quatro dados, então não obtemos dados por página dois. Se mudarmos a página atual para uma, salve isso e veja aqui os dados. Criamos uma consulta para paginação e rolagem infinita. Essa consulta única funcionará para os dois recursos. Espero explicar isso bem. Se você ainda tiver confusão, tente colocar valores diferentes nessas variáveis. Aposto que você vai entender isso. 71. Atualize os dados: Agora vamos ver como podemos atualizar os dados no Mongo DB. Portanto, há duas maneiras de atualizar os dados. No primeiro método, encontraremos primeiro o documento que queremos atualizar. Depois disso, modifique sua propriedade e, por fim, salvamos os dados atualizados em nosso banco de dados. E o segundo método é usar métodos de atualização de mangas e atualizar diretamente o documento no banco de dados Depois disso, temos a opção de retornar dados atualizados de acordo com nossas necessidades. Agora, o que você acha , qual método é rápido? Agora, o que você acha que método é útil? Sim, o segundo método é mais útil porque, no primeiro método, precisamos executar várias etapas, o que pode levar um pouco de tempo. Mas no segundo método, usaremos métodos definidos por mangas, então não precisamos nos preocupar em atualizar os dados sozinhos Além disso, usaremos o primeiro método de acordo com nossas necessidades. Agora, existem quatro métodos para atualizar o documento. Não se preocupe Cada método é muito simples e fácil. Deixe-me te mostrar isso. Aqui eu abro o projeto de demonstração do MongoDB E aqui, vamos supor que queremos atualizar nosso ID de e-mail de usuário cujo nome é code bless. Então, criamos aqui uma função sing chamada Update User. E dentro dessa função, escreveremos nossa lógica de atualização. Então, para Update, usamos o módulo dot do usuário. Aqui temos o método Update one. Agora, da mesma forma que o método fine, podemos passar aqui um objeto de consulta no qual aplicaremos filtros ou podemos dizer condição. Então, qual é a condição aqui? O nome de usuário deve ser code plus. Então, declaramos qual usuário queremos atualizar. Agora só precisamos passar qual propriedade queremos alterar. Então, para isso, passamos outro objeto no segundo parâmetro, e dentro dele, temos operador de conjunto de dólares e passamos para o objeto. Agora, neste objeto, especificaremos qual propriedade queremos alterar com seu valor atualizado. Então, queremos mudar o e-mail para atualizado no gmail.com vermelho Assim, podemos aderir a várias propriedades. Mas, por enquanto, queremos apenas mudar o e-mail. Agora, como sabemos, essa expressão é tarefa de Asnruners. Então, podemos aderir, aguardar. Deixe-me salvar para que possamos ver corretamente. Bom. Agora, essa expressão não retornará o objeto atualizado. Vamos ver o que temos aqui. Então, nós o armazenamos em uma variável chamada resultado e, simplesmente na parte inferior, console registra esse resultado. Também no lugar dessa função de usuário do Gate, chamamos a função Atualizar usuário. Agora, antes de salvar as alterações, certifique-se de interromper o aplicativo. Agora salve as alterações e dê uma olhada. Execute este aplicativo usando node index dot js. Veja, aqui não obtemos dados atualizados do usuário, mas obtemos algumas informações básicas sobre a tarefa ddt. Vamos verificar como os dados são atualizados no banco de dados ou não. Então, Pamongo seja bússola e veja aqui nosso e-mail foi alterado para updated@gmail.com Então é assim que atualizamos os dados. Primeiro, passamos o objeto de consulta com condições e, no segundo argumento, passamos o operador dollar set e passamos o objeto com propriedades e valores atualizados. Simples assim. Mas lembre-se também de que esse método de atualização atualizará apenas um documento, não todos os documentos que atendam a essa condição. Às vezes, também queremos obter o documento atualizado. Não se preocupe, é muito simples. No local da atualização um, passaremos por find one e atualizaremos. Isso retornará o documento antigo antes da atualização. Mas aqui queremos obter o documento atualizado. Esquecendo o documento atualizado, passamos aqui, terceiro objeto, e nele passamos de novo para verdadeiro Além disso, como uma boa prática, passaremos outra opção aqui, que é executar validadores para True Agora você pode perguntar o que são validadores de execução? Não é nada que estejamos dizendo à nossa consulta para garantir que esses valores atualizados sigam o esquema do modelo Além disso, deixe-me alterar esse valor de e-mail para blessthergml.com. As mudanças e dê uma olhada. Vamos executar esse aplicativo novamente. Veja agora que obtemos aqui o valor atualizado. É assim que podemos atualizar valores usando o método update one e find one and update. Ambos são muito parecidos. Atualize um, não devolva o documento atualizado. Ao usar find one e update, obtemos o documento atualizado, mas ambos atualizam apenas um documento. Agora, deixe-me dar uma pequena tarefa aqui. Queremos atualizar o nome do usuário cujo ID é esse. Você pode escrever a consulta? É muito simples. Aqui no objeto de consulta no local do nome, passamos o ID de sublinhado e passamos aqui nosso ID de usuário em string Você pode copiar seu ID de usuário do Mongo DB Compass e também alterar esse valor de e-mail para XYZ Salve as alterações e dê uma olhada. Execute esse aplicativo. Veja aqui que obtemos o documento atualizado. Adorável. Então, isso é muito simples. Muitas vezes, queremos encontrar nosso documento apenas com base em seu ID exclusivo, como fizemos atualmente. Não queremos aprovar nenhuma outra condição porque esse ID é exclusivo e não adianta passar por outras condições. Quando queremos atualizar os dados usando seu ID no local de localizar um e atualizar o método, temos outro método de atalho, que é localizar por ID e atualizar Agora, aqui não precisamos passar esse objeto de consulta. No lugar disso, passamos diretamente nosso ID em string. As mudanças e dê uma olhada. Execute esse aplicativo. Veja, novamente recebemos o documento atualizado. Então, quando quisermos encontrar o usuário por seu ID, usaremos fine by ID e atualizaremos. Agora, vimos esses três métodos de atualização. Atualize um, encontre um, atualize e encontre por ID e atualização. Se você notar, todos esses métodos atualizam apenas um único documento que eles encontraram primeiro. Dois, atualize um, encontre um e atualize seus nomes mostrando que eles estão atualizando apenas um documento. E se falarmos sobre multa por ID e atualização, o que estamos passando aqui como condição, passamos um ID exclusivo, o que significa que ele também atualizará apenas um único registro cujo ID seja esse. Mas e se quisermos atualizar vários documentos? Para isso, temos o quarto método de atualização, que é atualizar muitos. No local dessa multa por ID e atualização, adicionamos muitas atualizações. Então, aqui temos que passar novamente seu objeto de consulta no qual definiremos as condições. Então você passa sua idade para 20. Então, aqui estamos dizendo para atualizar nossos registros cuja idade é 20 e atualizar seus e-mails para esse valor. Deixe-me alterar esse valor de e-mail como hegmil.com. Não precisamos desse terceiro argumento, que são opções, porque isso só funcionará para finalizar e atualizar e localizar por ID e atualização. Veja as mudanças e vamos executar esse aplicativo. Veja, novamente, não recebemos documentos atualizados, mas se verificarmos nosso banco de dados, nosso valor será atualizado. Então, para resumir rapidamente, temos quatro métodos para atualizar dados no Mongo DB Atualize um para atualizar um único documento, atualize vários para atualizar vários documentos, encontre um e atualize para localizar e atualizar um único documento em uma etapa, última, localizar por ID e atualizar para encontrar um documento por ID e atualizá-lo. Além disso, em find one and update, e find by ID and update method, passamos o objeto Option no qual definiremos new como true para obter novos dados atualizados e executaremos validadores como true para seguir o esquema do modelo para valores atualizados. Simples assim. 72. Atualize operadores no MongoDB: Agora vamos falar sobre operadores de atualização. Os operadores de atualização são usados para modificar documentos durante uma operação de atualização. Em palavras simples, os operadores de atualização nos permitem atualizar preenchimentos específicos, incrementar valores, definir novos dados, remover preenchimentos e Deixa eu te dizer uma coisa. Já usamos um operador de atualização, que é definido em dólares, mas temos muitos outros operadores de atualização. Então, vá até o navegador e digite operadores de atualização no Mongo DB Abra este primeiro link e aqui podemos ver que temos operadores de atualização, como data atual do dólar, para definir o valor do preenchido até a data atual. Tinta em dólar para incrementar o valor do preenchimento em uma quantidade específica Suponha que alguém goste da postagem, para que possamos usar o Operador de tinta de dólar para aumentar o valor do preenchimento. Também no operador de tinta, podemos passar valores negativos que podem diminuir a contagem. Em seguida, temos mean, max, ML para multiplicação, renomear, definir, definir na inserção, definir para remover o campo do documento Também na parte inferior, temos operadores para arrumar, puxar, empurrar, puxar tudo, etc Não se preocupe com esses operadores. Usaremos muitos deles em nossos projetos futuros. Por enquanto, eu só quero apresentar esses operadores de atualização. Na próxima lição, veremos como podemos excluir um documento do MongoDB 73. Exclua os dados com: Agora vamos ver como podemos excluir dados do Mongo Div. É muito semelhante à atualização dos dados. Temos quatro métodos para excluir os dados. Exclua um, exclua vários, encontre um e exclua, e o último, localize por ID e exclua. Agora você entende por que eu dedico mais tempo para explicar os métodos de atualização. Eles são muito semelhantes aos métodos de exclusão. Vamos ver rapidamente esses métodos de exclusão. Aqui, criamos uma nova função ASN chamada delete user. Agora, dentro disso, usamos o usuário dot Delete one e o que passaremos nesse método. Nós apenas passamos o objeto de consulta porque aqui queremos apenas excluir o documento. Não precisamos especificar o que queremos atualizar, podemos passar algo como esse ID de ascore para algum ID de usuário, que copiei da bússola Mongo Dib Isso removerá esse único usuário com seu ID. Agora podemos aderir ao await, mesma forma que antes, e simplesmente armazenar seu resultado de forma invariável Esse resultado é o objeto com propriedade de exclusão. Não recebemos aqui o documento. Agora, deixe-me te perguntar uma coisa. E se quisermos incluir esse documento excluído no resultado? Qual método usaremos? Podemos usar aqui, encontrar um e excluir. E aqui, não precisamos mudar nada. Portanto, no lugar da correção e do método delete, podemos usar o método fine by ID e o método delete. Mas quando usamos fine by ID e delete, não precisamos passar aqui o objeto com a propriedade ID. Podemos passar diretamente assim. Não quero me emprestar mostrando esses métodos porque eles são quase iguais, certo? Imagine que queremos excluir todos os usuários idade superior a 15 anos e que eles também não tenham sido verificados. É muito simples. Usamos aqui, excluímos muitos métodos e, no blas desse ID, passamos o objeto de consulta e, dentro dele, idade deve ser maior que 15 E outra propriedade é verificada como falsa. Agora, vamos registrar esse resultado com pontos no console. E no lugar de chamar a função Atualizar usuário, chamamos a função de usuário excluída. Salve as alterações e vamos executar esse aplicativo. Veja, aqui excluímos a contagem até um porque apenas um documento está cumprindo essa condição E se verificarmos nosso banco de dados , veremos que temos apenas um documento. Então, isso é tudo sobre a operação de exclusão. É muito mais simples do que atualizar os dados. 74. Exercício 01 — Configurando o MongoDB: Agora é hora de se exercitar, você pode praticar sozinho tudo o que aprendeu nesta seção. Abra nosso primeiro projeto, Task Track, que deixamos na Seção cinco. Podemos praticar nesse projeto. Se você não tem um código de projeto anterior, não se preocupe, você pode baixá-lo abaixo desta lição. Agora, eu crio este exercício para você seguir várias etapas do Mongo DB Em primeiro lugar, primeiro passo, quero que você conecte este projeto ao banco de dados Mongo DB Você pode dar um nome a esse banco de dados, faixa de tarefas ou qualquer coisa. Depois de se conectar com sucesso ao banco de dados na etapa dois, você precisa criar um esquema para armazenar o Tudous Em seu projeto, crie uma nova pasta chamada models e dentro dessa pasta, crie um novo arquivo chamado Tudous dot js Nesse arquivo, você precisa definir o esquema e modelo para a coleção Tudos separadamente de nosso outro código, e os preenchimentos devem ser Primeiro, tivemos uma tarefa na qual definiremos o texto para esse Tudo. Certifique-se de que esse preenchimento seja obrigatório. próximo preenchimento que temos é o status, que pode ser Tudo feito ou feito. É preciso pensar em qual tipo de campo você deseja usar. Além disso, o valor padrão desse campo deve ser fazer. Agora, o último campo é texto, que é a área de valores na qual podemos adicionar textos de idiomas relacionados, como SDML, CSS, JavaScript, react, node, etc., e pronto para esse esquema Agora, a etapa número três, com base nesse esquema, precisa definir um modelo para a coleção de Tudou Simples. Eu sei que você pode fazer isso. Também adiciono este PDF de instruções de exercícios abaixo desta lição. Além disso, não se preocupe se você não se lembra dos métodos do Mongo DB Você pode usar o PDF resumido que eu adicionei no final desta seção. O objetivo deste exercício é que você conclua o processo das etapas do Mongo DB Então, dê seus 100% e veja a solução. Espero que você resolva este exercício ou tente resolvê-lo e siga uma dessas etapas. Não se preocupe, pelo menos você tenta resolver isso. Então, dê crédito a si mesmo por isso. Agora vamos ver a solução. Primeiro de tudo, em nosso projeto, temos que instalar mangas porque sem Ted não podemos fazer nenhuma outra coisa Então, o NPM instala mangas no vermelho 8.8 0.0. Deus. Vamos minimizar esse terminal. Agora, em nosso arquivo JS de pontos de índice, na parte superior, inserimos const mangos é igual a require E depois dessa rota do Studos, escrevemos mangos dot Na primeira discussão, passamos um anel em excesso, que é Mongo DV, dois pontos, barra dupla para frente coluna 27017 é cortada e aqui escrevemos o nome do nosso banco de dados, que é Agora, como sabemos, essa expressão retorna uma promessa. Por isso, usamos o método e, dentro dele, basta consultar o log de pontos Mongo DB conectado com sucesso. Agora, e se obtivermos um erro nisso? Então, também adicionamos o método de cache. Aqui, obtemos o objeto de erro, função de erro e o registro de pontos do console. Conexão MongoDB preenchida. E imprima esse erro. Então, a etapa número um está concluída. Agora, etapa número dois, temos que definir o esquema para a tarefa. Então, criamos uma nova pasta em nosso projeto chamada models. E dentro dessa pasta, criamos um novo arquivo chamado todos dot js. Agora você pode perguntar por que precisamos criar um novo arquivo? Não podemos defini-lo em nosso arquivo js de pontos de índice. Sim, podemos definir o esquema e modelos no arquivo JS de pontos de índice Mas imagine que nosso projeto tenha cinco modelos diferentes. Pense em como nosso código se tornou confuso: adicionamos cinco esquemas e modelos diferentes em nosso arquivo JS de pontos de índice Essa é a prática do mundo real. Definiremos todos os modelos e seus esquemas na pasta separada, que é models E seja qual for o modelo que queremos criar, damos seu nome ao arquivo. Nesse caso, é Tudos dot js. Aqui, primeiro importamos mangas Cs, o que equivale a exigir mangas Depois disso, criamos um novo esquema de pontos do Mongoose e, dentro dele, passamos nossos preenchimentos A primeira é a tarefa, e nós a configuramos como string. Mas também queremos tornar esse preenchimento obrigatório. Então, no lugar dessa string, passamos propriedades diferentes no objeto. Digamos que digite para string e requerido para true. Em seguida, temos estatísticas para objetar, novamente, digite duas strings. E aqui queremos dar os valores do campo. Então, escrevemos a propriedade Enum na matriz e aqui passamos valores O primeiro é fazer, depois podemos fazer, e depois escrevemos pronto. Então, se tentarmos inserir qualquer quarto valor , esses valores, isso não funcionará. Além disso, queremos fornecer seu valor padrão, então default e o configuramos como todo. Bom. Agora, a seguir, temos texto, que é uma matriz de string. Podemos passar diretamente aqui a matriz e dentro dela, passamos a string Done. Nosso esquema está pronto. Vamos armazená-lo em uma variável chamada esquema Tds. Vamos para a terceira etapa. Você se lembra de como podemos definir o modelo? Usamos o modelo de pontos de manga. Aqui, primeiro passamos o nome singular da nossa coleção, que é Todo, que se tornará a coleção Todos. No segundo argumento, passamos o esquema Todos. Agora, isso retornará o modelo de tarefas. Vamos armazená-lo em uma variável chamada todo. Certifique-se de usar seu caso de pascal porque esses todos funcionam como uma classe JavaScript. Concluímos nosso primeiro exercício. Na próxima lição, avançaremos um pouco. 75. Exercício 02 — para armazenar dados: Agora vamos passar para o segundo exercício, no qual relembraremos a inserção de dados no Mango Então, aqui está o exercício da Instrução em PDF. Você também pode baixá-lo do lado direito. Além disso, adicionei um arquivo JSON no qual adicionei oito registros para Todos Agora, neste projeto, já temos uma API para criar novas tarefas. Mas nessa API, estamos simplesmente enviando novos dados para nossa matriz local Em vez disso, queremos armazenar dados em nossa coleção de todos. Deixe-me dar uma pequena dica. Podemos fazer qualquer coisa na coleção usando o modelo. Você precisa obter o modelo da pasta de modelos e usá-lo aqui. Aqui está uma pequena demonstração para você. Quando enviamos uma solicitação pós-API com esse objeto JSON, no back-end, armazenamos esses dados em nosso banco de dados e retornamos os dados armazenados na resposta Já fizemos isso nesta seção. Você também pode usar esse código de seção atual como referência. Tente resolver isso e depois observe a solução. Então, espero que você resolva ou tente resolver. Agora vamos ver a solução. Primeiro de tudo, temos que inserir registros em nossa coleção de todos. Mas sabemos que estamos fazendo qualquer coisa com a coleção, precisamos desse modelo. Como podemos obter o modelo Tudo aqui neste arquivo de rotas do Tu Dos? Certo, temos que exportar nosso modelo do Tudos Model five. Então, escrevemos aqui, o módulo dot Exports é igual a esse modelo Tudo Isso exportará esse modelo Tudo como padrão. Guarde isso. No TudosRout na parte superior, importamos Const Tudo é igual a require, agora estamos na pasta de rotas e queremos acessar a pasta e queremos acessar a Então, temos que voltar para nossa pasta usando modelos de barra dupla de pontos e dentro desse arquivo todos dot js Bom. Portanto, temos o modelo Todo neste arquivo. Agora, vamos armazenar rapidamente esses dados de Todos dentro da coleção. Então, passamos para a solicitação post, que criamos para adicionar novas coisas para fazer dentro de nossa matriz local. Em primeiro lugar, podemos comentar esse método Tudos array dot push e, no lugar disso, podemos escrever Nu to do E aqui nós desmaiamos para fazer um objeto. A primeira propriedade é a tarefa, e como podemos obter a tarefa? Logo na parte superior, pegamos o corpo da solicitação e o armazenamos na variável do. Então, na parte inferior, escrevemos para fazer o dot Task. Em seguida, temos o status, que novamente obtemos do status de pontos Tudos e também das tags das tags Todo dot Aqui não estamos adicionando o ID porque ele será gerado automaticamente pelo MongoDB Anteriormente, nesta seção, usamos aqui valores codificados, mas aqui estamos usando valores que obtemos no corpo da solicitação Simples assim. Agora, isso retornará um objeto New to do e, para salvá-lo, escrevemos aqui Nut dot save. Como já sabemos, essa é uma tarefa de executores assíncronos. É por isso que usamos here away. Mas veja aqui que estamos recebendo um erro de tempo de execução. Para usar o Avid, precisamos tornar nossa função assíncrona. Mas como, aqui nesta API, nossa função é começar a partir da solicitação e resposta a esse suporte de CR. Agora, para tornar essa função assíncrona, antes desse parêntese, passamos antes desse parêntese, passamos uma palavra-chave. Simples assim. Veja, o erro desapareceu. Agora, essa expressão retornará os dados armazenados do banco de dados. Então, nós o armazenamos em dados armazenados variáveis const. E então enviamos esta loja para fazer a resposta. Agora vamos ver se isso está funcionando ou não. Salve as alterações e vamos executar esse aplicativo usando o nodemon index dot js Um bom servidor está funcionando e também conectamos o Mongo Db com sucesso Perfeito. Agora, usando nossa extensão de cliente de licitação, enviaremos uma solicitação postal. Já salvamos essa API de criação para fazer, então usaremos isso diretamente aqui no corpo da solicitação, em vez de usar o formulário codificado, usaremos JS e formato Facilitará nossa tarefa. Agora abra o JSnFle que eu anexei com esta lição. Você pode fazer o download enquanto baixa o PDF no lado direito. Agora, simplesmente, copio o primeiro objeto a ser feito e o colo no corpo da solicitação. Além disso, certifique-se de inserir uma API de prefixo na URL e envie a solicitação Veja, aqui obtemos nossos novos dados com ID gerada automaticamente. Além disso, podemos verificar que no Mongo DBCompass, veja, aqui obtemos os Agora eu avanço rapidamente esta lição e, uma por uma, insiro todas as tarefas. Bom. Você pode ver como estamos progredindo e resolvendo cada exercício passo a passo No mundo real, também, você tem que trabalhar passo a passo. Dessa forma, você fica menos confuso e trabalha com facilidade. 76. Exercício 03 — colhendo dados: Agora é hora do terceiro exercício, que eu desenvolvo para buscar os dados Depois de adicionar vários valores na coleção, quero que você escreva uma consulta para essa coleção. Já temos um método G para buscar todas as tarefas. Você pode escrever todas as consultas uma a uma aqui e concluir o exercício primeira consulta do exercício três é que queremos buscar todos os dados do dos Depois disso, a segunda consulta é Fatudos, que tem tag, react. Terceira consulta, isso é um pouco complicado. Festuds que têm a tag STML e também um status devem ser Tudo. Depois disso, a quarta consulta conta o número de Tudos cujo status está definido como concluído última quinta consulta é faz tudos, em que tarefa, existe a palavra criar, somente a palavra criar Não deve incluir recreate created, apenas create e também certifique-se de ignorar a distinção entre maiúsculas e minúsculas aqui Como você sabe, você pode usar meu resumo em PDF se não se lembrar dos métodos e resolver este exercício. Isso aumentará sua confiança e é assim que você aprenderá em quais coisas precisa se concentrar mais. Além disso, se você estiver confuso em uma consulta, poderá prosseguir com outras consultas e resolver outras consultas Então, espero que você tente resolver esse exercício. Agora, vamos ver rapidamente a solução. Para a primeira consulta, para buscar todas as tarefas do banco de dados, aqui temos essa GPI na qual estamos retornando diretamente essa matriz de todos Mas agora queremos buscar dados do banco de dados e, em seguida, retornaremos esses dados Então, aqui escrevemos todo dot find. Queremos todas as tarefas, então aqui não aprovamos nenhuma condição. Agora, essa expressão é promessa. Podemos esperar aqui e armazenar esses dados em uma variável chamada todos Agora, aqui temos um erro de tempo de execução. Você pode me dizer como podemos resolver isso? Tornamos nossa função função assíncrona e, no final, enviaremos esses todos como resposta Salve as alterações e vamos chamar isso de GTI PI. Aqui não temos esse GIPI, então criamos uma nova solicitação e, na URL, passamos a coluna do host local 3.000 API SLAStudos Veja, aqui temos a lista de Tudos. Então, resolvemos a primeira consulta. Agora vamos passar para a segunda consulta. Neles, temos que corrigir todos os que têm a tag react. Eu dupliquei essa linha e comento a primeira consulta, agora para descobrir uma única string está disponível na matriz ou não Não precisamos fazer nada de especial. Passamos diretamente aqui, objeto, e adicionamos aqui condição, texto e, em string, escrevemos nossa palavra-chave, que é react. Se na matriz de texto houver algum elemento, igual a essa reação, então fazemos isso. Além disso, podemos fazer o mesmo usando o operador in. Ambos funcionam da mesma forma. Salve as alterações e vamos enviar essa solicitação. Veja, aqui temos três coisas para fazer e todas têm a tag react. Agora vamos passar para a terceira consulta, que é fast todos, que tem a tag STML e seu status deve ser fazer Então, no local dessa tag react, passamos STML e passamos outro status de condição para to do Portanto, podemos usar seu operador de dólar, mas já sabemos que ele também funciona da mesma forma que aquele operador. Salve as alterações e dê uma olhada. Envie a solicitação. Veja, aqui chegamos a Tudos Ótimo. Agora vamos passar para a quarta consulta, na qual temos que contar o número de tudos cujo status está definido como concluído Deixe-me te perguntar uma coisa. Devemos usar seu método fino ou contar o número de tudos? Não, temos outra coisa. Você se lembra que sim, usamos o método de contagem de documentos. Então, substituímos esse método fino por documentos de contagem, e aqui passamos status da condição para D. Salve as alterações e dê uma olhada. Veja, aqui temos cinco, que significa que o status de cinco tarefas foi concluído. Agora temos a última consulta, que é buscar tarefas em qual tarefa existe a palavra criar Aqui, adicionamos novamente método fino e, no local dessa condição de status, temos uma tarefa e aqui temos que usar a expressão regular porque estamos trabalhando com string. Agora, você se lembra da sintaxe da expressão regular? Sim, é uma barra padrão. Agora, para pesquisar uma palavra específica, usamos Backwards B, criamos Bwards B. Para tornar essa palavra insensível a maiúsculas e minúsculas, usamos aqui, I, salve as alterações e dê uma olhada Envie a solicitação e veja aqui que obtemos três registros nos quais criamos o Word na tarefa. É assim que buscamos dados do banco de dados no mundo real. Espero que você tenha uma ideia do que estamos aprendendo. 77. Exercício 04 — Atualização e remoção de tarefas: Agora vamos para o quarto exercício. Não se preocupe, você pode resolvê-lo em apenas dois a 3 minutos. Neste projeto, também colocamos um método de atualização específico para fazer por meio de seu ID. A primeira consulta deste exercício é atualizar a tarefa específica por sua ID e somente alterar o texto da tarefa para atualizado para fazer. Como você precisa retornar essa atualização para fazer na resposta. Aqui você pode copiar qualquer ID de objeto da passagem Mongo Di BC e passá-la no parâmetro de consulta Depois disso, a segunda consulta é você precisa atualizar todos os documentos cujo status atual está funcionando e atualizar esses status com De. Além disso, aqui você não precisa criar uma nova API. Você pode simplesmente escrever apenas a consulta de atualização e verificá-la quando eu mostrar a solução. Na última terceira consulta, você precisa excluir uma tarefa específica pelo ID. Aqui, você também pode usar qualquer ID da bússola Mongo Divi E depois que o processo de exclusão for concluído, você precisará retornar o objeto com a propriedade de mensagem para que ele seja excluído com êxito E para excluir a consulta, você pode usar a API delete em nosso código. Esses são exercícios bem simples. Você pode usar o PDF de resumo ou observar a sintaxe. Não se preocupe se precisar observar a sintaxe dos métodos. Até às vezes eu esquecia a sintaxe. Portanto, não se preocupe com a prática, você conhecerá essa sintaxe Então, espero que você resolva este exercício ou tente resolver este exercício. Dê crédito a si mesmo por isso. Agora, vamos ver rapidamente a solução. Portanto, a primeira consulta é que precisamos atualizar a tarefa específica por seu ID e alterar apenas o texto da tarefa para atualizá-la por completo. Então, aqui temos o ID, que estamos obtendo dos PAMs de pontos de solicitação Agora, do corpo, precisamos apenas de uma tarefa para que possamos remover outros preenchimentos. Não precisamos desse código porque escrevemos essa lógica para a matriz local. Mas agora temos os métodos do MongoDB. Podemos escrever aqui para fazer pontos. Agora, qual método usamos aqui? Devemos usar Atualizar um, encontrar um e atualizar, tudo bem por ID, e atualizar ou atualizar muitos? Sim, podemos usar qualquer um desses quatro. Mas aqui, temos que devolver o documento atualizado. Portanto, duas opções são simplesmente removidas, que são atualizar um e atualizar muitos porque essas duas não retornarão o documento atualizado. Agora temos apenas duas opções. Qual deles é mais simples? Temos que atualizar para fazer com o ID. Então usamos aqui, find by ID e update, e aqui passamos esse ID. Além disso, não precisamos converter esse ID em número inteiro porque o ID do objeto Mongo DV é uma string Agora, no segundo argumento, passamos objeto com operador de conjunto de dólares e passamos aqui objeto com tarefa para tarefa, que obtemos do corpo da solicitação. Agora, aqui está uma coisa. Se estiver no objeto, nome da nossa propriedade e o nome do valor são iguais, que é aqui tarefa e tarefa. Podemos simplesmente escrevê-lo como uma tarefa. Mas por fornecer esse código, eu o mantenho assim. Agora, você se lembra que temos que passar o terceiro argumento nesse vento pelo ID e pelo método de atualização? Aqui, passamos o novo para verdadeiro e também executamos os validadores para o verdadeiro Vamos guardar isso para que possamos ver claramente. Agradável. Agora sabemos que essa expressão é uma tarefa assíncrona Então, passamos aqui um peso e armazenamos o valor atualizado na variável updated to do. Além disso, para obter um peso, temos que passar aqui de forma assíncrona e, na parte inferior, simplesmente retornamos essa atualização para fazer Salve as alterações e vamos iniciar esse aplicativo. Bom. Abra o teste de API atualizado. Aqui temos o corpo pronto. Logo na parte superior, precisamos passar o ID do objeto real para fazer como parâmetro. Então, copiamos qualquer ID de tarefa do Mongo Di become pass, e aqui no lugar desse ID, passamos nosso ID e também certificamos de adicionar o prefixo de API less Envie essa solicitação. Ótimo, recebemos nossos dados atualizados. Agora vamos passar para a segunda consulta, que é atualizar todos os documentos cujo status atual está em andamento e o status atualizado com concluído. Eu dupliquei essa consulta e simplesmente comento isso. Agora temos que atualizar aqui vários documentos. Portanto, no local de localizar por ID e atualizar, usamos o update many. Aqui no local do ID, temos que passar o objeto de consulta com status de condição para fazendo e queremos alterar os dados conforme concluído. Além disso, removemos esse terceiro argumento. Não precisamos disso, salve as alterações e não nos preocupamos com a ID e o corpo da tarefa. Nós não os usamos em nossa consulta. Envie a solicitação. Veja, aqui modificamos a contagem para um, o que significa que a atualizamos com sucesso. Você também pode verificá-lo na bússola Mongo Di B. Essa é uma delas, certo, que trabalha com dados. Eu adoro isso. Agora vamos passar para a terceira consulta. É para excluir uma tarefa específica por seu ID. Então, aqui já estamos obtendo ID do ponto de solicitação PRMs. Além disso, removemos esse método inteiro anterior porque não precisamos dele Agora só precisamos escrever uma consulta. Remova esse código anterior e usaremos para fazer dot, método que usamos. Pense sobre isso. Precisamos excluir uma tarefa específica por seu ID. Sim, podemos usar Dilt one, fine one e delete, ou também podemos usar fine by ID e delete Aqui, eu não especifico, precisamos retornar o documento excluído ou não. Então, para a primeira apresentação, usamos aqui o DLT one. Se quisermos excluir o documento, então usamos aqui, multe por ID e exclua. Aqui, passamos o objeto de consulta com a propriedade de ID de sublinhado para ID Agora, no início, adicionamos await e o armazenamos em uma variável chamada result Agora, por await, na parte superior, adicionamos Async e, na parte inferior, retornamos esse resultado para esse objeto JSON com essa Salve as alterações e dê uma olhada, copie qualquer ID do banco de dados e abra a solicitação de exclusão. No W desse ID, colamos nosso ID e também aderimos ao prefixo da API slash e enviamos a Veja, excluímos a contagem até um, o que significa que excluímos com sucesso a tarefa. Se atualizarmos nosso banco de dados, C, teremos apenas sete tarefas. Uma coisa a fazer é excluir do banco de dados, então é assim que realizamos a atualização e a exclusão no Mongo DB Eu sei que esta seção é um pouco longa do que outras seções, mas como você pode ver, é muito importante aprender Mongo Deb É por isso que criei esses exercícios específicos para aprender Mongo Deb Se você estiver assistindo este curso continuamente, faça uma pequena pausa na tela. Beba um pouco de água e cuide dos seus olhos. Nos vemos na próxima seção, onde aprenderemos tópicos avançados do Mongo 78. Seção 08 — construídos em validadores: Bem-vindo à oitava seção do curso definitivo de Node JS Nesta seção, aprenderemos conceitos avançados do Mongo DB Começamos aplicando validadores no esquema do modelo, retornando erros personalizados para essas Depois disso, veremos como criar relações entre coleções, diferentes tipos de design de estrutura de banco e como tornar o patch muito rápido. Esses conceitos são muito úteis quando queremos criar aplicativos do mundo real. Vamos começar esta seção. Na seção anterior do projeto de demonstração do Mongo, criamos esse esquema para nosso modelo de usuário e, no esquema, definimos o tipo de preenchimento e algumas outras propriedades Isso é necessário para um tipo de validador para esse esquema. Anteriormente, nós apenas os definíamos, mas não vemos realmente a implementação prática do validador para o esquema Vamos ver o que aconteceu quando tentamos adicionar dados sem passar o nome fill. Contamos essa propriedade de nome daqui e, na parte inferior, no lugar da função relativa do usuário, chamamos de função criativa do usuário Salve as alterações e, no terminal, vamos executar o índice do nó do aplicativo dot js. Veja, aqui temos um erro. Vamos rolar até o topo. Aqui podemos ver que estamos recebendo erro de validação, a validação do usuário preenchida. O nome do caminho é obrigatório. Agora você pode se perguntar por que estamos recebendo esse tipo de erro longo. Portanto, o motivo é que não estamos tratando os erros adequadamente. Então, aqui sabemos que esse novo método dot cv do usuário retorna uma promessa, e é por isso que usamos await Mas aqui estamos fingindo que sempre obtemos dados nesse objeto e esquecemos de lidar com o erro Então, você se lembra, na seção Asynrna JavaScript, como lidamos com erros nos Certo, usamos o blog try and catch. Então, aqui também adicionamos o blog Tr e movemos nossa tarefa de corrida para ele. Agora, se você receber um erro ao armazenar esse usuário, nosso código, vá para o catch blog. Aqui, obtemos o objeto de erro e, por enquanto, simplesmente consultamos dot log esse objeto de erro, e ele tem uma propriedade chamada message na qual receberemos a mensagem de erro Salve as alterações e, novamente, execute esse aplicativo. Veja, agora recebemos nossa mensagem de erro. Mas aqui também estou recebendo essas informações de atualização. Deixe-me ver o que está errado. Sim, na parte inferior, esqueci de comentar essa função de atualização do usuário Salve os NGs e vamos executar esse aplicativo novamente. Veja, aqui temos nossa mensagem de erro. Isso é bom e claro. No mundo real, podemos retornar essa mensagem de erro como resposta com o Código de Status 400. Agora, não se preocupe com isso. Agora, e se quisermos passar uma mensagem de erro personalizada para esse campo obrigatório? No lugar desse valor verdadeiro, passamos array. Em primeiro lugar, passamos nosso valor pelo necessário, o que é verdade. Em segundo lugar, passamos nossa mensagem de erro em string. Digamos que, por favor, insira o nome de usuário. Salve as alterações e dê uma olhada. Veja, aqui temos nossa mensagem de erro personalizada. Os validadores nos ajudam a manter a qualidade e a precisão dos dados Ao usar validadores, verificamos se os valores no documento seguem as regras que definimos para cada preenchimento Existem dois tipos de validadores em mangas. O primeiro é construído em validadores, que são os validadores predefinidos por mangos Em segundo lugar, temos validadores personalizados, que podemos definir por conta própria Obrigatório faz parte dos validadores integrados. Deixe-me mostrar outro validador embutido de mangas. Para string, temos o comprimento mínimo, que verificará o comprimento mínimo da string, e passaremos o comprimento mínimo aqui. Depois disso, temos o comprimento máximo que verificará o comprimento máximo da string. Em seguida, temos match, que valida a string usando uma expressão regular, e sua sintaxe é padrão de barra. O desenvolvedor de barra usa esse validador de correspondência para validar e-mails Por enquanto, não queremos isso. Agora, suponha que, para cada usuário, tenhamos que mencionar a função desse usuário, que pode ser usuário simples ou administrador, e a string diferente dessa não será válida. Então, naquele momento, definimos o tipo como string para definir as duas possibilidades, usamos aqui a propriedade num e a configuramos como matriz, e você adivinhou corretamente, passaremos nossos valores nessa matriz Primeiro, pode ser usuário e segundo, pode ser administrador. Podemos aderir quantos valores quisermos, mas precisamos passar um desses valores quando salvamos um novo usuário. Já vimos isso em nosso exercício. Lembre-se de que esses são os validadores da string. Além disso, também existem dois validadores para o número, média e máxima, mas não queremos adicioná-los aqui Tudo isso é validador incorporado. Eles são muito úteis. Além disso, uma coisa que quero deixar claro é que os validadores são um recurso simples. Não faz nada com o Mongo DB. Se do banco de dados Mongo Debi removermos o campo de nome de um registro, então o Mongo Deb não se importa em nosso esquema, definimos o campo de nome Mongoose nos fornece esses recursos para que possamos validar os valores do usuário antes de armazená-los Se não for válido, mongoose não armazena esses dados no banco de dados e, se for válido, o e, se for válido, Mongo os armazena no Simples assim. Agora, na próxima lição, veremos como criar dados personalizados válidos. 79. Validadores personalizados: Agora vamos ver como podemos definir validadores personalizados em nosso esquema Então, aqui temos hobbies preenchidos, que é a matriz de cordas Queremos garantir que o usuário adicione mais de um hobby. Para isso, precisamos definir validadores personalizados. É muito simples. Então, depois dessa propriedade de tipo, aqui temos outra propriedade chamada validate, e passamos aqui outro objeto Agora, dentro desse objeto, temos a propriedade validadora, coluna e aqui a função validadora de passagem Aqui queremos verificar. O valor passado para esse campo tem dois elementos ou não, mas para isso, precisamos do valor aqui. Recebemos esse valor como parâmetro e o chamamos de V para valor. Agora, nesta função, podemos simplesmente retornar a condição. Deixe-me perguntar, como podemos verificar isso? V tem dois elementos ou não? Sim, podemos escrever aqui, comprimento do ponto deve ser maior que um. E é isso. Vamos ver se está funcionando ou não. Para isso, comentamos esse campo de hobbies e também altero o e-mail para Harley One Salve as alterações e vamos executar esse aplicativo. Veja, aqui temos dois erros, um para o nome e outro para o hobby. validador falhou para hobbies de caminhos com valor de string vazia Agora imagine que retornamos esse erro com nossa API. Quase ninguém consegue entender esse erro. Portanto, temos que fornecer uma mensagem de erro significativa para alterar essa mensagem de erro Após essa função de validador, temos a propriedade da mensagem e passamos aqui uma mensagem personalizada Insira dois hobbies diferentes Certifique-se de que tenhamos essa propriedade de mensagem nesse objeto validador, não na função validadora, porque cometi esse erro ao gravar esta lição Salve isso e vamos executar esse aplicativo mais uma vez. Veja, aqui temos nossa mensagem de erro personalizada. Agora vamos testar mais coisas para esse preenchimento. E se alguém passar por apenas um hobby? Vamos verificar isso. Remova o comando e removeremos outros dois hobbies da nossa matriz Salve as alterações e vamos executar esse aplicativo. Bom, aqui estamos recebendo a mensagem de erro , está funcionando. Agora, e se alguém passar aqui o valor nulo? Salve isso e vamos executar nosso aplicativo mais uma vez. Veja, aqui temos propriedades impossíveis de ler de comprimento de leitura nulo Agora, por que estamos recebendo esse erro? Porque em nossos validadores personalizados, tentamos obter o tamanho desse valor Mas se o usuário passar null como valor, não poderemos acessar a propriedade length Podemos aderir a outro tipo de condição de V igual à matriz. E seu comprimento deve ser maior que um. Se essas duas condições forem verdadeiras, somente então nossos dados serão validados. Também podemos modificar a mensagem para inserir uma matriz de hobbies com dois hobbies diferentes Salve as alterações e vamos executar esse aplicativo. Veja, aqui também recebemos a mensagem personalizada para o valor nulo Então, para recapitular rapidamente a adição de validadores personalizados, temos uma propriedade válida após a propriedade de tipo E nessa validação, podemos adicionar duas propriedades. Um é o validador, que tem uma função de validador, e o outro é a mensagem personalizada E a partir dessa função validadora, retornaremos a condição para validação Você pode perguntar se queremos retornar a condição, então por que precisamos dessa função? Podemos adicionar condições diretamente aqui, mas verifique isso mais uma vez. Nessa condição, sempre precisamos do valor atual desse preenchimento e só o obtemos na função validadora É por isso que precisamos dessa função. É assim que definimos validadores personalizados para o esquema. 80. Validadores assíncronos: Às vezes, em nosso projeto, nossa validação pode envolver algumas operações assíncronas, que significa que a operação pode levar tempo Por exemplo, queremos buscar dados do banco de dados e, com base nesses dados, queremos validar nosso Nesse caso, podemos aplicar validadores assíncronos. Deixe-me te mostrar. Para aplicar os validadores Async na versão anterior Aqui no objeto validador, temos que adicionar uma propriedade chamada async Mas na versão mais recente do Mongoose, essa opção está ativada por padrão . Nós podemos remover isso. Agora podemos simplesmente tornar essa função assíncrona e, dentro dessa função, podemos realizar nossa tarefa assíncrona Não queremos essa complexidade ou esse modelo, então, para demonstrar o atraso, usamos aqui o método set timeout primeiro parâmetro é a função de retorno de chamada e, segundo, adicionamos 3.000 Agora, antes dessa função de tempo limite definida, deixe-me registrar pontos do console buscando dados para Agora, suponha que, após 3.000 milissegundos, estejamos obtendo dados do banco de dados e, com base nesses dados, possamos retornar qualquer condição Lembre-se de que precisamos devolver uma condição como a que retornamos anteriormente, o que significa que ela deve ser verdadeira ou falsa. Salve as alterações e vamos executar este aplicativo e ver, aqui está nosso erro. É assim que podemos aplicar validadores assíncronos. Pessoalmente, nunca uso isso em meu projeto porque operações acyc para validação são raras, mas esse tópico pode ajudar alguns de vocês, e é por isso que adiciono esta lição Agora, na próxima lição, veremos algumas opções esquematizadas 81. Opções úteis de SchemaTypes: Agora vamos ver as opções de tipos de esquema no mongoose. Nós já os usamos em nosso esquema, que é minúsculo para verdadeiro Isso armazenará nossa string em letras minúsculas. Da mesma forma, temos maiúsculas para verdadeiro. Isso armazenará nossa string inteira em maiúsculas. E depois disso, temos outra opção útil, que é transmitir para true. Isso removerá espaços em branco desnecessários da nossa string. Por exemplo, isso converterá essa string nesse tipo de string. Portanto, nossos dados parecem bem organizados e limpos. Não é necessário, temos que usar todas essas opções de esquema em nosso projeto Podemos usar o que for necessário de acordo com nosso modelo. Não há regras para isso. No final das contas, os validadores servem apenas para manter a qualidade e a precisão dos dados 82. Relação entre os modelos: Então, até agora, neste curso, vimos modelos ou coleções que são simples e não têm conexão com outro modelo. Mas no mundo real, a maioria dos nossos modelos está conectada entre si. Deixe-me explicar com o exemplo. Então imagine que estamos trabalhando em aplicativo de mídia social como o Twitter. Portanto, temos uma coleção para usuários na qual armazenaremos todos os dados dos usuários, como nome, e-mail, senha, etc Depois disso, temos uma coleção para postagem na qual armazenaremos todos os dados da postagem. No documento de postagem, temos conteúdo, que é a data do texto do conteúdo da postagem em que essa postagem foi criada. Depois disso, temos um usuário que fez o upload desta postagem, digamos Harley Agora, esses dois documentos ou podemos dizer que as coleções não estão conectados entre si. Temos que conectá-los. Isso é chamado de relacionamento de modelo. Agora você pode se perguntar por que precisamos conectar modelos uns aos outros? Por que precisamos desse relacionamento? Então, se não usarmos relacionamento, podemos acabar armazenando os mesmos dados do usuário repetidamente para cada postagem que eles fizerem. Suponha que um usuário publique dez postagens diferentes. Se não usarmos relacionamento, teremos que armazenar os mesmos dados do usuário dez vezes para cada postagem, e isso é apenas um usuário. Imagine que em nosso aplicativo de mídia social há 100.000 estudantes ou mais do que isso. Pense na quantidade de dados que precisam ser repetidos em nosso banco de dados, e isso também é mais difícil de gerenciar. Portanto, temos que usar relacionamentos entre modelos que têm associação. Agora, existem duas abordagens para implementar o relacionamento. O primeiro é usar referências e o outro são dados incorporados em outro documento. Vamos primeiro ver como podemos implementar relacionamentos usando referências. No documento postal, temos esse usuário e passamos o nome de usuário. Agora, esse usuário já está disponível na coleção do usuário. Em vez de armazenar o nome de usuário na coleção de postagens, podemos usar seu ID de usuário desse usuário. Com o ID exclusivo do usuário, podemos executar outra consulta para obter os dados do usuário, como nome e foto do perfil, da coleção de usuários. Agora, para cada postagem, temos apenas o ID do usuário no local do nome do usuário. Mas podemos ver a necessidade de executar outra consulta nessa abordagem, o que pode causar problemas de desempenho. Não estou dizendo que isso definitivamente causará problemas de desempenho, mas às vezes pode. A outra abordagem que pode resolver esse problema são os dados incorporados em outro documento. No lugar de passar aqui o ID do usuário, podemos passar aqui o objeto do usuário e removemos a coleção do nosso usuário. Com essa abordagem, não precisamos fazer consultas, então não enfrentamos problemas de desempenho aqui , mas aqui está uma coisa Imagine que o usuário tenha de 20 a 40 detalhes. Isso tornará nosso documento postal muito maior. Além disso, isso causará duplicação de dados porque, para cada postagem, temos que armazenar o objeto do usuário Agora, alguns desenvolvedores dizem que atualmente o armazenamento de banco de dados é barato. Podemos arcar com a duplicação de dados e isso é verdade. Mas e se nosso usuário quiser atualizar seu nome de usuário ou ID de e-mail? Dessa vez, temos que atualizar várias postagens e se de alguma forma dois a três documentos não receberem essas atualizações , isso nos levará à inconsistência de dados Mas quando usamos referências, precisamos atualizar os dados somente em um só lugar. Resumindo, quando usamos referências, obtemos consistência de dados porque nossos dados são armazenados em um único local, mas podemos ter problemas de desempenho porque precisamos executar várias consultas. Por outro lado, quando incorporamos dados em outro documento, obtemos desempenho Recebemos nossos dados mais rapidamente porque não precisamos executar várias consultas. Temos nossos dados em um único documento, mas com isso, obtemos inconsistência de dados porque temos os mesmos dados em vários lugares Isso é compre um e leve outro de graça. Temos que decidir por nossa inscrição. Precisamos de consistência de dados ou queremos desempenho. Se quisermos consistência de dados , usamos referências e, se quisermos desempenho , incorporamos dados em outro documento. Projetos diferentes têm requisitos diferentes. Como desenvolvedor, você precisa decidir qual abordagem funciona melhor para seu projeto. Atualmente, os desenvolvedores usam a abordagem híbrida, que combina essas duas abordagens, e veremos isso na próxima lição. 83. Abordagem híbrida para relações: Vimos que quando usamos referências, obtemos consistência de dados e, quando incorporamos dados em outro documento, obtemos desempenho Deixe-me mostrar a abordagem híbrida que os desenvolvedores usam hoje em dia. Suponha que tenhamos usuários com 20 a 30 propriedades, armazenaremos os detalhes desses usuários na coleção do usuário. Agora, para postagem, temos esses outros campos, os mesmos que vemos na abordagem de referência. Mas, na abordagem de referência, armazenamos aqui o ID do usuário. vez disso, podemos usar aqui um pequeno objeto de usuário, que contém apenas as propriedades necessárias que queremos exibir com a postagem. Podemos ter o ID do usuário, que é a referência à coleção e ao nome do usuário. Não armazenamos aqui todas as 20 a 30 propriedades, mas incorporaremos apenas essa quantidade de dados Queremos exibir com postagem. Com essa abordagem, podemos buscar postagens rapidamente porque não precisamos buscar várias consultas Temos todos os dados necessários em um único objeto. Essa abordagem funciona melhor quando nossa coleção precisa de pequenos detalhes que sejam acessados com frequência. Por exemplo, em nosso projeto de comércio eletrônico, onde temos produtos, pedidos, carrinho, etc Em cada pedido, queremos usar pequenos detalhes de nossos produtos, como ID, nome, imagem da capa e preço porque queremos exibir os detalhes desse pedido com os produtos. Portanto, temos uma coleta separada de dados de produtos, mas ainda assim incorporaremos alguns pequenos dados sobre os produtos em cada pedido Então, quando queremos acesso rápido a pequenos detalhes, mas também queremos referenciar dados grandes ou complexos , usamos a abordagem híbrida. Novamente, estou dizendo que você não precisa se ater a uma abordagem. Alguns aplicativos funcionam melhor com referências. Então, funciona melhor com dados incorporados, e alguns funcionam melhor nessa abordagem híbrida. Você precisa decidir de acordo com as necessidades do seu projeto. Não se preocupe quando construirmos outros dois projetos, mostrarei como podemos decidir a abordagem de relacionamento. Estou falando sobre relacionamento entre coleções, não sobre outros tipos de relacionamento. 84. Aplicando abordagem de referência: Vamos ver como podemos aplicar abordagem de referência para relacionamento. Para praticar esse conceito, criei esse novo arquivo porque não quero que você se confunda com esse núcleo confuso. Deixe-me explicar para você o que eu adicionei neste arquivo. Primeiro, conectamos esse arquivo ao banco de dados Mongo DB chamado Mongo that is relationship Depois disso, como vemos no exemplo, definimos aqui um esquema de usuário simples com apenas três preenchimentos, nome, e-mail e idade Depois disso, definimos um novo esquema para postagem. Nesse caso, temos dois preenchimentos de conteúdo, que podem ser texto e depois data, que é a data atual em tempo real Temos um usuário que adicionaremos em apenas um minuto. Depois disso, criamos dois modelos para usuários e postamos a coleta. Nós já fizemos isso. Não quero aborrecê-lo escrevendo o mesmo código repetidamente. Agora, depois de criarmos essas duas coleções, eu defino algumas funções. Uma é para criar usuário, na qual podemos criar um novo usuário e armazená-lo na coleção do usuário. Em seguida, temos a função Create Post, na qual criamos uma nova postagem usando conteúdo e dados do usuário, quem criou esta postagem. A última função é obter todas as postagens do banco de dados. Já vimos tudo isso. Vamos criar o primeiro usuário com esses valores. Execute este aplicativo usando node, reference dot JS. Bom. Agora, vamos tentar criar uma nova postagem sem adicionar dados do usuário. Aqui, eu comento essa função de criação de usuário e removo comentário da função Criar postagem. Vamos executar esse aplicativo novamente e ver aqui criarmos uma nova postagem. Temos conteúdo e, veja, não obtemos nenhum dado do usuário, mesmo se passarmos os novos dados do usuário como preenchidos. Podemos ver que as mangas adicionarão apenas os preenchimentos que definimos no esquema Ele não adicionará todos os outros preenchimentos. Agora, neste modelo de postagem, temos que adicionar o campo do usuário e fornecemos a referência do usuário da coleção de usuários. Deixe-me mostrar o que quero dizer. Aqui, adicionamos usuário. Agora, sempre que quisermos dar referência, podemos fornecer isso usando o ID do objeto porque é único. Passamos seu tipo para o esquema de pontos do Mongos, tipos de pontos, ID do objeto de pontos Sim, precisamos passar essa expressão para definir o ID do objeto como tipo preenchido. Depois da propriedade de tipo, temos que dizer qual outra referência de modelo estamos adicionando. Passamos RF dois e aqui passamos o nome da nossa coleção em uma palavra singular mesmo que passamos neste método de modelo de pontos mongoose, que é usuário Agora vamos passar nosso ID de usuário na função de criação de postagem. No Mongo D BCMEpass, obtemos novo banco de dados chamado relacionamento isso, obtemos a coleção de usuários, copiamos esse ID de usuário, que acabamos de criar, e o colamos no lugar dessa string de usuários. Na função Criar postagem, tínhamos esse ID no local do usuário. Além disso, vamos mudar esse conteúdo para conteúdo. Então, as mudanças, e vamos executar esse aplicativo. Veja aqui que também temos uma nova postagem com conteúdo, e também temos aqui o ID do usuário, que é a referência ao modelo do usuário. Adicionar uma referência é muito fácil. Temos que definir esse tipo de preenchimento Mongos dot schema dot Types dot Object ID e passamos a propriedade ref para adicionar o nome do modelo de referência em uma palavra singular Agora, se tentarmos obter uma postagem, comente isso e remova o comentário dessa função G post. Salve as alterações e dê uma olhada. Veja, aqui temos dois posts. O primeiro, que criamos sem usuário, e segundo, no qual definimos o ID do usuário como referência. Agora você pode perguntar que estamos recebendo aqui um ID de usuário simples. Como podemos obter os dados do usuário, como nome de usuário ou e-mail , dessa referência? Isso veremos na próxima lição. 85. Como extrair dados da referência [Populate]: Vamos ver como podemos extrair dados usando esse ID de referência? É muito simples. Para obter os dados por referência, usamos um método chamado populate. Após esse método fino, adicionamos o preenchimento de pontos e, dentro dele, temos que passar o nome do preenchimento que é a referência Sim, é usuário aqui. Salve as alterações e dê uma olhada. Execute esse arquivo novamente. Veja, aqui voltamos a postar. Na segunda postagem, obtemos todos os detalhes desse ID de usuário. Agora imagine que só queremos obter o nome aqui. Não precisamos de outros preenchimentos. Podemos fazer isso? Sim, nós podemos. No segundo argumento, passamos o nome dos comprimidos que queremos obter de nossa coleção de referência. Nos códigos, adicionamos o nome, salvamos e vamos executar esse aplicativo mais uma vez. Veja, aqui temos apenas nome e ID de sublinhado. Agora, em vez de mostrar apenas o nome, queremos todos os detalhes sobre o usuário, mas não precisamos dessa idade. Como podemos fazer isso? Qualquer lugar do nome que queremos remover, menos ge Muito simples É assim que ampliamos os dados de referência usando um método popular. Agora, deixe-me dizer uma coisa. Tínhamos referência em nosso modelo, apenas mangas usam essa referência Mongo Deb não se importa com isso. Mesmo se passarmos aqui um ID de usuário inválido, Mongo DB não verifica se o ID do usuário está disponível na coleção do usuário ou Ele armazena os dados sem se preocupar com isso. Deixe-me te mostrar isso. Criamos aqui outro post. Comente esta função de postagem do Gad e remova o comentário desta função de criação de postagem Vamos mudar esse conteúdo para três e simplesmente modificar o último caractere desse ID de usuário. Na coleção de nossos usuários, não temos nenhum usuário cujo ID seja esse. Agora vamos executar esse aplicativo. Veja, nosso usuário três é criado aqui. Agora vamos pegar a lista de postagens, comentar essa função e chamar essa função Gad Post Nas alterações, veja na terceira postagem, fazemos com que o usuário seja nulo porque não obtemos uma referência para esse ID de objeto inválido, que prova que o MGB não verifica se ID do usuário está disponível na coleção do usuário Agora, na próxima lição, veremos outra abordagem que está incorporada em outro documento. 86. Aplicando a abordagem incorporar: Para aplicar a abordagem incorporada, não removo o código anterior porque quero fornecer esse código para referência. Baixamos o arquivo incorporado dot JS abaixo, ou você o obterá na pasta oito da seção de recursos. Agora, na abordagem de referência aqui para preenchido pelo usuário, passamos o tipo para o ID do objeto e o referenciamos com a coleção de usuários. Mas na abordagem incorporada, adicionamos diretamente aqui o objeto do usuário com todas as propriedades. Não criamos aqui um modelo de usuário, excluímos esta linha, criamos apenas um modelo que é post. Além disso, podemos remover a função de criação de usuário da parte inferior porque, para cada postagem, o documento tem um objeto de usuário. Agora podemos adicionar aqui o objeto e temos que passar aqui as propriedades que precisamos para esse objeto de usuário. Podemos dizer nome para string, e-mail para string e idade para número. Agora, o lado ruim desse objeto de usuário é que nosso usuário não pode passar valores para nome, e-mail ou idade. Temos que passar pelas validações desses preenchimentos porque precisamos do objeto do usuário em cada postagem Então, em vez de adicionar aqui a validação, já temos o esquema do usuário Então, no lugar de passar esse objeto simples, passamos aqui o esquema do usuário Nesse esquema, podemos adicionar todos os nossos validadores, assim como temos uma coleção separada Além disso, definir o esquema separadamente tem mais um benefício Também podemos usar esse esquema de usuário para outra coleção na qual também queremos incorporar os dados do usuário Agora vamos criar uma nova postagem com esses dados de usuário incorporados. Então eu removo essa chamada de função de criação de usuário e chamamos a função Create Post. Agora, no lugar desse usuário, temos que passar o objeto do usuário porque esse objeto do usuário será armazenado diretamente no documento de postagem. Para o usuário, passamos o objeto com o nome das propriedades para o código e-mail para o código etheridgmil.com Idade, digamos 25. Salve as alterações e vamos executar esse arquivo s incorporado. Então, node, incorpore e pressione Enter. C, recebemos uma nova postagem com objeto de usuário que tem nome, e-mail e idade. E se também verificarmos nosso banco de dados na parte inferior, obteremos uma postagem com o objeto do usuário. Então, na referência, simplesmente passamos ID do objeto e adicionamos referência a outra coleção. Mas na abordagem incorporada, adicionamos diretamente dados completos do usuário em um único documento. Agora eu tenho uma pergunta. E se tornarmos esse campo de nome obrigatório e depois não passarmos o nome no objeto do usuário? Nossa postagem será criada ou não? Isso não faz parte da lição que eu realmente queira ver. Vamos pegar isso. Aqui, no lugar do nome à string, adicionamos objeto, tipo à string e required a true. Agora, na parte inferior, vamos remover esse campo de nome e vamos alterar esse conteúdo para erro de tentativa. Salve as alterações e dê uma olhada. Ah, recebemos um erro de validação, o que significa que uma nova postagem não foi criada, e também podemos verificar isso em nosso banco de dados. Agora imagine que queremos armazenar de 20 a 30 propriedades para os dados dos usuários. Não podemos adicionar todos esses preenchimentos em cada documento postal. R, suponha que desejemos obter dados dos usuários, como e-mail e senha, como podemos obter esses dados separadamente sem buscar todas as postagens Esse método incorporado não é realmente prático para tipos de aplicativos de mídia social. É por isso que os desenvolvedores usam a abordagem híbrida para equilibrar o aplicativo, e implementaremos a abordagem híbrida na próxima lição. 87. Aplicando abordagem híbrida: Vamos implementar a abordagem híbrida no mesmo modelo de código. Eu adiciono novamente o mesmo código no arquivo js de pontos híbridos. Você também pode baixá-lo abaixo desta lição. Agora, na abordagem incorporada, adicionamos todas as propriedades dos usuários em uma única coleção e nem criamos a coleção do usuário. Agora, na abordagem híbrida, criamos uma coleção de usuários na qual podemos adicionar todas as propriedades. Mas o que adicionaremos no campo do usuário da coleção de postagens, porque esse documento de postagem precisa dos dados dos usuários que criaram essa postagem, então, em vez de passar aqui todas as propriedades dos usuários, adicionamos apenas algumas propriedades que exigimos com a postagem. Por exemplo, com a postagem, queremos mostrar o nome do usuário e o e-mail desse usuário. Não queremos lá, então adicionamos o nome, que pode ser uma string, e queremos mostrar a foto do perfil desse usuário, que pode ser uma sequência de URL da foto do perfil Portanto, aderimos apenas aos preenchimentos necessários para o usuário. Nem todo o documento. Agora, isso funcionará perfeitamente bem. Mas e se, talvez, em algum caso, quisermos mais informações sobre o usuário com a postagem. Alguns desenvolvedores também aderem ao Rf do usuário, que é a referência do usuário É a mesma referência que adicionamos na lição de referência anterior. Dissemos que é tipo para Mongos, esquema de pontos, tipos de pontos, ID de objeto O que adicionamos aqui , sim, refira ao usuário. Além disso, podemos alterar esse nome de campo para resumo do usuário. Eu acho que isso é muito melhor. Agora vamos mudar um pouco na função de criação de postagem. Aqui, adicionamos o ID do usuário no parâmetro e, neste post, alteramos esse campo do usuário para resumo do usuário e depois disso, outra propriedade usa uma referência para esse ID do usuário. Agora, na parte inferior, chamamos isso de função create post. Aqui podemos alterar o conteúdo. Essa é uma forma híbrida e passa o nome do objeto para códigos e a foto do perfil para o ponto do perfil JPG. Para o ID do usuário, eu copio o ID do banco de dados. E cole o ID aqui. Salve as alterações e dê uma olhada. Veja, aqui temos uma nova postagem com resumo do usuário e representante do usuário. Nós dois chegamos aqui. Se você quiser mostrar dados rapidamente sem chamar várias consultas, usaremos esse resumo do usuário e, se quisermos mais dados do usuário, somente então usaremos essa referência do usuário. Dessa forma, podemos otimizar o desempenho e também obter os dados que queremos. Use o que funciona melhor para seu aplicativo. No final das contas, isso não é seu. 88. Indexes no MongoDB: Agora vamos falar sobre índices no Mongo DB. Índices é um tópico muito interessante e importante do Mongo DB O índice é usado para agilizar nossa consulta ao banco de dados, e também veremos uma demonstração disso. Até o Mongo DB diz que, com índices, nossa consulta de pesquisa de banco de dados pode executar o Tenex mais rápido do que antes, o que é muito avançado Agora você pode se perguntar como o índice torna nossa consulta de pesquisa mais rápida. Deixe-me explicar com o exemplo. Imagine que temos aqui uma lista de dados de cem usuários e queremos encontrar um usuário cujo e-mail seja esse y123 atgmil.com Agora, como funciona a consulta real, pego um objeto de documento, verifico se o e-mail é ele 123 aterra gmail.com ou Se não estiver, ele será movido para outro objeto do documento e verificará novamente esse e-mail. Ele continuará esse processo até que todos os documentos de cem usuários sejam digitalizados Como você pode ver, isso é um pouco lento. Qual é a solução aqui? Criaremos um índice para nosso e-mail preenchido com a coleção. Apenas criando o índice para e-mails preenchidos, nossa consulta de pesquisa por e-mail ficará mais rápida. Vamos ver isso na prática. Em nossa coleção de usuários, atualmente, temos apenas um usuário. Vamos adicionar alguns dados falsos do usuário em nossa coleção. Assim, podemos ver praticamente nossa consulta está funcionando melhor ou não. Para isso, na pasta de recursos da seção oito, adicionei um arquivo, testando index dot js. Basta acessar este arquivo em nosso projeto. E nesse arquivo, eu adicionei quase o mesmo código de antes. Primeiro, coleção Mogadbi, aqui você deve escrever o nome do banco de dados que está usando para esta seção Em seguida, criamos o esquema do usuário com nome, e-mail e senha, para que possamos nos concentrar em nossa consulta Então, na parte inferior, temos funções. A primeira é para inserir alguns dados aleatórios na coleção do usuário. Veja, usando esse simples for loop e esse pacote falso, podemos gerar nome de usuário, e-mail e senha aleatórios para testes Para isso, em nosso projeto, temos que fazer a instalação do NPM no red faker Js faker, na taxa 9,6 0,0 E aperte Enter. Bom. Agora, vamos simplesmente chamar essa função para gerar dados de 100.000 usuários porque aqui estamos executando esse loop 100.000 vezes. E aqui não queremos que ocorram erros ao adicionar e-mails, então eu removo o preenchimento exclusivo para true do nosso esquema apenas para permitir que 100.000 usuários entrem Além disso, do seu banco de dados, remova essa coleção de usuários, para que possamos obter todos os dados novos. Solte a coleção e digite aqui usuários e solte a coleção. Agora, em nosso arquivo iNexis de teste, chamamos aqui a função Inserir usuários de teste Salve isso e vamos simplesmente executar esse arquivo. Teste de nó no eixo dot js e pressione Enter. Levará pouco tempo e veja aqui a mensagem de sucesso. Se verificarmos nosso banco de dados, atualizarmos a coleção, S na coleção do usuário, obteremos dados de 100.000 usuários Adorável. Agora, primeiro, comentamos essa inserção dessa função de dados Não queremos mais executá-lo. Agora vamos ver o que é encontrar um usuário por e-mail, quanto tempo está demorando. Na parte inferior, temos a função chamada find user. Nesta função, primeiro, eu declaro o tempo. Depois disso, executamos consulta dot Fine do usuário, na qual estamos passando email para o parâmetro email. Depois de concluir essa consulta, declaramos novamente o cronômetro, que é a hora de término, e aqui simplesmente mostramos a hora de término menos a hora Com isso, saberemos quanto tempo essa boa consulta está demorando. Além disso, o Performance Dot agora é mais preciso e confiável para medir o tempo de execução. Agora, vamos chamar essa boa função de usuário. Então, da coleção de nossos usuários, vamos copiar qualquer e-mail e passar esse e-mail em nossa função de usuário fina com códigos. Salve isso e, no terminal, encerramos o código e executamos novamente nosso ponto índice de degustação JSFle Veja, aqui temos o tempo de 130 milissegundos. Agora vamos criar um índice para nosso preenchimento de e-mail e provar a rapidez com que nossa consulta se tornará. Para criar o índice, aqui, antes de criarmos a coleção, adicionamos o índice de pontos do esquema do usuário e, dentro dele passamos o e-mail do objeto, que é o nome do preenchimento, queremos marcar como índice e, como valor, podemos passar duas coisas, um e menos um Agora você pode perguntar: qual é o significado de um e menos um É muito simples. Um é para ordem ascendente e menos um é para ordem decrescente Quando criamos um índice, Mongo DB captura que preenche os dados em ordem crescente ou decrescente Isso ajudará o Mongo Deb a encontrar dados rapidamente. Não se preocupe, vou te explicar isso depois da degustação. Aqui, passamos por um em ordem crescente e pronto. É assim que criamos um índice para e-mails preenchidos, uma linha de código. Todos os outros códigos neste arquivo são para degustação, não se preocupe com isso Só queremos ver que, ao criar um índice, nossa consulta está ficando rápida ou não. Então, aqui, executamos novamente a mesma função find user e vamos executar esse arquivo. Veja, aqui temos 133 milissegundos. Deixe-me executar esse arquivo mais uma vez. Veja, agora leva apenas 76 milissegundos. Eu tenho tanto tempo porque, no meu sistema, atualmente muitos softwares grandes estão sendo executados. Anteriormente, quando eu provava isso sem nenhum software, demorava 60 milissegundos antes adicionar o índice e, depois de adicionar o índice, bastava quatro milissegundos É quase 15 ngs mais rápido do que sem consulta de índice. Isso é muito interessante. Além disso, estamos obtendo o tempo de consulta em milissegundos porque atualmente nosso aplicativo está sendo executado localmente e nosso banco de dados também é local Se implantarmos as duas coisas na Internet , os 130 milissegundos podem se tornar 1,3 segundos. Com o índice, executamos a mesma consulta em 0,7 segundos. Imagine o quão rápido nosso site se torna, é por isso que a indexação é muito útil Deixe-me mostrar o índice que criamos. Abra a bússola Mongo Divi, vamos aos índices Veja, aqui temos dois índices. O primeiro é para ID de sublinhado e o segundo é para e-mail Portanto, na coleção Mongo Di B, Mongo DB sempre cria um índice para o campo de ID de sublinhado, e esse é o motivo pelo qual, quando pesquisamos dados por seu ID , obtemos esses Agora, aqui na parte inferior, temos outra função chamada índice de largura. Nessa função, primeiro criamos índice manualmente usando essa linha e, em seguida, escrevemos uma consulta fina. No final da consulta, eu uso esse método explicado. O método explain ajuda você a analisar como o Mongo DB executa uma consulta Ele mostra se o Mongo DB está usando um índice ou realizando uma verificação completa da coleção Nessa explicação, passamos as estatísticas de execução da string e simplesmente desregistramos esses usuários Vamos ver o que temos dentro disso. Aqui, no lugar da boa função de usuário, adicionamos a função de índice B e deixe-me simplesmente movê-la para a parte inferior. As mudanças e dê uma olhada. Vamos executar esse aplicativo usando node, tasting indexes dot js. Veja aqui todos os detalhes sobre a consulta, como estatísticas de execução, comandos, informações do servidor e muito mais. Aqui, só precisamos ver as estatísticas de execução. Aqui podemos ver e retornar a um, que significa que um dado é retornado da consulta se virmos o total de documentos examinados, que também é um. Se não criarmos aqui o índice para o campo de e-mail , o total de documentos examinados será muito maior do que isso examinados será muito maior Deixe-me mostrar isso também. Aqui temos sem função de índice. Primeiro nessa função, removo todo o índice da nossa coleção de usuários e, em seguida, executamos a mesma consulta com o método explicado. Não se preocupe em nosso aplicativo de nó real, só usaremos o método userschema dot index quando definirmos o esquema da coleção Eu adicionei esses dois métodos apenas para remover e adicionar índice usando a função. Agora vamos chamar isso sem função de índice e passar aqui o mesmo e-mail. Agora, novamente, execute este arquivo, node testing indexes dot js Veja aqui nos estados de execução, obtemos o retorno do número para um e o total de documentos examinados para 100.000 É por isso que está demorando mais tempo do que com o índice. Anteriormente, se verificássemos com o índice, obteríamos o total de documentos examinados em um, e é por isso que, ao criar o índice, nossa consulta se torna rápida Agora você pode se perguntar como, por meio índices, nossa consulta está se tornando tão mais rápida O que está acontecendo aqui? Veremos isso na próxima lição. 89. Como os indexes funcionam no MongoDB: Então, anteriormente, temos um problema. Nossa consulta ao banco de dados está digitalizando todos os cem mil documentos um por um, para encontrar e-mails específicos, o que está tornando nossa consulta lenta. E resolvemos esse problema simplesmente aplicando um índice para e-mails preenchidos. Mas a questão principal é como? O que está acontecendo nos bastidores quando aplicamos o índice? Deixe-me explicar com um exemplo interessante. Imagine que você está em uma biblioteca com 100.000 livros. Agora, você precisa encontrar um livro intitulado Harry Potter. Agora, se os livros não estiverem organizados em nenhuma ordem, você deve começar do primeiro livro, verificar cada título um por um e continuar esse processo até encontrar o livro de Harry Potter É como digitalizar todos os 100.000 documentos no Mongo Di B sem um índice que podemos considerar lento Agora, digamos que a biblioteca crie um índice, algo como a lista para armazenar as informações dos livros. Nessa lista, ou podemos dizer nesse índice, temos títulos de livros, temos títulos de livros, que classificamos alfabeticamente, e também adicionamos um ponteiro para o eu exato ou o local em que Agora, quando você pesquisa por Harry Potter, acessa o índice, encontra Harry Potter em segundos porque está classificado em ordem alfabética e, com o título do livro, adicionamos o acessa o índice, encontra Harry Potter em segundos porque está classificado em ordem alfabética e, com o título do livro, adicionamos o ponteiro. Você usa esse ponteiro para ir diretamente ao livro. Em vez de digitalizar 100.000 livros, você encontra seu livro em apenas um milissegundo. No Mongo DB, também, quando criamos um índice, Mongo Di B cria uma estrutura semelhante a uma árvore, que chamamos de árvore B ou árvore balanceada, e encurtamos nossos dados em ordem crescente ou decrescente, dependendo de passarmos o valor como um ou menos um Com esse preenchimento, é um ponteiro armazenado que localiza o documento original Ao criar um índice, reduzimos o número de documentos digitalizados e, por isso, nossa consulta fina se torna f para esse preenchimento. Agora você pode perguntar os dados resumidos. Além disso, temos que encontrar nossos dados, pois está demorando menos do que verificar todos os documentos um por um Essa é a pergunta realmente ótima. Deixe-me explicar isso. O problema é que, suponha que, se você tiver matriz não classificada e uma matriz encurtada em ambas, queira encontrar o elemento 60 Então, em ambas as matrizes, não precisamos escanear cada número. Como essa matriz classificada pode levar menos tempo Como vimos anteriormente, quando criamos um índice, Mongo B cria uma estrutura de bateria ou árvore de equilíbrio com um ponteiro anexado a cada dado Mas nesta bateria, Mongo Dib também precisa pesquisar dados e, para pesquisar os dados, o Mongoi usa outra técnica de pesquisa, que chamamos de pesquisa que chamamos Então, quando não criamos um índice, Mongo Db usa a técnica de busca linear, que significa que o Mongo Db verifica os dados um por um para todos os documentos E se criarmos um índice , o Mongo Dib usará a técnica de busca binária Deixe-me explicar rapidamente como a pesquisa binária funciona para que você entenda melhor. Imagine aqui que temos uma matriz curta de números dez, 20, 30, 200 Nessa matriz, queremos encontrar 60. Agora, existem duas maneiras. Primeiro, verificamos que dez é 60, não, 20 não. 30, não. 40, não. 50, não. 60, sim. Então, aqui pesquisamos todos os itens um por um, que é o exemplo da pesquisa linear. Agora, deixe-me explicar o que é pesquisa binária. Na busca binária, produzimos jerms pela metade. Então, aqui no lugar de marcar dez, 20, 30, pulamos diretamente para a metade da lista, que é 50 Aqui verificamos que 50 é maior que 60 ou menor que 60. Sim, 50 é menor que 60, então vamos para o lado direito da lista. Agora nossa lista é de 50 a cem. Nisso, pulamos novamente na metade. Diga-me em qual item vamos pular. Certo, saltamos para 80. Nesse caso, verificamos novamente 60 é maior que 80 ou menor que. É menos do que. Então, se nosso número for menor que, então vamos para o lado esquerdo. Agora 50-70, pulamos novamente na metade, que é 60, e obtemos o elemento Então, no lugar de obter 60 em seis átomos na busca linear, aqui estamos obtendo 60 em três a quatro átomos. Isso é muito rápido. O que você diz? E esses são apenas dez dados. Imagine que temos 1 milhão de dados e, em seguida, quanto tempo podemos economizar usando o índice. É por isso que o índice torna nossa pesquisa mais eficiente e leva menos tempo do que a pesquisa linear. Observe também que a pesquisa binária funciona apenas em matriz ordenada, e é por isso que, quando criamos um índice, passamos se deve ser matriz ascendente ou matriz descendente um ou menos um Agora você entende corretamente o que é índice e por que ele funciona muito rápido. Agora, isso significa que precisamos criar um índice para cada campo em nosso banco de dados? A resposta é não. Precisamos criar um índice apenas para os preenchimentos que queremos pesquisar Suponha que temos dados de usuários e queremos pesquisar usuários pelo nome. Com isso, podemos criar um índice com nome preenchido. Portanto, Mongotbcmmand, use o índice apenas para uma grande coleção na qual vamos armazenar milhares ou milhões de Você pode se perguntar por que não podemos criar índices para coleções pequenas ou para cada campo. O motivo é que, quando criamos um índice, como sabemos, Mongotb cria a estrutura Btree, mas o Bitr também é armazenado em nosso banco de dados e isso requer espaço e Deixe-me te mostrar. Abra a bússola Mongoib e acesse nosso banco Veja, aqui temos a coleção de usuários. Aqui está o tamanho de armazenamento de nossa coleção, que é 6,65 B no lado direito, C, temos um tamanho total de índices de 3,86 B, que significa que nossos dados têm apenas três MB e outros 3,86 B são adquiridos apenas Então, mais de 50% são adquiridos por índices, o que é muito grande, e são apenas dois índices Se criarmos um índice para todos os campos , quanto será necessário para nosso armazenamento. Além disso, quando temos coleções pequenas , nossa pesquisa linear também é executada rapidamente. A diferença é ignorável e é por isso que não criamos índices para coleções pequenas Quando precisamos aplicar o índice, primeiro, quando temos grandes coleções, indexação ajuda a usar conjuntos de dados como milhões de registros Sem um índice, o Mongo Di B verifica cada documento um por um Segundo, quando a pesquisa é frequente. Se frequentemente pesquisamos um preenchimento como e-mail, nome de usuário, ID do pedido , podemos indexá-lo. Por exemplo, no sistema de registro de usuários no qual pesquisamos usuários por e-mail. Isso aumenta significativamente a velocidade de leitura. Em seguida, terceiro, quando o curto-circuito é comum. Se costumarmos usar o Short Method by Price , podemos indexar esse preço preenchido. Por exemplo, na lista de produtos de comércio eletrônico. Na hora, queremos vender produtos por preço ou data. O índice evita a digitalização completa da coleção. Número quatro, quando usamos preenchimentos nos métodos find, update e delete O índice acelera essas operações. Agora vamos ver também quando não precisamos aplicar o índice. Número um, quando nossa coleção é pequena. Se tivermos apenas algumas centenas de documentos , a pesquisa sem um índice já é rápida. Número dois, nossos dados estão mudando constantemente. Os índices diminuem a velocidade, inserem, atualizam e excluem o método, porque o Mongo Di B deve sempre atualizar a árvore Por exemplo, um sistema de log. Nesse caso, novos registros são adicionados a cada segundo, e isso diminuirá se criarmos um índice para registro. Número três, quando já temos muitos índices, cada índice usa armazenamento, muitos índices são iguais ao Portanto, a solução é indexar apenas os preenchimentos mais importantes. Número quatro, quando estamos consultando muitos preenchimentos diferentes, devemos evitar Portanto, se nossas pesquisas variam muito em preenchimentos como nome, e-mail, idade, cidade, indexação, cada um pode não ajudar Portanto, a solução é apenas indexar preenchimentos usados com frequência. Então, para recapitular rapidamente, criamos um índice no Mongodi B quando temos Queremos tornar nossa consulta muito rápida. Não se preocupe, aplicaremos esses índices em nosso projeto quando precisarmos Agora, na próxima seção, começaremos a criar nosso Projeto dois, que é o back-end do aplicativo de comércio eletrônico 90. Seção 09 — Projeto 02 e planejamento: É hora de criar nosso segundo projeto. Neste projeto, vamos criar o aplicativo de comércio eletrônico Ben Não criaremos front-end porque esse não é o escopo deste curso. Para isso, tenho um curso separado de Reac JS. Agora, quando começo um novo projeto, gosto de planejar o projeto de forma aproximada. Isso me dará clareza e também recomendo que você faça o mesmo. Então, primeiro de tudo, temos que visualizar o front-end básico, não o design perfeito, apenas visualizar Por exemplo, aqui estamos criando um aplicativo de comércio eletrônico. Nesse site, o usuário pode criar uma conta ou fazer login no site. Depois disso, eles podem ver a lista de produtos e, ao clicar nesse produto, podem ver detalhes completos sobre esse produto, mais imagens e descrição. Não importa se o usuário está logado ou não. Todos os usuários podem ver os produtos. Depois disso, o usuário pode ver seu histórico de pedidos. Além disso, eles podem adicionar o produto ao cartão, remover o produto do cartão e fazer o pedido por meio de pagamento. Então, esses são os recursos que precisamos para nosso projeto. Não se preocupe se você não conhece todos os recursos do seu projeto, como eu disse, isso é apenas um plano. No futuro, podemos adicionar ou remover recursos do nosso aplicativo. Então, primeiro, começaremos com a criação da API de criação do modelo de usuário para autenticação do usuário. Depois disso, passaremos para os produtos, depois para o cartão e depois para os pedidos. Você vai adorar isso e também terá a confiança necessária para não criar projetos por conta própria. Vamos começar esse projeto incrível. 91. Criando um novo servidor: Agora, em nossa pasta de projetos, vamos criar uma nova pasta para nosso segundo projeto de comércio eletrônico chamada cart Wish Backend e simplesmente abrir esse projeto no código VS Bom. Agora, quando criamos um novo projeto, o que devemos fazer? Certo. Inicializaremos o projeto usando o NPM int Y. Isso criará um pacote de pontos e um arquivo Agora, aqui, criamos um novo arquivo chamado index dot js. Vamos criar um servidor Express para esse aplicativo. O Const Express é igual ao pacote Express exigido. Depois disso, estamos criando o aplicativo Express, aplicativo Const é igual a, e chamamos aqui essa função Express Agora vamos ouvir esse servidor, então o app dot LISN aqui, primeiro passamos a porta, mas no lugar de passar o valor codificado, criamos aqui a variável const port é igual ao processo dot nv dot Port processo dot nv dot Então, se tivermos uma porta no ambiente, ela usará essa porta, caso contrário, temos 3.000, e simplesmente passamos aqui pela porta em primeiro lugar E o que passaremos no segundo parâmetro, passaremos aqui a função de callback e simplesmente consol dot log O servidor está escutando na porta, pacotes Dollar Ci, porta Agora, vamos executar esse aplicativo e verificar se fizemos isso corretamente ou não. Por que eu acho que podemos obter um erro aqui? Vamos ver, o erro na vida dos desenvolvedores é constante. Não tenha medo disso. Abra o terminal e execute aqui nodebn index dot js. Veja, aqui temos um erro. Oh, esquecemos de instalar o pacote Express. Então, o NPM instala o Express. E se você quiser usar a mesma versão que a minha, escreva na taxa 5.1 0.0 e pressione Enter. Bom. Agora vamos tentar novamente. Veja, aqui temos o servidor ouvindo. Agora, na próxima lição, conectaremos esse aplicativo ao banco de dados. 92. Conectando ao banco de dados: Vamos conectar esse aplicativo a um banco de dados porque precisamos armazenar informações sobre usuários, produtos, etc Antes de tudo, em nosso projeto, temos que instalar mangas Não vamos repetir o mesmo erro. Abra o terminal e crie um novo terminal a partir daqui. Dessa forma, não precisamos interromper nosso aplicativo. Então, o NPM instala o Mongoose no vermelho 8.13 0.2. Bom. Vamos minimizar isso. Agora, em nosso arquivo de pontos de índice, importamos mangos const que é igual a require mangos E depois desse aplicativo, escrevemos Mongos dot connect No primeiro argumento, passamos nossa string de conexão. Se você não se lembra da cadeia de conexão do Mongo Di B, pode obtê-la no Mongo DB Aqui na barra lateral, temos essa conexão de host local e, no lado direito dela, temos a opção de três pontos Aqui, obtemos Copy Connection String. E cole na primeira posição. Agora, no final dessa cadeia de conexão, adicionamos o nome do nosso banco de dados, que é Card fish. Agora, como sabemos, essa expressão retorna uma promessa. Então, usamos aqui o método dot TN e dentro dele simplesmente o console dot log O MongoDB se conectou com sucesso. Agora, após o método, também adicionamos o método de cache de pontos para lidar com erros. Aqui, obtemos o objeto de erro, a função de erro e o log de pontos gonsol, conexão com o MongoDB, falha e imprimimos esse Agora vamos testar essa implementação, salvar as alterações e, no terminal, veja, aqui conectamos o Mongo DB com sucesso Na próxima lição, projetaremos nosso modelo de usuário. 93. Exercício — criando o modelo do usuário: Deixe-me fazer um pouco de exercício , porque já fizemos isso. Portanto, você precisa criar um modelo de usuário para este projeto. Você precisa decidir quais usuários preenchemos o que queremos para este projeto. Não se preocupe se você adicionar mais ou menos preenchimentos, mas o importante é pensar Portanto, lembre-se de quais são os recursos relacionados aos usuários e, de acordo com isso, decida o preenchimento do usuário. Defina um esquema para esses preenchimentos e, em seguida, crie um modelo com esse Depois de concluir este exercício, você pode ver a solução. Agora vamos ver a solução. Primeiro de tudo, vamos criar aqui uma nova pasta chamada models. E dentro dessa pasta, criaremos um novo arquivo chamado users dot js. Bom. Aqui, em primeiro lugar, importamos Const Mongos que são iguais às mangas necessárias Porque sem mangas, como podemos criar um esquema ou modelo O esquema de custo do usuário é igual ao novo esquema de pontos de manga. Nos colchetes de Cali, passaremos nosso esquema no par de valores-chave Em primeiro lugar, nomeie o objeto, definimos seu tipo como string, necessário para desenhar, e definimos o comprimento médio como três. Depois disso, podemos definir campo Email e definir seu tipo como string, também obrigatório como verdadeiro, também precisamos exclusivo para verdadeiro, porque todos os usuários devem ter apenas um e-mail exclusivo E para a melhor prática, também adicionaremos minúsculas a Depois disso, qual campo podemos adicionar, sim, podemos adicionar a senha, digitar a string e também precisamos que seja verdadeiro. Depois disso, para usuários de comércio eletrônico, precisamos do endereço de entrega para entregar o produto. Portanto, digite a string necessária para verdadeira e também definimos o comprimento médio como cinco. Depois disso, podemos especificar a função de cada usuário, seja ele usuário ou administrador. Então, definimos seu tipo como string. Podemos restringir o campo de função a apenas duas opções usando a propriedade Enum para matriz Aqui passamos nossos valores de usuário ou administrador. Além disso, podemos definir seu valor padrão como usuário. Se quisermos mudar a função para administrador , precisamos acessar o banco de dados. Por padrão, a função de todos os usuários é definida apenas como usuário. Acho que são praticamente todos os campos do modelo de usuário. Se, no futuro, precisarmos de mais funcionalidades , também poderemos modificar o esquema Não se preocupe com isso. Além disso, se durante o exercício você usar nomes diferentes para esses preenchimentos, poderá alterá-los, assim como os meus Caso contrário, isso poderá causar um bug no futuro. Agora temos o esquema do usuário pronto, para que possamos criar um modelo usando esse esquema Portanto, o usuário Const é igual ao modelo de pontos de Mongos e ao que passamos na primeira posição Certo, passamos o nome singular do modelo que é usuário. No segundo argumento, passamos o esquema do usuário Além disso, vamos exportar esse modelo de usuário. Precisaremos dele na rota do usuário. As exportações de pontos do módulo são iguais ao usuário. Perfeito. Agora, na próxima lição, criaremos a primeira rota desse projeto para criar um novo usuário. 94. Criando o novo usuário: Agora vamos criar uma API para criar um novo usuário. Aqui, criamos uma nova pasta chamada routes. Nessa pasta, criaremos todas as nossas rotas em arquivos separados. Crie um novo arquivo users dot js. Agora, você se lembra de como podemos criar a API em um arquivo separado? Se precisarmos criar uma API em nosso arquivo js de ponto de índice principal , podemos usar essa variável de aplicativo. Mas como podemos criar uma API em um arquivo separado? Certo, vamos criar um roteador para isso. Então, primeiro, inserimos Express igual ao Express exigido. Depois disso, esse expresso tem um método de roteador que podemos chamar. Isso nos dará um roteador. Armazene-o em um roteador variável. Bom. Agora vamos criar uma API para criar um novo usuário. Qual método podemos usar aqui, get ou put, usaremos o método post. Então o roteador foi postado. Aqui escrevemos nosso endpoint, que é a barra frontal, e depois desse endpoint, adicionaremos a função de retorno de chamada, que será executada quando alguém chamar a API Essa função tem dois parâmetros: solicitação e resposta, e função de erro. Agora, em primeiro lugar, nesta função, queremos valores que o usuário passe no corpo da solicitação. Portanto, os dados do usuário const são iguais ao corpo do ponto da solicitação. Vamos fazer o Const dot registrar esses dados do usuário. E depois disso, simplesmente respondTsn ou podemos usar aqui o ponto de resposta JSON porque estamos enviando dados JSN, que são esses dados que Agora vamos verificar se nossa API está definida corretamente ou não. Gosto de dar pequenos passos porque isso não cria confusão. Isso está funcionando, então podemos passar para a lógica principal. Atualmente, definimos a API aqui, mas precisamos adicionar essa rota em nosso arquivo index dot js. Caso contrário, não funcionará. Nós sabemos disso direito. Então, vamos exportar esse roteador usando o módulo dot exports é igual ao roteador. Salve este arquivo e vá para o arquivo index dot js. Aqui, após a conexão Mongo DV, podemos adicionar o app dot U e, na primeira posição, adicionaremos nosso prefixo de API, slash API slash user e, na segunda posição, teremos que passar por Router, que exportamos que Então, na parte superior, adicionamos que o custo das rotas do usuário é igual aos períodos exigidos aqui. Aqui vamos para a pasta de rotas e, dentro dela, a rota dos usuários. Agora podemos simplesmente passar rota desse usuário aqui. Nós já fizemos isso. Lembre-se, e não se preocupe se você não se lembrar da sintaxe, está tudo bem Muitas vezes, eu também esqueci a sintaxe. Por enquanto, concentre-se na criação do aplicativo. Salve as alterações e vamos testar essa API do usuário. Então, no concurso aqui podemos ver nossa atividade anterior, mas não quero misturar as coisas com o projeto anterior, vamos para as coleções e, do lado direito, temos a opção de nova coleção e damos a ela o nome de cartwis Adicionaremos todo o nosso gosto de API a esta coleção. No lado direito, temos mais opções. Clique em Criar nova pasta e dê a ela o nome de usuários. Portanto, nesta pasta de usuários, salvaremos todos os nossos gostos de API relacionados ao usuário. Você pode ver como isso parece sistemático e, se, no futuro, visitarmos esse projeto, não nos confundiremos. Então, criamos uma nova solicitação e damos um nome a ela. Crie um novo usuário. Selecione o método a ser postado e inserimos nosso URL de API, que é DTP, coluna Abo, barra frontal, host local, coluna 3.000 ou o que você usa como usuário de APIs coluna Abo, barra frontal, host local, coluna 3.000 ou o que você Não se esqueça de adicionar esse prefixo. Para enviar dados no corpo da solicitação, selecionamos seu corpo e passaremos os dados aqui no formato JSON Objeto, primeiro nome do campo, certifique-se de escrever em códigos duplos. Value to code plas Em seguida, temos um e-mail para codificar no gmail.com vermelho Depois disso, qual preenchimento adicionamos, deixe-me verificar o esquema do usuário Sim, temos senha e status de entrega e ambos são obrigatórios. Senha e, em sequência, um, dois, três, 45678 e endereço de entrega, digamos XYZ, em XYZ Certifique-se de usar o mesmo nome preenchido que usamos no esquema Caso contrário, obteremos um erro. Agora, vamos enviar essa solicitação. O que você acha? Vai funcionar ou não? Vamos ver. Envie a solicitação. Veja, aqui temos o status 200, o que significa ok, mas não recebemos nossos dados na resposta a essa solicitação. Vamos verificar o console A. Veja aqui também, ficamos indefinidos Você consegue adivinhar por que isso acontece de novo? Lembre-se de que, quando queremos obter dados da solicitação do corpo, precisamos usar um middleware para converter os dados em JSNFMat Agora você se lembra, no arquivo index dot js, antes dessa rota, adicionamos app dot ug para adicionar middleware e simplesmente passamos aqui express Com isso, obteremos dados da solicitação do corpo. Veja se as mudanças. Vamos enviar a solicitação novamente. Veja, agora que estamos obtendo os dados na resposta, nossa implementação atual está funcionando. Agora vamos salvar esses dados na coleção do nosso usuário. Mas antes de salvar os dados na coleção do usuário, precisamos verificar se esse usuário já existe em nosso banco de dados ou não. Não se confunda, veja isso e suas cotas serão limpas. Aqui, precisamos de um modelo de usuário para executar a consulta. custo do usuário é igual ao exigido aqui, temos que subir uma pasta, ponto, ponto, cortar modelos e ir para o modelo de usuários Agora, após esses dados do usuário, podemos fazer algo como esse usuário dot Fine. Aqui passamos objeto por filtro. Aqui encontraremos o usuário por seu e-mail exclusivo e, por valor, passamos aqui userdata dot email Então, estamos encontrando o usuário, qual e-mail é o mesmo que esse e-mail userdata dot Além disso, aqui está uma coisa. Se não tivermos nenhum usuário cujo e-mail seja igual a esse e-mail userdata dot, esse método find retornará uma matriz vazia Então, em vez desse método find, podemos usar aqui Find one method. Se o usuário não existir , esse método find one retornará indefinido e isso nos ajudará a escrever a condição Então, usaremos aqui Encontre um método. Como sabemos, essa expressão retornará promise, então temos que aguardar aqui e, para usar await, temos que tornar essa função Cavey Bom. Agora, vamos armazenar o resultado na variável chamada usuário. Agora você pode simplesmente colocar aqui a condição. Se o usuário estiver disponível, retornaremos um erro na resposta. Então responda o status do Dodge para 400 por solicitação inválida e também na resposta quero enviar dados, então pontue o Json, e aqui passamos o objeto com a mensagem que o usuário já existe Agora, aqui está uma coisa. Se o usuário já estiver disponível, não queremos executar essa lógica inferior. Para fazer isso, temos que passar aqui status de retorno antes desse ponto de resposta. Caso contrário, ele executará o código para frente. E se o usuário não estiver disponível na coleção do usuário? Certo, armazenaremos os dados do usuário na coleção. Portanto, const new user é igual a new user, e aqui no objeto, passamos nossos dados Então, nomeie para userdata dot name e envie um e-mail para userdata dot Espere, aqui temos que gravar dados do usuário várias vezes. Em vez disso, podemos desestruturar nosso objeto aqui. Então, no local dos dados do usuário, adicionamos Object e passamos nome dos preenchimentos que obtemos do corpo do ponto da solicitação Isso é chamado de desestruturação de objetos. Portanto, temos nome, e-mail, senha e último endereço de entrega. Certifique-se de escrever aqui o mesmo nome preenchido que passamos no corpo do ponto da solicitação. Agora, no lugar do nome do ponto de dados do usuário, podemos escrever somente o nome Além disso, se o nome da propriedade e nome da variável de valor forem iguais, podemos removê-los. Mas, para sua compreensão, não vou removê-lo. E-mail para e-mail senha para senha e endereço de entrega para endereço de entrega. Além disso, temos que mudar aqui no método fino, de e-mail para e-mail. Agora temos um novo objeto de usuário, então podemos salvá-lo em nosso banco de dados, novo usuário dot c, e essa é a operação Async É por isso que aderimos e aguardamos. Agora, isso retornará o usuário armazenado do banco de dados. Se não quisermos retornar os dados armazenados do usuário , também podemos usar esses novos dados do usuário. Não se preocupe, obtemos identificação em ambos os objetos. Então, na parte inferior, aderimos status do ponto de resposta Diga-me o código de status que usaremos para novos dados. Certo, usamos Json de 201 pontos e aqui passamos um novo objeto de usuário Perfeito. Agora vamos testar essa implementação. Salve as alterações e vamos enviar a solicitação de publicação. Veja, aqui temos um novo usuário com seu ID exclusivo. E se verificarmos nosso banco de dados, atualizarmos o banco de dados, aqui temos o Cardwish Dentro disso, temos usuários, e aqui temos nosso primeiro usuário. E se enviarmos a mesma solicitação com as mesmas informações do usuário? Veja, aqui temos o usuário que já existe com erro, 400 solicitações inválidas. Perfeito. 95. Hashing a senha para segurança: Agora, atualmente em nossos dados de uso, estamos armazenando a senha em uma string simples. Mas e se alguém tiver acesso ao nosso banco de dados, qualquer pessoa poderá ver as senhas reais do usuário. Para resolver esse problema, podemos colocar a senha em uma string aleatória, o que torna nossa senha ilegível Para ter a senha, usamos uma biblioteca muito popular chamada BCrypt O NPM instala o BCRP. Não se preocupe com isso. É muito simples. Entenderemos a combinação de senhas em um arquivo separado e, ao final, a adicionaremos à rota de nosso usuário Aqui, criamos um novo arquivo chamado pass dots. Bom. Agora, primeiro de tudo, importamos const, Bcrypt é igual a exigir Bcrpt Agora, o Bcrpt é especialmente forte porque tinha SLD. Você pode perguntar o que é vendido? SALT é um dado extra aleatório adicionado a uma senha antes que ela seja adicionada. Deixe-me explicar em palavras simples. Digamos que temos dois usuários, usuário A e usuário B, e ambos escolhem a senha. Digamos que um, dois, três, quatro, cinco. Agora, suponha que nosso pacote BrP tenha essa senha que pode ser parecida com esta Se tivermos apenas um, dois, três, quatro, cinco, sem nenhum sal, o usuário A e o usuário B terão senha. Tenha a mesma aparência no banco de dados. Isso é um problema porque dizem que esses dois usuários têm a mesma senha. Se os hackers virem uma senha de atenção idêntica , eles poderão adivinhar que os dois usuários têm a mesma senha simples Portanto, precisamos do SLT para resolver esse problema. SALT não é nada, apenas dados aleatórios, adicionados a uma senha antes de responder. Então, antes de UseraPassword, adicionamos alguns dados aleatórios, então a senha fica assim Para a senha do usuário B, adicionamos alguns dados aleatórios ou vendemos. Então, sua senha é parecida com esta. Não é necessário, o Bcrypt mantém a mesma senha. Eu só te mostro para entender. Deixe-me mostrar isso na prática. Aqui podemos usar crypt dot e essa função, exceto dois argumentos primeira é a senha original, que é a senha digitada pelo usuário. Por exemplo, aqui passamos um, dois, três, quatro, cinco e o segundo argumento é vendido por rodada. Isso controla o custo do traseamento. Alto valor significa mais segurança, mas mais lentidão. Normalmente, um valor de dez é considerado seguro e razoavelmente rápido Agora, no terceiro parâmetro, veja, aqui temos que passar a função de retorno de chamada porque essa é uma operação assíncrona Mas em vez de usar callback, podemos usar aqui um peso no início Para usar um peso, precisamos escrever essa expressão com uma função de sincronização chamada passe. E simplesmente movemos essa linha para essa função. Agora armazene aquela invariável chamada st pass e simplesmente console o log de pontos dessa st Agora, vamos chamar essa mesma função duas vezes para que possamos ver a senha semelhante ou que o SALT esteja funcionando. Abra o terminal e simplesmente execute node spass dot js. Veja, aqui temos duas senhas diferentes. Mesmo se passarmos a mesma senha um, dois, três, quatro, cinco, para a, esse é o poder do SLT. Vamos implementar esse código na rota do nosso usuário. Corte essa linha daqui e cole-a antes da nossa nova variável de usuário. Agora vamos fazer algumas pequenas mudanças aqui. Primeiro, alteramos essa senha codificada um, dois, três, 45 com nossa senha, que obtemos do corpo da solicitação Isso gerará uma senha para esse usuário. No local de salvar a senha original, armazenamos essa senha. Além disso, temos que importar o Bcrt na parte superior. Const Bcrypt é igual a exigir BCR. Separa as mudanças e dá uma olhada. Em nosso banco de dados, usamos dados sem hesitar. Então, podemos excluir esse registro daqui, excluí-lo. Agora vamos executar nosso aplicativo usando o índice normon dot js. Bom. Agora, novamente, envie a solicitação de postagem com os mesmos dados. Veja, agora temos a senha com sucesso e a armazenamos em nosso banco de dados. Mesmo que alguém tenha entrado em nosso banco de dados, não conseguirá ver a senha como ela está. 96. Validação de entrada do usuário usando Joi: Agora, atualmente, nossa rota de usuário está funcionando bem. O usuário Weg já está cadastrado ou não, e também estamos usando a senha, mas existe uma regra para os desenvolvedores do Bend. Nós, como desenvolvedores do Bend, nunca confiamos nos dados enviados pelo cliente. Temos que sempre validar esses dados. Suponha que no local do nome, senha do cliente, propriedade do nome do usuário. Além disso, às vezes eles se esqueciam de enviar e-mail ou até mesmo senha Nesse momento, não podemos armazenar metade das informações em nosso banco de dados. Agora você pode dizer que já configuramos a validação em nosso esquema Se precisarmos adicionar mais uma validação, sim, geralmente é uma boa ideia adicionar várias camadas de validação além do que está configurado no esquema Vamos realizar a validação de dados de back-end nesta lição. Essa é outra camada da validação. Se o Acker de alguma forma ignorar essa camada de validação, então já temos a validação no esquema que impedirá que dados inválidos entrem em nosso banco de dados Aqui temos duas opções. Pode ser executado manualmente ou podemos usar um pacote muito popular chamado Joy. Além disso, temos outros validadores como Express validator, Yup e validator Você pode usar o que quiser. Adoro o Joy porque é versátil e fácil de usar e se integra bem a muitos frameworks nodejs, especialmente Deixe-me te mostrar isso. Abra o terminal e escreva NPM, instale o Joy ethert 17.13 0.3. Bom. Agora, usar a alegria é muito simples. Em primeiro lugar, importaremos alegria neste arquivo. Então, alegria constante com J é igual a exigir alegria. Você já sabe por que escrevemos aqui J porque esse pacote de alegria retorna uma aula. Agora, com alegria, temos que definir o esquema para os dados do corpo da solicitação Nesse esquema de alegria, fazemos muitas coisas, mesma forma que fizemos no esquema do usuário Definimos aqui uma nova variável chamada esquema de usuário ou criar esquema de usuário é igual a, e aqui passamos o objeto joy dot e, dentro disso, passamos nosso objeto de esquema Neste objeto, passamos nossos campos com o esquema Joy. Qual é o tipo de propriedade? É necessário? Qual é o valor médio, o valor máximo ou o comprimento médio da string ou o comprimento da string e muito, muito mais Em primeiro lugar, precisamos de um nome para alegria aqui, podemos especificar o tipo de campo que é string. Certifique-se de chamarmos essa função aqui. Agora também podemos adicionar aqui a média a três caracteres, e também queremos que isso seja preenchido como obrigatório. Existem muitos métodos de alegria. Você pode ver todos os métodos usando sua documentação. A seguir, temos aqui o e-mail fill joy dot string. Agora, para aproveitar o e-mail, temos o método de e-mail, também valida o e-mail e também fixa esse preenchimento conforme necessário Em seguida, temos a senha para joy dot string dot Min 26 letra de senha, e também precisamos que isso seja necessário. Por fim, queremos validar seu endereço de entrega para joy dot dot Min to Pi e obrigatório Bom. Aqui temos esse esquema Joy, agora queremos aplicar esse esquema nos dados que estamos obtendo no corpo do ponto da solicitação É por isso que escrevemos o mesmo nome de campo que passamos no corpo do ponto da solicitação. Para validar os dados usando o Joy, temos que usar esse método criativo de validação de pontos do esquema de usuários validação de pontos Dentro disso, temos que passar quais dados queremos validar e quais queremos validar, o corpo do ponto da solicitação Agora, isso retornará o objeto que armazenamos na variável chamada Joe validation. Deixe-me mostrar o que obtemos nessa variável de validação do Joy. Eu comento esse código inferior e apenas valido o corpo do ponto de solicitação aqui e simplesmente retorno o ponto de resposta json, validação de Joy Diga isso em Js e dê uma olhada. Envie a solicitação de postagem. Veja aqui nossos dados são validados. É por isso que preenchemos o valor. Se eu remover essa senha do corpo do ponto da solicitação e enviar o Again. Veja, aqui obtemos o objeto de erro e nele temos esses detalhes, que é matriz, e nisso recebemos a mensagem de erro. A senha é obrigatória. Ao usar esse objeto de erro, podemos retornar um erro em nossa resposta. Não se confunda. Deixe-me te mostrar isso. Remova esse método JSN de ponto de resposta. Não precisamos disso e simplesmente escrevemos aqui I condicione e verificamos se o erro de validação do joy está disponível e, em seguida, simplesmente retornamos o erro na resposta. Retorne o status do ponto de resposta, 400 para o ponto de solicitação inválida Json, e aqui retornamos o objeto de erro de ponto de validação do Joy Agora, como uma boa prática, os desenvolvedores não passam o objeto de erro completo daqui. Eles gostam de enviar apenas mensagens de erro. Adicionamos detalhes de pontos, que são a matriz, e acessamos seu primeiro elemento entre colchetes, zero índice de pontos. Mensagem, vamos testar isso, enviar a solicitação sem preencher a senha Veja, aqui temos a senha necessária. Se passarmos a senha preenchida novamente, então desfaça, mas no nome, passaremos apenas dois caracteres E envie a solicitação. Veja, aqui recebemos uma boa mensagem de erro. O tamanho do nome deve ter pelo menos três caracteres. Na validação do esquema Mongo, não recebemos esse tipo de mensagem de erro, e é por isso que os desenvolvedores gostam de Agora, aqui, eu tenho uma pergunta. Se não passarmos aqui duas falhas, o que obteremos. Portanto, remova esses dois primeiros preenchimentos. Envie a solicitação. Veja, aqui temos apenas um erro. Joey executou a validação linha por linha. Se a primeira linha não for validada, ela retornará imediatamente um erro É por isso que retornamos sempre os detalhes da mensagem de pontos do primeiro elemento. É assim que validamos dados de entrada que obtemos do corpo da solicitação Você pode remover o comentário de outro código. Deus. Para recapitular rapidamente, existem três camadas de validação no mundo real, a validação do lado do cliente, que os desenvolvedores de front-end realizam no navegador Os usuários podem ver isso no formulário de front-end. Em seguida, temos a validação paralela do Bacon, que acabamos de fazer usando joy. Com isso, estamos validando os dados, que estamos obtendo do front-end no corpo do ponto da solicitação Em seguida, temos o esquema Mongo, que é a validação final Impedirá a entrada de dados inválidos no banco de dados. Se alguém passar pela validação do lado do cliente , teremos a validação do lado do vagão e, se alguém passar na validação também, esquema Mangus estará sempre lá adição dessas camadas fornece uma abordagem robusta para evitar que dados inválidos entrem em nosso banco de dados e garante uma aplicação segura e confiável Agora você pode ver que estamos trabalhando como profissionais. Agora, na próxima lição, veremos como a autenticação do usuário funciona no mundo real. 97. Como a autenticação funciona: Agora vamos falar sobre a autenticação do usuário no node js. autenticação do usuário desempenha um papel muito importante em qualquer aplicativo. nodejs, fazemos autenticação usando JWT, ou podemos dizer que é JSN ou podemos dizer Agora você pode perguntar: o que é esse JWT ou JSN WebTken? Não se preocupe com isso. É muito simples. token web JSON é uma longa cadeia de caracteres , parecida com esta Ao usar esse token, que geraremos no back-end, podemos autenticar o usuário Deixe-me explicar com um exemplo de como autenticação funcionava antes do JWT e como funciona agora Aqui está uma Harley que ele faz login com as informações da conta, e-mail e senha Agora, nosso servidor primeiro verifica as informações e, se forem verdadeiras, servidor retorna seu ID de usuário como resposta e o armazena na sessão ou ooki Agora, sempre que ele envia solicitações de informações seguras, digamos, todas as suas informações bancárias. Portanto, o servidor primeiro solicita o ID do usuário e, se ele tiver o ID do usuário, servidor envia as informações seguras. Mas aqui está um grande problema, o SSN ou Cookie no qual armazenamos nosso ID de usuário, que pode ser facilmente modificado no navegador Digamos que eu altere esse ID de usuário para o ID de usuário de outra pessoa e, em seguida, obtemos as informações sobre esse usuário. Essa abordagem não é segura. Agora, para resolver esse problema, apresentamos o token web JSN Agora Harley faz login novamente com seu e-mail e senha. Agora, nosso servidor primeiro verifica as informações e, se forem verdadeiras, servidor retorna o token exclusivo criptografado por muito tempo como resposta e o armazena no armazenamento local. Agora, o melhor desse token é que ele é feito com detalhes de uso e uma chave secreta que somente definiremos no servidor. Ninguém sabe a chave secreta , exceto você e sua equipe. Portanto, sempre que a Harley envia uma solicitação de informações seguras , no servidor, primeiro solicitamos o token JWT e o verificamos usando nossa chave secreta Se for verificado, em quando do servidor, enviaremos essas informações protegidas. E se alterarmos alguma coisa nas informações do usuário , nosso token também mudará. Como desenvolvedor do Bend, nosso trabalho é enviar o token web JSN quando os usuários se inscrevem ou fazem login e também verificar o token quando necessário Armazenar o token no armazenamento local e tudo mais é tarefa do desenvolvedor front-end. Defina uma soma. Quando os usuários fazem login ou se registram com sucesso, enviamos o token web JSON, que simplesmente funciona como cartão de segurança Quando o usuário solicita dados que só podem ser acessados pelo usuário logado , o servidor primeiro verifica a placa de segurança, que é nosso token web JSON, e valida com a chave secreta do JWT Esse token é verificado, somente então o servidor retorna os dados para esse usuário. Simples assim. Agora, na próxima lição, geraremos o token web JCN e o enviaremos em resposta 98. Gere o token JWT para o usuário: Então, entendemos o token web JN. É como um cartão de segurança. Agora vamos gerar um token quando o usuário se cadastrar com sucesso e enviar um token na resposta. Portanto, para gerar o token web JSN, precisamos do pacote do token web JSN, abrir o terminal e escrever o NPM, instalar o token web JSN E se você quiser instalar a mesma versão que a minha, escreva na taxa 9.0 0.2 e pressione Enter Bom. Agora, no arquivo do nosso usuário na parte superior, importamos esse pacote usando require e simplesmente o armazenamos em uma variável chamada JWT Agora, quando queremos criar esse token, no início ou finalmente, queremos criar um token quando nossos dados de usuário forem armazenados com sucesso. Depois desse mesmo método, escrevemos JWT dot Sign No método sign, temos que passar dois argumentos Primeiro, temos que passar os dados que queremos enviar dentro do token. Por enquanto, queremos apenas enviar o ID do usuário com nosso token. Objeto e primeira propriedade, sublinhado para ID de sublinhado nwuser Certifique-se de escrever aqui, sublinhado ID. Eu já cometi esse erro antes. Além disso, quero enviar a propriedade name desse nome de usuário para o usuário dot N. Agora, no segundo argumento, temos que passar string, que é nossa chave de segurança Por enquanto, passamos GWT, chave de segurança. Podemos passar qualquer string. Não há regras para a chave. Além disso, atualmente estamos passando essa chave diretamente. Mas na próxima lição, vamos adicioná-la à variável de ambiente. Não se preocupe com isso. Agora, isso gerará um token web JSN, então nós o armazenamos em uma variável chamada token Simplesmente no local de envio dos novos dados do usuário, passamos apenas o token. Deixe-me mostrar a aparência desse token. Salve as alterações e, a partir do cliente Thunder, enviamos novos dados do usuário, escrevemos o nome completo e alteramos o e-mail para o código one@gmail.com. Certifique-se de adicionar a vírgula e enviar a solicitação. Veja, aqui temos esse token longo, que acabamos de gerar. Agora, deixe-me mostrar mais sobre esse token. Então, copie esse token JWT. Certifique-se de não copiar esses códigos duplos. Abra uma guia no seu navegador e pesquise jwt dot IO. E essa é a documentação oficial do JWT. Aqui nas bibliotecas, você pode ver a implementação do JWT para diferentes bibliotecas Agora, volte para a página principal e role para baixo até a seção Depurador E aqui podemos decodificar nosso token. Agora, vamos entender o que o token contém. Então, passe nosso token aqui. Agora, todos os tokens do GWT estão divididos em três partes. A primeira parte é sobre o cabeçalho, que está na cor vermelha. segunda parte é sobre a carga útil, que está na cor roxa e última e mais importante parte é a assinatura, que está na cor azul Agora, esse cabeçalho contém o algoritmo e o tipo de token, o que é muito comum. Concentre-se nisso. Em seguida, essa carga contém os dados que queremos passar com o token Nesse caso, passamos o ID do usuário e usamos um nome, que é esse objeto nesse método de sinal. O motivo pelo qual passamos esses dados aqui é que podemos exibi-los em nosso front-end sem chamar uma API separada. Depois disso, temos mais uma propriedade It, que significa emitido em e seu valor é o momento em que nosso token é gerado. Com isso, podemos ver a idade do nosso token. A última parte, que está em azul, é a assinatura, e é gerada com base em nosso cabeçalho, nesses dados de carga útil e na chave secreta que só está disponível em nosso servidor Portanto, isso evitará que os usuários obtenham seu próprio token e o modifiquem com o ID para fingir ser outra pessoa. Porque se você modificar alguma coisa nessa carga ou cabeçalho, a assinatura será regenerada Portanto, não há chance de os usuários fazerem algo antiético Somente com essa chave secreta, nosso token será validado. Caso contrário, isso nos dará um erro. É por isso que o JWT é tão popular. Resumindo rapidamente, quando os usuários fazem login ou se registram com sucesso, obtemos o token web JCN, que simplesmente funciona como um cartão de segurança Quando o usuário solicita dados que só podem ser acessados por usuários do LogN , o servidor primeiro verifica o cartão de segurança, que é nosso token web JCN e o valida com a chave secreta do JWT Os dois são verificados, somente então o servidor retorna os dados para esse usuário, simples como definido. 99. Configurando a expiração do token: Muitos desenvolvedores, como boa prática, definem um tempo de expiração para esse token web JSON, como 2 horas ou 24 horas Após esse período, esse token não será válido. Se o usuário quiser um novo token, ele precisará fazer o login novamente. Então, para isso, podemos passar terceiro argumento neste método JWT Sign, Object, e nele temos uma propriedade chamada expires Podemos passar valores em milissegundos, se quisermos definir 2 horas, depois escrever dois por 2 horas em 60 por minutos porque 1 hora tem 60 minutos novamente, porque 1 minuto tem 60 segundos e em 1.000 para converter segundos em milissegundos Você pode ver que isso é um pouco confuso. Então, também podemos passar aqui de corda a ponta, o que é de 2 horas. Ou podemos escrever aqui um dia por um dia. Sempre que você quiser. Um valor numérico é interpretado como uma contagem de milissegundos Se você usar uma string, certifique-se de fornecer as unidades de tempo, como dias, horas etc Caso contrário, a unidade de milissegundos é usada por padrão. Então, se passarmos aqui apenas 120 em string, então é igual a 120 Eu gosto de definir 2 horas, então duas pontas, esse tempo de expiração realmente depende da sua aplicação Você pode notar nos aplicativos bancários seu login expirou na última vez, por exemplo, de cinco a 10 minutos. Depois disso, você precisa fazer o login novamente. O motivo pelo qual eles usam o tempo de expiração para o token é porque desejam proteger seu aplicativo outro lado, muitos sites de mídia social definem o prazo de validade para 30 dias ou 60 dias Depois de fazer o login, eles não expiram seu token porque querem que usemos mais de suas mídias sociais O tempo de expiração depende do seu projeto. Escolha o melhor para sua aplicação. Apenas certifique-se de não se irritar com o ExpiryT. 100. Proteja a chave de segurança no ambiente: Atualmente, passamos nossa chave secreta do JWT diretamente aqui. Mas no mundo real, isso não é seguro porque, quando implantamos nosso aplicativo na Internet, também carregamos nosso código em alguma nuvem, como o Github ou o Gitlab Se escrevermos nossa chave secreta nesse código, todos poderão ver nossa chave secreta, e isso não é seguro. Portanto, no local de definir a chave secreta aqui, podemos editar no arquivo DOT ENV Neste projeto, não criamos o arquivo DOT ENV. Crie um novo arquivo aqui chamado dot ENV. Nesse arquivo, simplesmente definimos a variável chamada chave de sublinhado JWT igual a, aqui escreveremos nossa chave, que é a chave de segurança JWT Além disso, muitos desenvolvedores gostam de adotar nome de chave aleatório para que ninguém possa prever a chave de segurança. Você pode usar qualquer chave de segurança, apenas para manter o backup dessa chave de segurança. Agora, para acessar essa variável-chave de sublinhado do JWT em nosso projeto, precisamos configurar Dot NV e qual pacote usamos para isso, precisamos do pacote dotNV, abrir o terminal e simplesmente instalar o Dot ENV abrir o terminal e simplesmente Bom. Agora, no arquivo index dot js na parte superior, adicionamos require dot NV e chamamos aqui o método dot config Salve esse arquivo e, na rota do usuário aqui no local dessa string codificada, adicionamos process dot nw dot à nossa variável, que é JWT que é JWT E pronto. Agora, se precisarmos usar essa chave novamente, não precisamos escrever a chave original. Podemos escrever o ponto E do processo e uma chave de sublinhado JWT de ponto. Agora, na próxima lição, criaremos uma rota de login na qual faremos a autenticação, e-mail e senha 101. Exercício Criar rota de login: Agora é hora de fazer um pouco de exercício. Você precisa criar uma nova API para login, portanto, deve ser uma solicitação de postagem com slash da API de endpoint E no corpo dessa solicitação, usuário pode passar duas propriedades, e-mail e sua senha. Então, primeiro de tudo, nesta API, você precisa encontrar o usuário por e-mail. Se você não encontrou o usuário, precisará enviar um erro em resposta com credenciais inválidas da mensagem e, se o usuário estiver disponível, será necessário comparar a senha Apenas essas duas etapas. Não se preocupe em comparar a senha, saia do exercício a partir desse ponto. Basta definir a nova API e encontrar o usuário por e-mail. Depois de concluir o exercício, você pode observar a solução. Então, espero que você resolva este exercício ou pelo menos tente resolver isso. Dê crédito a si mesmo por isso. Agora vamos ver a solução. Primeiro, na parte inferior, definimos uma nova API usando o roteador dot post. Aqui, na primeira posição, passamos o login do endpoint slash Na segunda posição, passamos a função de retorno de chamada com dois parâmetros, solicitação e resposta, e a função de seta aderente Agora, deixe-me mostrar minha trigonometria para escrever código sem confusão Gosto de escrever etapas em comando. Por exemplo, aqui, o primeiro passo é encontrar o usuário do banco de dados por e-mail. Se encontrarmos o usuário, depois disso, compare a senha criptografada. Se a senha corresponder, criaremos o token web JSON e o enviaremos em resposta Dessa forma, obtemos o caminho claro para escrever o código. Primeiro passo, temos que encontrar o usuário por e-mail. Para isso, precisamos obter dados do corpo do ponto da solicitação. Os dados de custo são iguais ao corpo do ponto da solicitação. Ou também podemos desestruturar nosso objeto aqui. Então, no local dos dados, adicionamos objeto e acessamos nossas propriedades, e-mail e senha. Agora, usando este e-mail, encontramos o usuário. Portanto, o usuário Const é igual a aqui, temos que aguardar o ponto do usuário. Tudo bem aqui passamos objeto de comparação e comparamos o e-mail preenchido com nossa variável de e-mail, mesmo que fizemos anteriormente Aqui, obtemos um erro de tempo de execução ao usar um peso. Temos que tornar nossa função assíncrona. Bom. Agora podemos verificar a condição. Se o usuário não estiver definido, retornaremos aqui o erro. Status de ponto de resposta 401 para credenciais inválidas, e também enviamos objeto GSN com credenciais inválidas de propriedade de mensagem Agora, e se o usuário for encontrado? Sim, temos que verificar se a senha está confusa ou não, mas aqui está uma coisa Armazenamos a senha do usuário em formato criptografado. Não podemos compará-lo diretamente com uma senha de string simples. Então, aqui temos que usar novamente o pacote crypt. Então crypt dot compare a primeira posição, passamos a senha, que obtemos do corpo do ponto da solicitação, e depois disso, temos que passar uma senha, que armazenamos no banco de dados Então, senha do ponto do usuário. Agora, essa expressão novamente leva pouco tempo, então podemos esperar aqui e simplesmente armazenar esse resultado em uma senha variável válida Podemos passar novamente a condição se a senha válida não estiver disponível e retornarmos o mesmo erro com a mesma mensagem de erro. Eu colo essa linha aqui. Agora você pode se perguntar por que enviamos a mesma mensagem de erro? É porque, por motivos de segurança, se especificarmos que a senha não corresponde , isso significa que encontramos usuário e apenas a senha não corresponde. É por isso que os desenvolvedores enviam esse tipo de mensagem de erro com credenciais inválidas Agora, se a senha corresponder , teremos que criar um novo token Eu copio o código da API de registro e colo em nossa API de login. Só nós para fazer pequenas mudanças. Aqui nos dados, temos que passar o ID de sublinhado do ponto do usuário e o nome do ponto do usuário No final, simplesmente enviamos esse token para o ponto de resposta Json. Bom. Agora vamos provar essa implementação. Então, vá para o cliente Thunder e, na coleção do usuário, crie uma nova solicitação e dê um nome a ela, faça login como usuário Altere o método para publicar e o URL para STP, chame uma barra dupla Localhost 3.000 barra API slash usuários slash E no corpo, passamos Object com preenchimento de e-mail. Aqui, passamos um e-mail, qual não criamos o código 12 athergmil.com Passe também a senha 12345678 e envie a solicitação. Veja, aqui recebemos uma mensagem de erro com credenciais inválidas. Agora, se escrevermos um e-mail válido passarmos a senha errada e enviarmos a solicitação, veja, ainda receberemos o mesmo erro. Agora, se passarmos por escrever e-mail e escrever a senha e enviar a solicitação, veja, agora obtemos o JSON Web Token É assim que criamos a API de login. Simplesmente, temos que encontrar o usuário, comparar sua senha com o pacote BCR. Se corresponder, geramos o JSN WebTken e o enviamos em resposta, simples assim Agora, antes de prosseguir, aqui nós literalmente copiamos e colamos o código para gerar o token web JSON Só mudamos esses dados. É melhor criarmos uma função separada para gerar o token e depois usá-la nas duas APIs Então, na parte inferior, criamos uma nova função chamada generate token igual à função arrow. Agora, a partir dessa função, queremos simplesmente retornar o token. Copie esse método JWT dot Sine e cole-o aqui. Agora, aqui, queremos apenas passar dados diferentes. Substituímos esse objeto de dados pela variável de dados e obtemos esses dados do parâmetro. Além disso, se você quiser definir um tempo de expiração de token diferente, também poderá passar um parâmetro para isso Por enquanto, não queremos que 2 horas sejam boas para ambos. Agora, na API de login, temos esse objeto de dados, que passamos no método de sinal de ponto JWT e simplesmente chamamos aqui, geramos a função de token e passamos esse mesmo objeto de dados como argumento Bom. Agora, o mesmo que fazemos na API de registro, recortamos o objeto de dados e aqui chamamos generate para confunction e passamos aqui esse objeto de dados Com essa implementação, nosso código parece mais organizado. 102. Como autenticar um usuário? Logou ou não?: Então, na lição anterior, vemos que depois de se inscrever e fazer login, geramos o token JWT e o enviamos na resposta Agora, deixe-me dizer o que o front-end fará com esse token. Portanto, quando enviamos o token JWT de back-end para front-end, o front-end armazena esse token no armazenamento local do navegador ou na sessão Com isso, o front-end saberá que o usuário está logado ou não. Quando o usuário deseja acessar dados seguros, que só são acessados pelo usuário de login, front-end precisa enviar esse token com a chamada da API. Portanto, há várias maneiras de enviar o token com a chamada da API. Mas, mais comumente, o front-end enviará o token na solicitação, especificamente no cabeçalho de autorização. Se seu front-end usar outro método, eles entrarão em contato com o back-end e o implementarão dessa forma Portanto, o front-end define o token no cabeçalho de autorização. E quando o usuário deseja acessar a API protegida, que só é acessada pelo usuário bloqueado , primeiro, no back-end, qual token é verificado ou não. Se for verificado, permitimos que o usuário acesse essa API e, se o token não for verificado, retornaremos um erro com o código de status 401, token de autorização necessário Agora, onde escrevemos essa lógica? E crie um middleware, especialmente para verificar o token, e podemos adicionar esse middleware para Deixe-me mostrar isso na prática. Então, em nosso projeto para definir um middleware, criamos uma nova pasta chamada middleware e, dentro dessa pasta, criamos um novo arquivo chamado Agora, você se lembra que é middleware? Middleware é uma função que chama a próxima função de middleware ou envia uma resposta à solicitação atual Então, aqui definimos uma função chamada middleware Orth e AV, conhecida por middleware expresso, obtemos três parâmetros, resposta de solicitação middleware Orth e AV, conhecida por middleware expresso, obtemos três parâmetros, resposta de solicitação e próxima função de erro. Agora, primeiro de tudo, aqui temos que obter o cabeçalho de autorização, o cabeçalho Seconoth é igual a solicitar cabeçalhos de pontos autorização de pontos Certifique-se de escrever a grafia correta das propriedades Caso contrário, não obteremos o cabeçalho aqui. Vamos registrar o ponto do console nesse cabeçalho de autenticação para ver o que estamos obtendo nessa variável No futuro, podemos remover esse console. Além disso, no mundo real, obtemos esse cabeçalho externo como este na string, primeiro obtemos espaço de erro e, em seguida, obtemos o token JWT completo O motivo pelo qual recebemos esse erro é porque ele é um padrão de autenticação comum e garante que o servidor processe o token corretamente. Agora, antes de verificarmos o token, precisamos verificar se recebemos token ou não nesse cabeçalho. Nós aderimos à condição if, se o cabeçalho O não estiver disponível, ou aderimos a mais uma condição, ambos os cabeçalhos começam com aqui na string, passamos o espaço do portador Se essa condição não for verdadeira, retornaremos o erro. Certifique-se de adicionar aqui não é verdade. Agora, dentro disso, retornamos ponto de resposta status 401 para solicitação não autorizada dot Jason, e aqui enviamos um objeto com propriedade de mensagem, autorização Certifique-se de enviar o objeto com a mesma propriedade para cada erro. Isso facilitará o tratamento de erros no front-end. Agora, o que está no outro cabeçalho. Como sabemos, o cabeçalho Oh é uma string com prefixo, portador, espaço e, em seguida, token Então, temos que obter o token dessa string. É muito simples. O token Const é igual aos dois cabeçalhos. Aqui, usamos o método split e de onde queremos dividir diretamente do espaço. Então, passamos códigos duplos e espaço. Agora, esse método de divisão retornará uma matriz como essa. O primeiro elemento é o portador e o segundo elemento é nosso símbolo. Podemos acessar o token pelo índice um. Entre colchetes, escrevemos um. Agora, precisamos apenas verificar se esse token é válido ou não. Então, para isso, precisamos do pacote JWT na parte superior, escrevemos que Cast JWT é igual a exigir o token web Json Na parte inferior, escrevemos JWT dot verify this method , exceto dois parâmetros primeiro é um token que queremos verificar, que é esse token. No segundo parâmetro, temos que adicionar a chave secreta do JWT, que é a chave de sublinhado do processo Env dot JWT Agora, se nosso token for verificado com sucesso, aqui obteremos os dados do usuário que enviamos com o token. Podemos armazená-lo em uma variável chamada usuário decodificado. Podemos salvar esses dados do usuário, pois o usuário do ponto de solicitação é igual ao usuário decodificado Se, em qualquer rota protegida, quisermos obter os dados atuais dos usuários conectados , podemos simplesmente acessá-los usando request dot user Não se preocupe, mostrarei isso também à medida que avançarmos neste projeto. Agora, depois de definir os dados do usuário na solicitação dot user, não queremos fazer nada nesse método. Assim, podemos simplesmente chamar a próxima função, que chamamos de próximo middleware na pilha de chamadas Se não chamarmos essa próxima função, express não chamará a função de API ou outra função de middleware Nosso servidor permanecerá neste momento, o que tornará nosso servidor muito lento. Sempre chame a próxima função no final da função de middleware Agora, aqui nesse código, e se nosso usuário não for verificado? E se o usuário passasse um token falso ou um token expirado? Também precisamos lidar com isso. Para lidar com o erro, adicionamos aqui o blog try and catch e simplesmente adicionamos essas três linhas no blog Try. Se obtivermos um erro nessas três linhas, esse blog de captura será executado. Neste blog de captura, podemos simplesmente retornar a resposta com status 400 para o ponto de solicitação inválido Json e o que passamos Certo, passamos aqui o objeto com a mensagem de propriedade e mensagem de erro será um token inválido e pronto Concluímos o middleware de autenticação. Vamos também provar isso. Primeiro de tudo, temos que exportar esse orddalware para usar esse middleware Então, module dot Exports. Igual ao middleware Auth. Salve as alterações e vá até a rota dos usuários. Aqui na parte inferior, após a rota de login, adicionamos o método Router dot Get e apontamos apenas para a barra frontal Depois disso, adicionamos função de retorno de chamada com solicitação e resposta Essa é a API normal. Mas como podemos tornar essa API protegida, o que significa que somente usuários bloqueados devem acessar essa rota de API. Para isso, precisamos adicionar middleware antes dessa função de retorno de chamada Na parte superior, importamos o middleware const. Você também pode chamá-lo de OT é igual a exigir que façamos uma OT de middleware mais completa Para executar esse middleware antes dessa função de retorno de chamada da API, precisamos adicioná-lo aqui antes Quando os usuários enviam uma solicitação Get para esse endpoint, primeiro, essa função de middleware do Forth será executada Nesse middleware, qual token de ação é válido ou não. Se for válido, somente então chamaremos a próxima função, que executará essa função de retorno de chamada da API Se, em nosso aplicativo, quisermos criar qualquer API protegida, precisamos adicionar apenas Omddalware antes dessa função de retorno de chamada da API Simples assim. Você pode me dizer como podemos obter os dados dos usuários conectados Certo, obtemos os dados dos usuários logados do usuário request dot Portanto, o custo do usuário é igual ao usuário do ponto de solicitação. E aqui simplesmente enviamos esse usuário no método response dot json Agora vamos testar essa implementação. Salve as alterações e, primeiro, precisamos gerar o token. Abra o cliente Thunder e acesse a API de login. Aqui temos os dados, para que possamos simplesmente enviar essa solicitação de login. Bom. Aqui obtemos o token. Certifique-se de gerar o token de letras porque definimos 2 horas de tempo de expiração. Copie esse token e aqui criaremos uma nova solicitação. Dê um nome a ele, usuário logado. Em primeiro lugar, escrevemos o endpoint da API, que é HTP, Callan double forward slash host local, 3.000 usuários de API slash 3.000 Agora envie essa solicitação. Veja, aqui temos o erro. token de autorização é necessário porque não passamos o token no cabeçalho de autorização. Então, para passar o cabeçalho de autorização, vamos para cabeçalhos. Aqui, adicionamos um novo cabeçalho, chave para autorização. Veja, também obtemos autorização, e aqui o que vamos passar. Sim, temos que passar o token, mas com prefixo, espaço de erro, e aqui passamos um token Certifique-se de não passá-lo com códigos duplos. Agora vamos enviar a solicitação. Veja, aqui obtemos os dados de login dos usuários com o nome de ID, que é emitido, esse é o momento em que esse token é gerado e EXP é o tempo de expiração, gerado e EXP é o tempo de expiração, ou seja, quando esse token expirará Além disso, se verificarmos nosso terminal, um console será o cabeçalho de autenticação Veja, primeiro obtemos o prefixo do portador e depois obtemos É assim que adicionaremos o middleware de autenticação para proteger nossa API Então, aqui estamos recebendo apenas nome de usuário e ID. Vamos enviar todas as informações sobre o usuário conectado. Então, na rota do usuário, aqui adicionamos a consulta Fine, sconctUser é igual a await user dot E aqui passamos nosso ID de usuário, que é request dot user dot dot underscore ID Selecione o ponto e aqui não queremos enviar a senha. Eu escrevo uma string menos a senha, e então retornamos o ponto de resposta para este usuário Remova essa primeira linha de usuário, não precisamos dela. Além disso, temos que tornar essa função uma. Salve as alterações e faça uma. Veja, agora temos os dados completos dos usuários logados Agora podemos usar essa rota para obter as informações completas do usuário de login atual. É assim que o usuário autenticado está logado ou não usando essa função de middleware do sistema operacional 103. OAuth em detalhes: Então, nos vídeos anteriores, vimos como inscrevemos e logamos usuários usando e-mail e senha, o que é muito importante. Mas hoje em dia, você pode ter visto muitos sites fornecerem alguns recursos adicionais, como fazer login com o Google, fazer login com Facebook, Twitter, fazer login com o Github e a lista continua dependendo do tipo de site Muitos usuários gostam de usar esses métodos para assinar. Se eles usarem esses métodos, não precisarão criar uma nova senha para outro site e se lembrar dela. Eles simplesmente usam seu ID do Google algum ID social e fazem login em nosso site. Além disso, é muito seguro. Portanto, é muito útil adicionarmos esses recursos em nosso aplicativo também. Mas antes de adicioná-los, você pode perguntar como esses recursos funcionam nos bastidores. Então, aqui está a arquitetura completa do processo de assinatura. Não tenha medo. Ouça apenas como uma história, porque em nossa vida diária, já usamos esses recursos. Suponha que aqui esteja um Hali, ele usou um site chamado Amazon ou Ebay Nesse site, ele tem a opção de se inscrever ou se inscrever no Google. Se você clicar nesse botão, esse botão o redirecionará para a página de login do Google Aqui, ele digita seu e-mail e senha do Google e faz login. Se ele digitar o e-mail e a senha, algo acontece na página da web e, no final, ele faz login no site da Amazon ou do eBay com seu nome de usuário e-mail sem criar a nova senha Isso é realmente incrível. Agora, a parte principal está acontecendo entre eles. Deixe-me contar o que aconteceu lá. Quando Harley entra, escreve e-mail e senha na conta do Google e clica em Login, o servidor do Google gera um código temporário e envia esse código temporário para nosso backend Agora, no backend, usando esse código, podemos buscar alguns detalhes de uso que queremos acessar e armazená-los em nosso banco de dados, como nome do usuário, ID de e-mail etc Portanto, nosso back-end entrará em contato novamente com o servidor do Google e informará que queremos acessar os dados de uso em vez desse código temporário Portanto, o servidor do Google verifica o código e extrai os dados do usuário desse código. E então o servidor do Google envia esses dados de uso para o back-end Em nosso back-end, temos esses dados de uso e podemos usar esses dados da maneira que quisermos. exemplo, podemos armazenar o nome do usuário e o e-mail do usuário em nosso banco de dados e gerar um novo usuário, ou se o e-mail do usuário já estiver disponível, não fazemos nada e simplesmente redirecionamos o usuário para o front-end com o token Agora, quando eu aprendo pela primeira vez sobre essa arquitetura, que é o Oath ou podemos chamar de autorização aberta Na hora, eu tenho uma pergunta e tenho certeza que você tem a mesma pergunta. Por que o servidor do Google envia primeiro esse código temporário ou de autorização para nosso back-end Por que ele não pode enviar diretamente as informações do usuário? Há alguns motivos pelos quais o servidor do Google envia esse código de autorização. Suponha que o Google envie diretamente informações do usuário, como dados de e-mail ou perfil, para o front-end , para que elas possam ser interrompidas ou excluídas por hackers e também corrigidas ou mal utilizadas antes de chegar ao Além disso, o código temporário funciona como uma permissão para dormir. Ele informa ao Google que esse usuário fez login e deu permissão ao nosso aplicativo Somente nosso back-end com uma chave secreta pode estender esse código para os dados reais do usuário. Essa chave secreta nos é fornecida pelo Google e só estará disponível em nosso back-end InvFle , da mesma forma que nossa chave secreta JWT Por motivos de segurança, o Google envia primeiro, somente um código temporário ou de autorização. Aqui está um resumo de como o OAuth funciona. O usuário primeiro clica, faz login ou se inscreve com o botão do Google e depois volta para a página de login do Google, ou podemos dizer servidor do Google Agora, depois disso, no servidor do Google, verifique se o e-mail e a senha estão corretos ou não. Se estiver certo, o Google gera o código de autorização e o envia para o back-end back-end envia novamente o código de autorização com a chave secreta para o servidor do Google, e o servidor do Google extrai os dados do usuário, como nome , e-mail, perfil, etc Agora, finalmente no back-end, podemos armazenar esses dados em nosso banco de dados ou, se o usuário já estiver disponível, podemos simplesmente redirecioná-lo para a página inicial do front-end com o JWT Simples assim. Portanto, essa arquitetura funcionará para todos os tipos de redes sociais, como login com Facebook, login com Github, Twitter, etc Não só para o Google. Eu uso aqui o Google como exemplo. Se precisarmos do Facebook, esse servidor do Google alterado pelo Facebook autoriza e pelo servidor ou pelo Github autoriza Agora, na próxima lição, implementaremos praticamente esse Oath em nosso aplicativo Catwis 104. Aplicativo OAuth no Node — Faça login com o Google: Vamos implementar o recurso de login com o Google neste aplicativo. E para isso, precisamos de um pacote chamado passpod dot js. Portanto, na arquitetura de OT, quando o usuário clica em fazer login com o Google Pattern, redirecionaremos o usuário para a coluna 3.000 APIs de barra do host local OT slash page Essa é nossa API de back-end. Como podemos definir? Queremos mostrar a página de login do Google ou vincular o servidor do Google a esta página. Além disso, se no back-end recebermos o código de autorização, como podemos enviar solicitações ao servidor do Google e recuperar os dados do usuário Sim, podemos fazer tudo isso manualmente, mas a biblioteca Js do passaporte torna tudo muito mais fácil. Nós vamos usá-lo. Não se confunda. Basta ver esta lição completa e você verá como essa implementação do Oath está funcionando Então, vamos para a página passports.org. Aqui podemos ver que o passaporte é um middleware de autenticação para No Jz, extremamente flexível Na parte inferior, temos todas as estratégias, como Facebook, Twitter, Google, Github, etc Não se preocupe, basta ir até a barra de pesquisa e pesquisar aqui, Google, e selecionar este passaporte Google Oth two. Certifique-se de não selecionar esse juramento 20. Usamos Oth two. Esses dois são muito parecidos, mas esse Oath 20 é uma estratégia mais antiga Não está muito bem conservado. Portanto, usaremos esse OR dois, que tem novos recursos e é mantido ativamente pelo passaporte. Deixe-me ampliar um pouco. Sim. Então, primeiro de tudo, precisamos instalar esse pacote. Então copie esse comando de volta para o código Vas, abra o terminal e, nesse terminal, simplesmente passamos o comando aqui. E para a mesma versão, você pode escrever na taxa 0,2 0,0. Além disso, precisamos do pacote de passaporte na taxa de 0,7 0,0 e pressione Enter. Bom. Agora, de volta à documentação. Aqui, eles nos fornecem o código completo para implementar o passaporte com a estratégia do Google. Copie todo esse código e, em nosso backend, podemos colar esse código em nosso arquivo Gs de pontos de índice Mas Deta bagunçou nosso arquivo index dot js, então podemos armazenar esse código em um arquivo separado Para isso, criamos uma nova pasta chamada Config e, dentro dela, criamos um novo arquivo, o ponto de passaporte JS e a página desse código dentro dela Por enquanto, não se preocupe com esse código. Vou explicar esse código e também faremos algumas alterações posteriormente. Agora, de volta à documentação, role para baixo e aqui podemos ver que eles nos fornecem APIs para adicionar em nosso aplicativo primeira API é Auth Google e, no local da função de retorno de chamada, ela passa o método de autenticação de pontos do passaporte e, na primeira posição, eles passam pelo Google, que é o servidor de autenticação, e depois disso, passam o escopo dos dados Basicamente, eles estão dizendo quais dados do usuário queremos obter do servidor. Queremos e-mail e perfil, que incluam muitos detalhes sobre o usuário. Agora você pode perguntar o que essa API fará. Quando o usuário envia uma solicitação get do navegador nesse endpoint do Google Oth slash, esse método de autenticação de pontos de passaporte abrirá a página de login do Google Para adicionar essa rota em nosso aplicativo, podemos fazer algo assim. Na pasta route, criamos um novo arquivo auth dot js. Criação de rotas separadas para autenticação. Nisso, em primeiro lugar, precisamos que o Cost Express seja igual a require Express. Para adicionar uma rota, adicionamos custo. O roteador é igual ao roteador de pontos expressos. Agora, a partir da documentação, copiamos essa primeira rota e a colamos na outra rota. Também na parte superior, temos que inserir o passaporte porque aqui você está usando o passaporte. O passaporte Const é igual a exigir passaporte. Agora, no lugar deste aplicativo dot GAD, o que usamos? Certo, usamos o roteador dot GAD. Além disso, não adicionamos esse OT. Mencionaremos slash OT como prefixo, mesma forma que definimos o prefixo para Agora, na parte inferior, temos que exportar essa rota. Portanto, as exportações de pontos do módulo são iguais ao roteador. Salve isso e antes de esquecermos de adicionar essa rota no arquivo js de pontos de índice, vamos adicioná-la. Após a rota desse usuário, adicionamos app.us. Aqui, adicionamos o prefixo API OT. No segundo parâmetro, temos que passar rotas de autenticação Portanto, inserimos o custo das rotas. Os é igual ao necessário. Aqui vamos na pasta de rotas OT. Agora, simplesmente passamos essas outras rotas neste aplicativo devido ao método. Agora, de volta ao arquivo auth dot js. Aqui especificamos o usuário Xs API Auth slash Google, ele deve abrir a página de login do Google Agora, depois que os usuários fizerem login com sucesso, o que queremos fazer, precisamos especificar isso também. Lembre-se de que, anteriormente, tínhamos código de estratégia no arquivo JS de pontos do passaporte Entenda esse código e também faremos algumas alterações nesse código. Em primeiro lugar, no topo, precisamos do passaporte da biblioteca de passaportes porque o estamos usando aqui. SeconctPassport é igual a exigir um passaporte e também alterar esse r para o custo. Depois disso, temos o passport dot ug e, dentro disso, temos uma nova estratégia do Google, que passamos do passaporte, do autor do Google ao pacote Com essa estratégia, não precisamos escrever código manual para buscar o código de autorização e extrair dados do servidor do Google Essa estratégia faz tudo isso por nós. Depois disso, temos um objeto com várias propriedades, como ID do cliente e segredo do cliente. Você receberá esse ID ao registrar seu aplicativo no Google Console e, com isso, também obteremos o código secreto do cliente. Sem esses dois preenchimentos, o Google não nos fornecerá dados dos usuários Então, vamos gerar isso também. Mais uma vez, estou lhe dizendo, não se preocupe com esse código. Quando concluirmos essa implementação, mostrarei o fluxo de trabalho completo desse código. No navegador, pesquise, Google Cloud Console. Abra esse segundo link. Aqui, temos que fazer login com nossa conta do Google. Você pode usar qualquer conta. Agora, após o login , fica assim. Não se preocupe, basta acessar aqui Selecionar projeto e criar um novo projeto. Dê um nome a ele. Digamos Card Wish e clique em Criar. Aqui na notificação, ele está criando e selecionando este projeto. Quando selecionamos esse projeto, podemos ver esse projeto aqui. Agora precisamos de API e serviços. Clique nessas três linhas e, na API e nos serviços, vamos para a tela de conteúdo O OT. Basta fazer o que eu faço e você está pronto para começar. Clique neste botão Começar. Aqui, temos que fazer algumas configurações. Primeiro de tudo, aqui temos que escrever o nome do aplicativo. Novamente, escrevemos Cartwish. Depois disso, selecione seu e-mail de suporte e clique em Salvar. Agora, aqui temos que selecionar o tipo de público, selecione aqui externo. Com isso, qualquer usuário pode fazer login em nosso aplicativo e clicar em Avançar. Aqui, escrevemos nosso e-mail no qual queremos receber uma notificação relacionada a este aplicativo e, finalmente, clicamos em “Avançar”, termos precisos e continuar e criar o aplicativo. Agora vamos para o acesso aos dados na barra lateral esquerda. Aqui, temos que selecionar o escopo dos dados do usuário. escopos expressam a permissão que você solicita que os usuários autorizem para seu aplicativo e permitem que seu projeto acesse tipos específicos de dados de usuários privados da Conta do Google Basta clicar em adicionar ou remover escopos. Selecione o primeiro a enviar e-mail e perfil, clique em Atualizar e salve. Agora vá para esse público, e aqui podemos adicionar usuários gustativos. Às vezes, se depois de toda a implementação, nossos usuários não conseguirem fazer login, talvez precisemos adicioná-los aos usuários do Taste. Quando fiz isso, não encontrei nenhum erro. Então não se preocupe com isso. Basta ir até os clientes. Aqui, precisamos gerar credenciais de OO e, para isso, clicamos em Criar cliente Selecione o tipo de aplicativo para aplicativo web. Nome, não precisamos mudar. Mas, na parte inferior, precisamos adicionar URIs de redirecionamento autorizados Um URI de redirecionamento é o endpoint em nosso aplicativo de back-end para o qual o Google redireciona o usuário após o login bem-sucedido Aqui, escrevemos STP, Column double forward slash local host, Column 3.000 API OT, Google, Lembre-se desse endpoint. Precisamos definir essa API em nosso back-end. E clique em Criar e pronto. Veja, aqui temos o ID do cliente e também o segredo do cliente. Copie esse ID de cliente e, em nosso aplicativo, no local desse ID de cliente do Google, podemos paginar esse ID ou, para torná-lo seguro, podemos colocá-lo em um arquivo DOT ENV Eu acho que é mais seguro. O que você acha? Então, no arquivo ENV de pontos na nova variável, Google, sublinhado, ID de sublinhado do cliente É igual a garantir que você não adicione espaço e cole aqui o ID do cliente do seu aplicativo do Google Depois disso, copie esse segredo do cliente, volte para o VSCode e simplesmente insira o Google, underscore, client, underscore É igual a basear aqui em segredo. Salve este arquivo e volte para o arquivo passport dot js. Aqui, passamos o processo ponto a ponto pelo Google, sublinhado o ID do sublinhado do cliente E aqui passamos o processo ponto a ponto do Google, sublinhado cliente, sublinhado segredo Agora, depois disso, temos a propriedade de URL de retorno de chamada. Certifique-se de que aqui escrevemos o mesmo endpoint que passamos em nosso aplicativo Google Console Podemos ver isso aqui, clique neste botão de edição e aqui temos o URL de retorno de chamada Copie isso e cole em códigos duplos. No final, não toque nessa solicitação de passe para a propriedade de retorno Certifique-se de que esteja definido como verdadeiro. Ele passará o objeto de solicitação para esse URL de retorno de chamada. Agora, depois disso, no segundo parâmetro, temos a função de retorno de chamada, ou podemos dizer função de retorno de chamada de estratégia Essa função será executada quando os usuários fizerem login com sucesso com seus detalhes, e obtemos aqui o objeto de solicitação, token de acesso, que é um token emitido pelo Google para nosso aplicativo. Ele permite que nosso aplicativo faça solicitações autorizadas às APIs do Google em nome do usuário Depois disso, temos o token de atualização, que é um token que pode ser usado para obter um novo token de acesso quando o atual expirar Não se preocupe, não precisamos disso por enquanto. Depois disso, temos o perfil, que é um objeto com informações sobre o usuário autenticado, como nome, e-mail, ID do Google, etc Obtenha esses dados do Google, e isso realmente depende dos escopos que solicitamos E, no final, concluímos, que é a função que você chama ao concluir o processo dos dados do usuário. Agora, dentro dessa função, não queremos encontrar um usuário ou criar um novo usuário. Faremos tudo isso nessa API de retorno de chamada. Então, aqui removemos esse código e simplesmente retemos aqui esse método concluído No primeiro argumento, passamos um erro que é nulo. No segundo argumento, temos que passar os dados dos usuários. Nesse caso, podemos passar diretamente o perfil. Para resumir, quando os usuários se conectarem com sucesso ao Google, o retorno de chamada estratégico será executado e, nesse perfil, obtemos os dados dos usuários do Agora, quando chamarmos esse método done com um nulo e dados do usuário para criar um perfil, passaporte executará esse endpoint da API e definiremos esse endpoint na próxima lição 105. OAuth com JWT: Agora vamos definir essa última etapa da autenticação do Google, que é adicionar essa API de retorno de chamada Onde adicionarmos essa API, vamos defini-la nas rotas ShorthTJSFle Aqui já adicionamos uma API, que é a primeira etapa. Agora adicionamos aqui outro método Get dot do roteador, endpoint slash Google slash callback Você precisa fornecer o mesmo que passou na propriedade de retorno de chamada Então, como sabemos, o Google enviará dados de uso nessa rota de retorno de chamada e, para isso, teremos que aderir novamente ao Passport Middleware O passaporte não é autenticado. Aqui, passamos o Google no segundo argumento, definimos o objeto com propriedade, que é SSN, como falso Isso fará com que a biblioteca do Passport não armazene o ID do usuário na sessão. E também passamos mais uma propriedade, falha, redirecionamento e, quando os dados do usuário falharem, aqui , o servidor do Google redirecionará nosso Então, aqui temos que passar nosso URL de front-end. Aqui, por exemplo, passamos o aplicativo Local React. Você pode escrever a coluna SDTP, barra dupla, host local C5173 slash Login. Isso é muito importante. Agora, depois disso, podemos adicionar nossa função de retorno de chamada, que executaremos depois de enviarmos dados de perfil do retorno de chamada da estratégia de senha a partir retorno de chamada da estratégia de senha a partir Agora, como podemos obter dados nesse retorno de chamada? Então, obtemos dados no usuário do ponto de solicitação, e vamos armazenar essa invariável chamada perfil e simplesmente retornar esse objeto de perfil no ponto de resposta Json e passar o Agora vamos testar se isso está funcionando ou não. Para testar essa implementação, precisamos enviar a solicitação Get para o endpoint Abra o navegador e vá até a barra dupla da coluna SGTP Hospedeiro local, coluna 3.000. Se seu aplicativo estiver sendo executado em outro pod, você precisará escrever o URL do Bean aqui e, em seguida, cortar a API OT cortar E aqui temos um erro. Está dizendo estratégia de erro e não autenticação, Google. Deixe-me verificar. A estratégia do Google está correta. Além disso, passamos o nome correto das variáveis ENV. Deixe-me verificar isso. Sim, eles são iguais. Oh, espere. Não adicionamos esse arquivo passport dot js em nosso arquivo index dot s e, por causa disso, esse arquivo não foi configurado em nosso aplicativo Acho que esse é o motivo pelo qual estamos recebendo esse erro. Então, vá para o arquivo index dot Gs e, na parte superior, adicionamos require, vamos para a pasta Config e o passaporte Veja as mudanças e vamos reiniciar nosso aplicativo. Meu ponto de índice é. Agora, de volta ao Navegador e eu deixo a página de lado, veja, redirecionamos diretamente para a página de login do Google Aqui podemos ver o nome do nosso aplicativo, que mencionamos em nosso console do Google. Bom. Agora, você precisa escrever os detalhes da sua conta do Google e simplesmente fazer login com isso. Aqui, ele solicita sua permissão para permitir que o Google envie seus dados de e-mail e perfil para esse aplicativo. Continue e aqui você pode ver que obtemos o objeto de dados do perfil do usuário. No topo, temos o provedor, que é o ID do Google, que é o ID exclusivo do Google. Nome de exibição em seu nome, sublinhado do e-mail verificado como verdadeiro para que obtenhamos o ID EML e muitos outros detalhes Você pode usar qualquer um desses detalhes e armazená-los em seu banco de dados. Por isso, concluímos nosso trabalho principal para a autenticação do Google. Agora só precisamos verificar se o usuário com esse ID EML já está disponível em nosso aplicativo ou não Não está disponível, então criamos um novo usuário com seu nome de e-mail, ID do Google, mas deixamos a senha preenchida porque, para fazer login no Google ou no Facebook, não precisamos preencher a senha e, em seguida, geramos o token JWT para os dados desse usuário Se o usuário já estiver disponível em nosso banco de dados , não se preocupe, simplesmente atualizamos seu ID do Google em nosso banco de dados e geramos o token JWT para os dados desse usuário Então, para implementar isso, precisamos mudar um pouco o esquema de nossos usuários Como fazer essas alterações porque em nosso aplicativo, temos usuários que podem fazer login com e-mail e senha, e também alguns usuários podem fazer login com o Google. Vamos primeiro modificar o esquema do usuário. Aqui criamos uma senha, obrigatória para verdadeira. Mas, como sabemos, quando o usuário faz login no Google, não armazenamos a senha, então precisamos alterar o obrigatório para falso. Além disso, quando criamos um novo usuário usando o Login do Google , também não armazenamos o endereço de entrega. Portanto, também podemos tornar obrigatório falso para o endereço e também remover essa propriedade de comprimento médio. Depois disso, podemos adicionar mais um campo para o usuário que usou o Google para fazer login. Adicionamos o tipo de ID do Google à string e é exclusivo para True. Você pode se perguntar por que precisamos desse ID do Google em nosso banco de dados? Precisamos desse ID do Google porque, usando isso, podemos identificar que o usuário já está disponível em nosso banco de dados ou não. Mas aqui, já temos e-mails de usuários. Por que não podemos usar esse e-mail? Veja, no navegador, estamos recebendo esses detalhes do perfil. Aqui temos a propriedade de e-mails, que é a matriz de e-mails. Uma conta do Google tem um ou mais e-mails, como hurled gmail.com, que é o e-mail principal, hurleredcorporate.com para e-mail de trabalho, hurleredcorporate.com Se a Harley alterar seu e-mail principal, então, para a mesma conta do Google, poderemos criar uma nova conta de usuário Para remover esse risco de e-mail, armazenamos o ID do Google. Outro motivo pelo qual precisamos usar o ID do Google é porque alguém pode alterar o endereço de e-mail da conta do Google, mas não pode alterar o ID do Google. O ID do Google é exclusivo para todos os usuários do Google, e é por isso que armazenamos o ID do Google dos usuários. Além disso, o ID do Google serve apenas para identificar os usuários que fazem login usando o Google, não para usuários que criaram uma conta usando e-mail e senha simples. Para aqueles, usamos e-mail para identificação. Salve esse arquivo e vamos escrever rapidamente nossa lógica nessa rota de retorno de chamada do Google Eu escrevo um comentário sobre essa lógica. Primeiro, verificamos que o usuário está disponível ou não usando seu ID do Google ou por e-mail. Se o usuário estiver disponível, atualizamos seu campo de ID do Google e, em seguida, simplesmente geramos o token JWT e o enviamos na resposta Aqui, não precisamos verificar a senha porque o usuário está conectado ao Google Se o usuário não estiver disponível, criaremos um novo usuário com nome, e-mail, ID do Google, geraremos o token JWT e o enviaremos em resposta No final, temos que enviar o token JWT para o front-end, simples assim Em primeiro lugar, qual usuário está disponível ou não. Para isso, precisamos da coleção de usuários. Então, no topo, o custo do usuário é igual ao necessário, colocamos uma pasta acima dos modelos de Agora, na parte inferior, escrevemos fine query, user dot Fine one. E aqui passamos Objeto e adicionamos condição, ID do Google. Para criar um perfil com o ID do ponto. Além disso, e se alguém primeiro fizer login com e-mail e senha e depois tentar fazer login com o Google. Na época, não encontramos ID do Google desse usuário em nosso banco de dados. Portanto, também precisamos encontrar o usuário com base no e-mail. Você pode usar aqui nosso operador. Adicionamos dólar ou coluna, e temos que adicionar aqui uma matriz de várias condições. Então, adicionamos um objeto de condição, o ID do Google ao ID de ponto do perfil, e o segundo objeto de condição, e-mail, ao e-mail de ponto do perfil. Agora, aqui está uma coisa. Esse campo de e-mail com pontos do perfil não estará 100% disponível. Para algumas contas do Google, funciona e, para poucas contas, não funcionará. Portanto, como uma boa prática, desenvolvedor não usa esse campo de e-mail com pontos de perfil. Eles usam e-mails com pontos de perfil, que é a matriz, e acessamos seu primeiro elemento por colchete, índice zero, e para valor, adotamos o valor do ponto Como sabemos, essa consulta retorna uma promessa, para que possamos aderir await, em armazenar o objeto do usuário na variável, let user Além disso, para usar await, temos que fazer esse retorno de chamada agir Agora, aqui temos dois cenários. Se o usuário estiver disponível e o usuário não estiver disponível. Agora, o que queremos fazer se o usuário estiver disponível, verificaremos se o ID do Google está armazenado ou não. Se o ID do Google do usuário não estiver disponível, definiremos o ID do Google por ponto do usuário. É igual ao ID do ponto do perfil. Esse ID de ponto do perfil é o ID do Google. E depois disso, para economizar ajuda, escrevemos await user dot save Agora, no resto, temos que escrever uma lógica para que o usuário não exista. Basicamente, criaremos um novo usuário. Então, escrevemos que usuário é igual a novo usuário. Aqui passamos um objeto com propriedades. O primeiro é nome para perfil, nome de exibição de pontos. Em seguida, envie um e-mail para o perfil. Aqui, acessamos o valor do ponto do primeiro elemento. O mesmo que fizemos antes. Última propriedade, precisamos do ID do Google para criar o perfil do Dot ID. Para salvar esse novo usuário, escrevemos aqui await user dot save Você precisa fazer apenas uma coisa. Gere o token JWT e envie-o. Portanto, o token de custo é igual a, seguimos a rota do usuário Copiamos esse método de sinal JWT para gerar o token e o colamos aqui Aqui, no ritmo dessa variável de dados, temos que passar os dados que queremos enviar dentro do token. E o que passamos no login, sim, passamos apenas ID e nome. Então, aqui também passamos o ID de sublinhado, não o ID do Google. O ID do Google é apenas um back-end para verificar essa condição. Basta copiar esse objeto de dados e passar aqui. Se você quiser enviar um e-mail também , você também pode mencionar isso Mas é importante, em todos os aspectos, que você envie os mesmos detalhes. Será fácil para o front-end usar esses dados. Certifique-se também de que aqui temos que importar o JWT. O custo do JWT é igual ao token web JSON necessário. Agora, no local de envio desses detalhes do perfil em resposta, enviamos o token JWT, mas enviamos o token na simples inscrição e login com e-mail e senha Além disso, às vezes, os desenvolvedores de front-end pedem que você redirecione o usuário para a página inicial direta do front-end Naquela época, podemos fazer algo assim. Ponto de resposta ReDic e aqui usamos a string de modelo. Aqui, temos que mencionar o URL da nossa página de front-end qual queremos redirecionar usuário após o login bem-sucedido no Google F localmente, podemos escrever SDDP, coluna dupla para host local de barra, coluna 5173, coluna 5173, Aqui você precisa escrever seu URL de front-end , painel de barra Aqui, passamos o token no parâmetro de consulta usando o ponto de interrogação, token é igual aos colchetes de Cali do dólar, Você também pode alterar esse URL conforme desejar. Isso realmente depende do seu front-end. Muitos desenvolvedores redirecionam usuários, e alguns desenvolvedores enviam apenas tokens Eu mostro para vocês dois caminhos: você pode escolher o que seu desenvolvedor de front-end disser. Por fim, implementamos o recurso de login com o Google em nosso aplicativo. Vamos recapitular o que fizemos nas duas últimas lições. Em primeiro lugar, o usuário clica no botão de login com o Google. Nosso front-end redirecionará o usuário para o host local Column 3.000 slash API Ath slash Google Esse é o nosso URL do Bend. Se seu back-end estiver sendo executado no host local 8.000, usuário deverá redirecionar para o host local 8.000 API Agora, quando o usuário redirecionar para a API Auth do Google, esse código será executado Aqui, mencionamos o passaporte , a autenticação com o Google e mencionamos o escopo Agora, depois disso, esse código será executado diretamente , disponível no arquivo JS do passaporte. Aqui, o passaporte envia nosso ID do cliente, segredo do cliente e o URL de retorno qual queremos enviar os dados do perfil Depois que os usuários fizerem login com sucesso conta do Google e permitirem a permissão , essa função será executada e aqui retornaremos o método com o erro nulo e os dados do perfil Esses dados de perfil, podemos acessar como usuário de ponto de solicitação em nossa função de retorno Além disso, certifique-se de que aqui não podemos passar a solicitação de retorno de chamada para True Depois disso, nossa API de retorno de chamada será executada, e aqui escrevemos nossa lógica de usuário e, em seguida, enviamos ou redirecionamos o usuário com Simples assim. Tenho certeza de que todas as suas dúvidas estão claras. Não se preocupe, esta é sua primeira vez e, por isso, você está um pouco confuso. Mas com o tempo, você entenderá isso sem nenhuma confusão. As duas últimas aulas são um pouco longas, mas basta ver o que você implementou em seu aplicativo. Parabéns por isso, você pode fazer uma pequena pausa na tela e continuar esta seção. 106. Faça login com o Facebook usando o OAuth: Então, anteriormente, adicionamos o login com o Google. Agora também podemos adicionar login com o Presbook ou qualquer outra plataforma, como Github ou Twitter Existem algumas etapas comuns que devemos seguir. Etapa número um, instale o passaporte e a biblioteca de estratégias de passaportes no aplicativo Node. Etapa 2: adicione o primeiro endpoint da API, que acionará o passaporte com essa estratégia Etapa número três, adicione código de estratégia do passaporte no arquivo passport dot js. Da mesma forma que adicionamos a estratégia do Google. Etapa número quatro, gere ID e segredo para essa plataforma. Por fim, etapa número cinco, defina a API de retorno de chamada, armazene os dados dos usuários, se necessário, e envie o token JWT Com essas cinco etapas, podemos adicionar qualquer plataforma em OT. Deixe-me mostrar rapidamente como podemos implementar o login com o Facebook. Etapa número um, temos que instalar a estratégia de passaporte. Vamos até a documentação do passaporte e pesquisamos aqui no Facebook. Veja, aqui temos o comando de instalação, copie isso e simplesmente cole em nosso terminal. Além disso, se você quiser usar a mesma versão que eu estou usando , você pode adicionar aqui na taxa 3.0 0.0 e pressionar Enter. Agora, passo número dois, temos que adicionar API e ponto, que abrirá a página de login do Facebook. Então, na documentação do passaporte, role para baixo. E aqui temos o código da API. Veja, é muito parecido com a API do Google. Lembre-se e simplesmente copie essa primeira API. E em nosso arquivo js th dot, após essa API de retorno de chamada, simplesmente o colamos aqui Pendure este ponto de API para cortar o Facebook e também para autenticar o passaporte com o Facebook. Para fins de escopo, temos que escrever aqui o perfil de sublinhado público e perfil de sublinhado público Etapa número três, temos que adicionar o código de estratégia de passaporte para o Facebook. Então, acesse o site do passaporte novamente e copie esse código de estratégia. Volte ao arquivo viscodeopen passport dot js e, simplesmente na parte inferior, colamos esse código Agora temos que fazer algumas correções. Primeiro de tudo, tem que importar a estratégia do Facebook do pacote. Portanto, duplique essa linha de estratégia do Google e simplesmente altere o nome dessa variável para estratégia do Facebook mesmo que eles usam aqui, e também alteramos o nome do pacote para passaporte do Facebook. Bom. Agora, aqui, temos que adicionar esses preenchimentos do ID do Facebook e do segredo do Facebook , que é a etapa número quatro Para gerar o ID e o segredo do aplicativo, precisamos acessar a página de desenvolvedores do Facebook. Mencione todos os detalhes na documentação de senhas de cada plataforma. Não se preocupe com isso. Na nova aba, pesquise aqui, Facebook, desenvolvedor, console e abra esse primeiro link. Aqui, clique em Login. Estou logado com minha conta. Bom. Após o login, chegamos aqui à opção de começar. Pode ser que você solicite o registro e a verificação. Conclua as etapas básicas e, em seguida, você será redirecionado para esta página de aplicativos Clique em Criar aplicativo. Aqui, escrevemos o nome do nosso aplicativo, que é Cardwis. Esses são os mesmos detalhes que preenchemos no Google Console. Agora, adicione casos de uso, para que queiramos autenticar e solicitar dados de usuários com login no Facebook Curta isso e clique em Avançar. Aqui, selecione Não quero conectar o portfólio de negócios. Talvez você não tenha essa opção porque, recentemente, Facebook se tornou rigoroso quanto a isso. Desculpe se você não tem a opção aqui, mas não se preocupe, escreva um código enquanto eu escrevo. No futuro, você só precisará adicionar apenas o ID do aplicativo do Facebook e o segredo do aplicativo. Aqui, clique em Avançar e Avançar e pronto, vá para o Deskboard, agora aqui, temos que concluir essas etapas Então, clique em personalizar adicionando um botão de login do Facebook. Aqui, tivemos permissão. Adicione e-mail e o perfil público já está adicionado. Agora clique nesse início rápido. Aqui, selecionamos a web aqui, nosso URL de front-end. Por enquanto, basta escrever aqui, STTP, Coluna com barra dupla, Host local, Coluna No mundo real, você precisa escrever seu URL de front-end aqui e clicar em Salvar e continuar. Clique em Avançar, clique em Avançar, clique em Avançar e pronto. Agora, basta acessar a configuração do aplicativo na parte inferior e ir para a configuração básica. Aqui temos APId e App Secret. Copie esse APD e, em nosso arquivo DOT ENV, adicionamos outra variável chamada Facebook, aplicativo de sublinhado, ID de sublinhado Passe o ID do aplicativo. Depois disso, adicionamos outra variável chamada aplicativo de sublinhado do Facebook, segredo do sublinhado é igual a voltar ao navegador, e aqui clicamos em mostrar que pode perguntar sua senha do Facebook, escrevê-la e ver aqui que podemos ver o código secreto Copie isso e simplesmente cole no arquivo ENV. Salve o arquivo e volte para o arquivo JS de ponto do passaporte. Aqui, nós em process.nw dotamos aplicativo de sublinhado do Facebook, ID de sublinhado E aqui também processamos dot nwt Facebook underscore app underscore secret Agora, depois disso, simplesmente copiamos essas duas propriedades do código anterior, callb URL e também passamos a solicitação para callback e as paginamos aqui para Aqui mesmo, temos que alterar a URL de retorno de chamada para cortar o API Oath e cortar o retorno de chamada do Facebook Além disso, temos que adicionar mais uma propriedade porque o Facebook não é como o Google O Facebook não envia muitos dados, então temos que especificar uma propriedade chamada campos de perfil para a matriz e, nessa matriz, adicionar todos os nomes de preenchimentos do Facebook Adicionamos o ID, que é o ID exclusivo do Facebook, e é exclusivo para cada usuário do Facebook, assim como o ID do Google. Além disso, passamos e-mails por e-mails, nome, nome de exibição. Tipo de ponto de imagem por vírgula e, entre parênteses Isso é para obter uma foto do perfil. A maioria dos aplicativos usa esses dados. Agora, aqui para retorno de chamada, queremos fazer o mesmo com essa estratégia do Google Então, simplesmente copiamos essa estratégia de retorno e a baseamos na estratégia do Facebook Aqui, nossa etapa quatro está concluída. Salve esse arquivo. Agora, na última etapa número cinco, temos que definir essa rota de retorno de chamada para o Facebook Abre um arquivo dot-gs. Aqui, podemos simplesmente copiar esse retorno de chamada do Google e colá-lo na parte inferior Também na parte superior, percebo que temos que mudar esse aplicativo dot GAD para roteador dot gat Bom. Primeiro, alteramos a API e apontamos para slash Facebook slash callback e também no passaporte dot Authenticate no lugar do Google, Agora, no retorno de chamada da API, precisamos alterar esse ID do Google pelo ID do Facebook Portanto, temos que adicionar outro campo no esquema de nossos usuários igual ao ID do Google Aqui, selecione o ID do Google e pressione Control plus T ou Command plus e selecione todos os IDs do Google nesta API do Facebook. No lugar disso, adicionamos o ID do Facebook e não precisamos mudar nada. Salve as alterações e não se esqueça de adicionar o campo ID do Facebook no esquema do usuário Abra o arquivo dot gs dos usuários e simplesmente duplique o campo ID do Google e altere seu nome para ID do Facebook, e estamos prontos para começar Salve as alterações, menos é isso. Abra o navegador e vá para o host local, coluna 3.000 slash API OT slash Veja aqui que o aplicativo não está ativo. Este aplicativo não está acessível no momento. O motivo é que, neste aplicativo, não adicionamos nem verificamos a empresa. Recentemente, o Facebook se tornou rígido quanto a isso, mas isso não importa, porque podemos ver que quando criamos essa API Get com APIs Orth, cortamos o Facebook, estamos obtendo a página do Facebook, o que significa que, do nosso lado, nossa API está Nosso principal objetivo é implementar o recurso de login com. Se seu cliente precisar fazer login no Facebook, você poderá usar a empresa dele e verificar seu aplicativo. Depois disso, esse recurso funcionará, mesma forma que nosso login com o Google está funcionando. Então é assim que implementamos Auth para nosso aplicativo de back-end É muito simples. Temos que seguir esses cinco passos. 107. Simplificando o código: Agora, como sabemos, nesse retorno de chamada de ambos, nosso código é o mesmo Basta alterarmos o ID do Google pelo ID do Facebook. Como prática melhor, podemos definir uma função reutilizável comum que simplesmente escreve um token no final Vamos cortar essa lógica do usuário líquido até a geração do token. Na parte inferior, criamos uma nova função, const, handle ou both callback igual à função arrow Nos colchetes Gly, passamos esse código e, no final, simplesmente retornamos o token Agora, primeiro de tudo, para usar esse Avid, precisamos tornar essa função assíncrona Agora, o que queremos mudar aqui? Aqui, precisamos desses dados de perfil e também precisamos dessa propriedade que queremos alterar, ID do Google ou ID do Facebook. Assim, podemos passar aqui dois parâmetros profile, que são os dados completos do perfil, e depois disso, ID do provedor. Não podemos adicionar esse ID de provedor porque, quando chamamos esse identificador ou função de retorno de chamada, passamos o ID do Google ou o ID do Facebook como string e não podemos adicionar aqui essa string Isso não vai funcionar. Simplesmente, podemos usar aqui, colchete, ID do provedor Além disso, no local do ID do Google com pontos de usuário, podemos escrever o ID do provedor entre colchetes do usuário Essa é a segunda forma de acessar o valor do objeto A aqui e também no blog Else e pronto. Agora, na API de retorno de chamada do Google, chamamos essa função de retorno de chamada handle orth E passamos aqui o perfil no primeiro parâmetro, e para o ID do provedor, o que passaremos write, passamos aqui, string, ID do Google. Certifique-se de escrever o mesmo nome de campo que você definiu no esquema do usuário Agora, essa função levará algum tempo para ser executada. Então, podemos usar here await e essa função retorna token. Assim, podemos armazená-lo em um token variável. Vamos fazer o mesmo com o callback do Facebook. Copie essa linha de token e no callback do Facebook do usuário let até esse token, removemos isso e simplesmente colamos aqui essa chamada de função Aqui, não se esqueça de alterar esse ID do provedor para ID do Facebook. Foi o que dissemos, nome completo? Sim, é o ID do Facebook. Veja, agora nosso código parece limpo. Agora, na próxima seção, criaremos APIs para cartões de produtos e pedidos de usuários. Isso é muito divertido. 108. Problema com Single Token [ATUALIZAÇÃO]: Agora vamos ver como grandes empresas como Google, Microsoft e Netflix implementam autenticação segura e perfeita, e é assim que outros aplicativos de nível de produção também implementam a autenticação Eles usam dois tipos de token JWT, token acesso e token de atualização. Não se preocupe com essas palavras grandes. Deixe-me explicar isso em palavras muito simples. Atualmente, em nosso aplicativo, criamos uma API para registrar um novo usuário e, em seguida, criamos uma API para registrar esse usuário. ambas as APIs, estamos enviando token JWT para o front-end e nosso front-end enviará esse token no cabeçalho da solicitação com o prefixo do portador e, usando esse cabeçalho, obtemos as informações do usuário em Agora, há dois problemas com essa abordagem. O primeiro é o problema de expiração do token. Definimos o tempo de expiração do token para 2 horas após 2 horas Nosso usuário precisa fazer login novamente para obter um novo token. Essa é uma experiência ruim para o usuário, pois eles precisam fazer login novamente toda vez que o token expira Agora você pode dizer que podemos aumentar o tempo de expiração e, com isso, nossa experiência do usuário será corrigida. Sim, isso é verdade, mas dessa forma, há outro problema relacionado ao risco de segurança. Imagine que, para uma boa experiência do usuário, aumentamos o prazo de validade para dez dias. Agora, se esse token JWT for roubado por outra pessoa, o atacante ou hacker poderá usar esse token como estamos usando até que o Nesse caso, não temos como sair ou revogar o token Só precisamos esperar que o token expire. Então, como podemos ver, não podemos aumentar o tempo de expiração. Tem que fazer esse tempo de expiração para 5 minutos ou 10 minutos. Agora, para melhorar a experiência do usuário, primeiro o Google criou esses dois conceitos de tokens, que são token de acesso e token de repressão, e veremos como esse conceito funciona na próxima lição 109. Acesso ao token e atualização da lógica de token [ATUALIZAÇÃO]: Agora vamos entender o conceito de token em excesso e token de atualização Então, no lugar de criar um token, criamos dois tokens em nossa API de registro ou login. O primeiro token, nós o chamamos de token em excesso e o segundo token, nós o chamamos de token de atualização Ambos são tokens JWT, mesma forma que geramos no final da nossa API Mas a única diferença é que, para o token em excesso, definimos o tempo de expiração como 5 minutos ou 10 minutos ou no máximo em horas para o token de referência. Definimos o tempo de expiração tão longo, por exemplo, por cinco dias ou duas semanas, assim, excesso e o token de referência, ambos são tokens JWT Podemos gerá-los usando o método de sinal de pontos JWT, mas apenas o tempo de expiração é diferente Agora você pode perguntar o que fará a diferença ao criar dois tokens separadamente. Para simplificar, eu explico seu fluxo de trabalho completo para que todas as suas dúvidas sejam esclarecidas. Imagine que isso é front-end e isso é back-end. usuário preenche o formulário de login como e-mail e senha e o envia. No back-end, verificamos os detalhes e comparamos a senha. Se as informações estiverem corretas, anteriormente, estaríamos criando um token. Nessa abordagem, criamos dois tokens. Um é o token em excesso e o segundo é o token de atualização. prazo de expiração do token excedente é de, digamos, 5 minutos e, para o token de atualização, damos um prazo de expiração de cinco dias Armazenamos esse token de atualização na coleção do usuário e, em seguida, enviamos esses dois tokens para o front-end nosso front-end, definimos o token em excesso no cabeçalho global da API com um prefixo melhor, o mesmo de antes Agora, se o usuário excede a API protegida, no back-end, obtemos o token em excesso do cabeçalho da solicitação e podemos enviar os dados de que nosso usuário precisa. Agora imagine que, após 5 minutos, nosso token de acesso expire Nosso usuário envia a solicitação de API novamente. Aqui, nosso back-end verifica esse token de acesso é válido ou não Aqui não é válido, a partir do back-end enviamos a resposta com erro 401 em token válido Agora, no front-end, o desenvolvedor escreverá o código. Quando o front-end receber o erro 401, desenvolvedor chamará outra API para obter o novo token de acesso Digamos que OT slash refresh. Agora, nessa API, podemos acessar o token de atualização Mas aqui, temos que verificar se esse token de atualização é válido para esse usuário ou não Lembre-se de que, quando geramos um novo token de acesso e um token de atualização, armazenamos o token de atualização no banco Podemos comparar esses dois tokens de atualização se eles corresponderem, que significa que o usuário é válido Nesse momento, geramos novamente um novo token de acesso, um novo token de atualização, atualizamos o token de atualização na coleção do usuário e, da mesma forma que antes, enviamos esses dois tokens para o front-end Com isso, o usuário não precisa fazer login repetidamente. Quando o usuário não tem um token de atualização ou quando um token expira, só então você precisa fazer login novamente. Simples assim. Agora, a pergunta que você pode fazer é: se esse token de acesso for roubado? Com isso, o atacante pode facilmente obter acesso. Sim, isso é possível, e é por isso que, atualmente, os desenvolvedores de front-end não estão armazenando tokens em excesso no armazenamento local. Eles o armazenam na abside, como uma variável JavaScript ou um repositório RxTate ou E mesmo que, de alguma forma, o atacante continue com o token em excesso, mantemos o tempo de expiração do token em excesso muito curto Agora você pode perguntar aos atacantes também possam manter o token de atualização . E quanto a isso? Além disso, ele tem uma longa expiração. Para resolver esse problema no local de envio do refrestocan para o front-end, podemos definir o refrestocen Agora, o que é o cookie SDTPoly? Um cookie SDDPoly é um tipo especial de cookie que não pode ser acessado pelo JavaScript executado no navegador Este cookie exclusivo para SDDP não pode ser acessado por meio de nosso navegador. Nosso navegador só pode enviar esse cookie com a chamada da API. Mas o JavaScript na página ou em execução no navegador não pode ler, modificar ou excluir um cookie, o que protege nosso token de atualização contra invasores Agora você pode perguntar se esse cookie SDDPoly é enviado somente com nossas chamadas de API ou será enviado com qualquer outra Essa é uma pergunta muito boa. cookie SDDPoly tem um recurso que chamamos de mesmo site Definimos a propriedade, o mesmo site como rua e, com isso, esse cookie exclusivo para SDDP será enviado apenas para nossas APIs de domínio de back-end, não para não para É por isso que o token de referência tem alta segurança porque não pode ser acessado por JavaScript. Agora vamos recapitular esse token de acesso e nos referir ao conceito de token Quando o usuário se registra ou faz login no lugar de um token, criamos dois tokens. O primeiro é o token em excesso, cujo prazo de expiração é buscado, e o segundo token é o token de atualização, cujo tempo de expiração é longo Armazenamos o token de atualização na coleção do usuário para esse usuário e, em seguida, enviamos o token em excesso para o front-end. Definimos o token de atualização no Agora, o melhor do SDTPoly Cookie é que ele não pode ser acessado pelo código JavaScript do navegador Amigo e navegador só podem enviar esse cookie SDTP com SDDPRquest Isso torna nosso token de atualização mais seguro e, como sabemos, nosso token de acesso está disponível no estado do aplicativo, não no armazenamento local Portanto, nossos tokens de barco estão seguros, e é assim que podemos oferecer ao usuário uma melhor experiência e melhor segurança. Simples assim. Então, usamos o token de acesso para acessar os dados do back-end e é por isso que o chamamos de token de acesso. Também usamos o token de atualização para reprimir nosso token de acesso, e é por isso que o chamamos de token de atualização Esse fluxo de trabalho é muito importante para seu aplicativo, e muitos desenvolvedores realmente não conhecem esse fluxo de trabalho completo. Mas tenho certeza que agora você sabe disso, o que é muito bom. Agora, na próxima lição, implementaremos essa lógica em nosso código. Vai ser divertido. 110. Implemente o Access Token e o Refresh Token [ATUALIZAÇÃO]: Agora, para implementar a abordagem de token em excesso e atualizar o token, precisamos fazer poucos lances em nosso back-end Primeiro, quando registramos ou logamos um usuário, precisamos gerar dois tokens e armazenar o token de atualização na coleção do usuário Depois disso, temos que devolver o token em excesso, mesma forma que o enviamos anteriormente na resposta. E então temos que inserir o token de atualização no cookie somente do SGDP, para que o JavaScript do nosso navegador não possa acessar ou atualizar Não se preocupe, é muito simples. Vamos fazer isso. Então, aqui criamos uma função para gerar o token e estamos retornando diretamente o token. Então, em vez de gerar um único token, aqui podemos gerar dois tokens. Então, primeiro, alteramos nome dessa função para gerar tokens. E dentro disso, no local em que está escrito, nós o armazenamos em uma variável chamada token de acesso. Depois disso, duplicamos essa linha e queremos gerar o token de atualização, como o nome da variável para o token de atualização. Além disso, precisamos alterar a expiração do token em excesso para 5 minutos e a expiração do token de atualização para sete D por sete dias essa linha e queremos gerar o token de atualização, como o nome da variável para o token de atualização. Além disso, precisamos alterar a expiração do token em excesso para 5 minutos e a expiração do token de atualização para sete D por sete dias . Além disso, no token de atualização, não queremos enviar todos os dados do usuário que desejamos no token excedente Então, aqui no lugar dos dados, simplesmente adicionamos um objeto com ID, coluna e ID de sublinhado de ponto de dados passivo Além disso, muitos desenvolvedores gostam de usar uma chave secreta diferente para o token de acesso e o token de repressão por motivos de segurança Aqui também, abrimos o arquivo ANV de pontos e, aqui, no lugar da chave JWT, escrevemos o token de acesso, Depois disso, criamos variáveis para reformulação, token, chave e fornecemos qualquer chave que você queira adicionar Salve isso e na rota de nossos usuários, em nossa função, alteramos jWTk para token em excesso, K, e esse jWTk para reformular Agora, ao final dessa função, retornamos o objeto com duas propriedades, token em excesso, token acesso ou podemos remover esse token de acesso e, depois disso, retornamos o token de atualização para o token de atualização. Bom. Agora vamos ver o que precisamos fazer no registro, uma nova API de usuário. Na parte inferior, podemos ver que chamamos essa função de gerar token e passamos aqui sob o quadrado ID e a propriedade do nome. Aqui, como sabemos, não retornamos um único token dessa função. Estamos retornando o objeto, então podemos desestruturar esse objeto aqui e obter o token de acesso e o token de atualização. Agora, na resposta, da mesma forma que antes, retornamos o token em excesso. Além disso, algumas empresas também enviam um token de atualização na resposta, mas não vamos fazer isso Estamos implementando aqui o código de nível de produção. Portanto, definiremos esse token de atualização no Cookie exclusivo do SDP. Para isso, escrevemos o ponto de resposta Cookie. Certifique-se de inserir o ponto de resposta Cookie antes de escrever ponto de resposta enviar ou o ponto de resposta JSn pois não podemos definir o cookie depois de enviar a resposta Se você escrevê-lo após a resposta dot json, você receberá um erro Com o primeiro parâmetro, escrevemos o nome da nossa propriedade. Digamos que se refira a um token. Depois disso, passamos o token de atualização. No terceiro parâmetro, temos que passar um objeto com algumas propriedades importantes. Primeiro, escrevemos SGDP apenas como verdadeiro. Isso significa que o JavaScript no navegador não pode ler esse cookie. Depois disso, adicionamos secure a true para garantir o SDP conforme solicitação Agora, atualmente, estamos testando-o para solicitação STDP local e é por isso que o tornamos falso aqui Mas, para lembrar, escrevemos aqui o comando para alterar isso de seguro para verdadeiro para produção. Depois disso, temos o mesmo local para a rua. Com isso, paramos nosso cookie para fazer outra chamada de API de domínio. Mas aqui, você precisa garantir que seu front-end e back-end estejam no mesmo domínio Por exemplo, gobleu.com para front-end e cola.com para back-end Se seu back-end e front-end estiverem hospedados em um domínio diferente, podemos definir essa configuração como nenhuma, que significa que nosso Cookie pode ir para qualquer domínio Aqui queremos que nosso navegador envie Cookie apenas para nossa plataforma de back-end Para isso, aqui escrevemos uma propriedade de domínio nosso domínio Bend, como api dotben.com Por essa propriedade, somente esse domínio receberá esse Cookie, não qualquer outro domínio. Atualmente, estamos executando nosso back-end no Host Local 3.000 e, no campo do domínio, não podemos adicionar o host local 3.000 porque aqui precisamos adicionar apenas o domínio real Também comentamos essa propriedade e, por fim, adicionamos MaxH ao tempo de expiração do nosso token de repressão Aqui passamos sete dias, mesmo que o tempo de expiração do nosso token de atualização. Sete em 24 horas em 60 minutos em 60 segundos em 1.000 milissegundos. Isso significa simplesmente que, após sete dias, esse cookie exclusivo para STP também expirará , será removido e pronto Definimos o token de atualização para o cookie SDTPoly. Agora temos que fazer o mesmo com a API de login. Então, copiamos esse método Cooke com pontos de resposta e, antes desse ponto de resposta, Jason, nós o colamos Então, aqui no lugar desse token, nós desestruturamos o objeto e obtemos aqui o token em excesso e o token reprimido Altere também o nome da função para gerar tokens, e aqui retornamos o token em excesso na resposta. Além disso, quando criamos o token de atualização, temos que manter esse token em nossa coleção de usuários porque, usando apenas isso, saberemos se o token de atualização é válido ou Primeiro de tudo, no esquema de nossos usuários, no final, adicionamos refrescen dois colchetes Carly, digite duas Salve isso e volte para a rota do usuário. Aqui na rota de login, antes de enviar o token em excesso, adicionamos o token de atualização ponto do usuário igual ao token de atualização E então adicionamos um peso pontos do usuário) s. Agora, aqui está uma coisa. Muitos desenvolvedores gostam de armazenar o token de atualização criptografado ou o token de atualização no banco de dados para maior segurança, e isso também é uma boa prática Então, aqui também, podemos fazer cost, new hed, refresh token é igual a await, crypt dot a, aqui, passamos o token de atualização e definimos Da mesma forma que estamos escutando a senha, estamos escutando o token de atualização Aqui, no local do token de atualização, armazenamos o novo token de atualização hesed Além disso, copie essas linhas e, em nossa API de registro, colamos aqui. Além disso, temos que mudar isso para o novo token de atualização de pontos do usuário e aguardar o CV do Nwuser dot É isso mesmo. Vamos verificar se está funcionando ou não. Salve as alterações, verifique se nosso back-end está funcionando. Agora, abra o Postman, abra a API de login e envie a solicitação Veja, aqui temos o novo token, que é nosso token de acesso. E se virmos depois dessa guia do corpo, obteremos um Cookie. Se verificarmos isso, veja, aqui obtemos o nome do cookie , que é token de atualização Portanto, obtemos valor, domínio, caminho expirado, STP apenas para verdadeiro e seguro para falso, o que é ótimo Portanto, definimos com sucesso o token de atualização no SDDPolygogi. Agora, na próxima lição, criaremos uma rota na qual nosso front-end enviará esse token de atualização, verificaremos esse token e enviaremos um novo token de acesso 111. Atualize rota para novo token de acesso [ATUALIZAÇÃO]: Agora, como sabemos, quando nosso token de acesso expirar, front-end enviará o token de atualização ao nosso back-end para obter um novo token de acesso Mas a questão é em qual endpoint, front-end enviará o token de atualização. Temos que definir esse ponto final. Portanto, na rota do autor, no final, adicionamos o ponto externo, endpoint para cortar a atualização e a função de retorno de chamada com solicitação e com Além disso, isso não é obrigatório. Temos que definir uma rota chamada atualização. É apenas uma convenção comum que os desenvolvedores usam. Agora, nesta função, precisamos fazer pequenas coisas. Primeiro, verificamos se o token de atualização está disponível no cookie ou não Portanto, para acessar o cookie, usamos request dot Cookies dot our Cookie name, que configuramos para reprimir o token Deixe-me te mostrar. Veja, esse é o nome do nosso cookie. Agora temos que armazenar esse valor em variável chamada token de repressão do usuário E depois disso, simplesmente adicionamos condição. Se o token de repressão do usuário não estiver disponível, retornaremos a propriedade de mensagem JSON de status de ponto de resposta de 2401 pontos para nenhum token de atualização fornecido Agora, e se obtivermos um token de atualização? Simplesmente, temos que comparar esse token de atualização com o token que salvamos na coleção do nosso usuário Agora, a questão é como sabemos qual usuário envia esse token de atualização Para isso, lembre-se de quando criamos um token de atualização, no momento em que passamos aqui o ID no token Então, usando esse ID, podemos passar o token de atualização armazenado Para isso, escrevemos JWT dot Verify. Primeiro, passamos o token de atualização, depois disso, temos que passar a chave secreta que é a chave atualização do processo dotenv dot Certifique-se de adicionar aqui token de atualização, não o excesso de Tgenkey Caso contrário, um token não será verificado. Agora, essa expressão retorna a carga ou podemos dizer os dados Então, nós o armazenamos na variável chamada usuário decodificado. Suponha que esse token não seja válido. Alguém alterou alguma coisa nesse token, então essa expressão pode retornar um erro. Assim, podemos aderir, tentar capturar o blog e simplesmente adicionar essa linha ao dr blog e ao blog de cache, obtemos aqui o erro e simplesmente retornamos a resposta, o status do ponto 403, o ponto Jason e a propriedade messet como token inválido e Agora, suponha que obtenhamos o usuário decodificado do token e agora, usando isso, tenhamos que encontrar o token do usuário armazenado Portanto, o custo do usuário é igual a um peso, ponto do usuário é encontrado por ID e passa aqui o ID de sublinhado do ponto de usuário decodificado Aqui também adicionamos condições. Se o usuário não estiver disponível, retornaremos o status do ponto de resposta, o Json de 404 pontos e a mensagem para o usuário não encontrado Além disso, aqui para usar await, precisamos adicionar async para Bom. Agora, se o usuário estiver disponível, basta comparar o token. Agora, como sabemos, em nossa coleção, nós armazenamos como token, então precisamos compará-la da mesma forma que estamos comparando nossa senha. Então, para isso, escrevemos await, decrypt dot compare. Primeiro, passamos o token de atualização do usuário, que obtemos do cookie, e depois queremos compará-lo com o token de atualização do ponto do usuário Essa expressão retornará se é válida ou não. Então, nós o armazenamos em variáveis. O custo é válido. Além disso, certifique-se de importar a criptografia B neste arquivo. Então, no topo, adicionamos custos. B crypt é igual a require, aqui adicionamos o Wikip. Agora, de volta à nossa rota. Aqui, depois disso, precisamos passar pela condição dela. Se for válido é falso, então retornamos o status de ponto de resposta 403 pontos jSN e a mensagem para atualizar o token não é E se o token for válido, precisaremos repetir exatamente o mesmo processo que estamos fazendo após o login ser bem-sucedido. Abrimos a API de login aqui depois de comparar a senha C, geramos um novo token de acesso e um novo token de atualização, como o novo token de atualização, atualizamos o token de atualização do ponto do usuário com novo stoken, depois configuramos o token de atualização no cookie e, no final, retornamos o Nós simplesmente copiamos esse código. E cole em nossa rota de repressão. Agora aqui, primeiro de tudo, precisamos gerar a função Cs. Podemos inserir nossa função a partir do arquivo de rota do usuário, mas para isso, precisamos alterar a entrada no arquivo JS de pontos de índice. Não quero confundir você por fazer isso, então podemos simplesmente copiar essa função de gerar para C daqui e simplesmente colá-la no arquivo de saída e pronto Aqui, nossa implementação da rota de atualização está concluída. Vamos usar essa API, salve as alterações e dê uma olhada. Abra o Postman, aqui criamos uma nova solicitação chamada método refresh token para postar, e aqui escrevemos nossa URL, STP, Column double for slash Local host, Column 3.000 slash APIs OT porque está Atualização do Slash. Agora, basta enviar a solicitação. Veja, aqui temos um erro, não é possível ler propriedades de indefinido Acho que não estamos entendendo token de atualização do usuário Deixe-me tentar consolar o registro de pontos. O usuário repres o token, salva as alterações e envia a solicitação Veja, aqui obtemos o mesmo erro, e se abrirmos nosso código via, veja, não estamos recebendo o token de atualização no log do console, o que significa que não estamos recebendo o token de atualização do usuário no cookie O motivo pelo qual não estamos recebendo cookie é porque no Node js, não podemos acessar o Cookie diretamente, assim como não podemos acessar diretamente os dados do corpo da solicitação. Lembre-se de adicionar o middleware Express dot JN para acessar os dados do corpo da solicitação adicionar o middleware Express dot JN para Para Cookie também, precisamos adicionar um middleware que nos ajudará a obter o Cookie a partir da solicitação Então, para isso, instalamos outro pacote Cookie parser, NPM install Cookie, das parser e pressionamos enter. Bom. Agora, em nosso arquivo Js de pontos de índice, primeiro inserimos o analisador de cookies de custo igual a require cookie parser E então, na parte inferior, adicionamos app dot ug, Cookie parser e chamamos essa função aqui Sem essa função de analisador de cookies, não podemos acessar cookies de pontos de solicitação Além disso, em nossa API de represe, percebo que esse usuário decodificado está É porque o definimos com Cst no blog seco e, devido ao custo, esse usuário decodificado só pode ser acessado neste blog seco Aqui, queremos acessar o usuário decodificado fora do blog dri Então, para isso, antes deste Tyblog, definimos deixar usuário decodificado e, em seguida, removemos esse custo Agora podemos acessar o usuário decodificado aqui, salvar as alterações e dar uma olhada Envie a solicitação e veja aqui que obtemos o usuário não encontrado, o que significa que não estamos recebendo os dados do usuário. Deixe-me verificar. Aqui estamos passando um ID de sublinhado de ponto de usuário decodificado. Deixe-me verificar se é propriedade de ID de sublinhado ou não. Sim, veja, no token de atualização que gera, passamos a propriedade ID e não a ID de sublinhado Então, atualizamos isso para sublinhar o ID e também com a mesma função de geração de tokens da rota do usuário Salve as alterações e dê uma olhada. Aqui, se o token expirar, você poderá chamar a API de login que definirá o novo token como Koki Agora, vamos enviar a solicitação de atualização novamente. Veja agora, em resposta, obtemos nosso novo token em excesso e também um novo token de atualização está definido no cookie de solicitação Se enviarmos novamente a mesma solicitação , veja aqui que obtemos os dois novos tokens. Isso é semelhante à nossa página inicial, seja atualizada. Se o token em excesso expirar, nosso front-end chamará essa API de atualização e, em seguida, nosso front-end receberá o novo token em excesso e o token de atualização 112. OAuth com dois tokens [ATUALIZAÇÃO]: Agora, vamos atualizar rapidamente o código Oth também porque aqui também estamos enviando apenas um token. Então, como você pode ver, estamos gerando um token dentro dessa função de callback do handle OT Agora, no local de gerar o token aqui, podemos usar nossa função de gerar tokens e passar aqui os mesmos dados que este. E agora temos aqui colchetes const cli, excesso e token de atualização Agora, não precisamos dessa variável de token e, depois disso, simplesmente retornamos o objeto com token em excesso para o token em excesso, ou podemos removê-la e atualizar o token para o token de atualização Agora, aqui temos uma coisa. Aqui, já temos dados do usuário. É bom. Salvamos o token de atualização nos dados do usuário, então não precisamos enviar outros dados por consulta Então, a partir da API do usuário de login, copiamos esses códigos de criptografia e também salvamos o token no token de atualização do ponto do usuário E cole esse código na função handle ou callback. Agora, em nossa API de retorno de chamada do Google, obtemos o objeto no lugar do token e desestruturamos o token em excesso e reprimimos o token Agora, antes de redirecionar o usuário para o front-end com o token, precisamos definir o token de atualização no cookie exclusivo do SDP Então, acessamos a API de login novamente, copiamos esse método cookie de ponto de resposta e o colamos na API de retorno de chamada do Google Por fim, simplesmente passamos o token em excesso no lugar do togan, agora fazemos o mesmo com a API de retorno de chamada do Facebook Aqui, obtemos o objeto com ficha em excesso e a ficha repressão e colamos aqui, o mesmo Goki Em seguida, simplesmente trocamos esse token pelo token em excesso e pronto. Agora, na próxima lição, veremos o que precisamos fazer para logar o usuário. 113. Rota para o logout de um usuário [ATUALIZAÇÃO]: Agora, você pode me dizer o que aconteceu quando o usuário se desconectou? Se expirarmos o token em excesso do front-end , no cookie somente do SCTP, já teremos um token de atualização que tem uma Nosso front-end pode executar a API de atualização novamente e obter os novos tokens, mas não queremos isso Queremos desconectar completamente o usuário. Portanto, para isso, precisamos remover apenas o token de atualização do Cookie somente do SDDP e da coleção do usuário Então, vamos criar aqui uma nova rota, ponto após barra externa, cabana de registro e função de retorno de chamada ASN com solicitação Agora, para remover o Cookie, usamos o método response dot clear Cookie. Aqui, passamos o nome do nosso cookie que queremos remover. Nós passamos aqui o token de atualização, certifique-se de verificar o nome do seu cookie ao gerá-lo Agora, esse método removerá o cookie refrestken e funcionará na Mas quando queremos implementar isso na produção , também precisamos adicionar objetos com propriedades. Essa expressão funciona para produção, mas às vezes pode causar problemas na produção. É melhor passarmos propriedades. Certifique-se de que sejam as mesmas propriedades que adicionamos durante a criação do Cookie. Copie este objeto e, em nosso cookie transparente, nós o passamos. Bom. Agora, depois disso, simplesmente retornamos o objeto Json do ponto de resposta com a propriedade de mensagem desconectada Agora, antes de remover o biscoito, é melhor. Também removemos o token de atualização da coleção do usuário Para isso, precisamos atualizar o token do cookie, decodificar o ID do usuário do token, buscar o token do banco de dados e, em seguida, removê-lo Já fizemos isso em nossa API de atualização. Lembre-se de que podemos simplesmente copiar esse código da obtenção do Cookie para decodificar o usuário até obtermos o usuário Copie isso e simplesmente cole antes do método clear Cookie. Agora, aqui temos o usuário. Só precisamos fazer com que o token de atualização do ponto do usuário seja igual a nulo E então aguardamos que o usuário salve e pronto. Vamos testar essa API de logout. Diga que as alterações NÃO, um Postman, duplique essa solicitação de atualização Bom, altere o nome da solicitação para o logotipo de um usuário. Altere a API e aponte para slash logout. Agora, atualmente, verificamos nosso cookie. Veja se está disponível aqui. Agora, se enviarmos essa solicitação de logout, veja, aqui obteremos o logout com sucesso e, se verificarmos novamente o cookie, ele desaparecerá daqui Então é assim que o registro, o login, o logout e o token no nível de produção funcionam Além disso, as últimas seis aulas são aulas atualizadas. Portanto, se você não vê esse código nas próximas aulas , não se preocupe com isso. Você pode seguir essas lições. Eu só quero atualizar essas feridas. Então, atualmente estamos degustando este projeto. Portanto, se definirmos o excesso para um prazo de validade de 5 minutos , é muito difícil prová-lo Portanto, apenas para degustação, definimos o prazo de validade em um Além disso, no arquivo de rota do usuário na parte inferior, alteramos o excesso para uma expiração de um dia Na produção, podemos atualizá-lo para 5 minutos. 114. Seção 10 — como criar o modelo de categoria: Bem-vindo à seção de então do curso definitivo de Node JS. Nesta seção, continuaremos trabalhando em nosso projeto de back-end de aplicativos de comércio eletrônico Adicionaremos alguns recursos interessantes, como adicionar imagens de produtos no back-end, autorização baseada em funções, consulta de pesquisa simples e rápida e muito, muito mais Então, vamos começar nesta seção. Em primeiro lugar, em nosso aplicativo de comércio eletrônico, queremos adicionar produtos por categoria Se você selecionar a categoria fones de ouvido, enviaremos apenas produtos cuja categoria seja fone de ouvido Para isso, temos que definir o modelo de categoria. Então, na pasta models, criamos um novo arquivo chamado category dot JS. Agora, dentro desse arquivo, em primeiro lugar, Const Mongoose é igual a require Mongoose Depois disso, o esquema da categoria de custo é igual ao esquema de pontos nu mangos Dentro desse objeto, adicionaremos nosso esquema. Agora, o que você deseja adicionar nesta coleção de categorias? Primeiro, precisamos do nome da categoria. Então, talvez precisemos do ícone da categoria. Essas propriedades dependem da parte da interface do usuário do front-end. Queremos exibir categorias como essa com ícones e, em seguida, temos que armazenar o nome do arquivo Cn em nosso banco de dados. Agora, em nosso aplicativo, queremos fazer uma coisa. Somente o administrador pode adicionar categorias em nosso banco de dados. Um usuário simples não pode adicionar ou excluir uma categoria. R, se em nosso aplicativo, tivermos vários administradores, podemos adicionar aqui o preenchimento É o ID desse administrador. Mas aqui não queremos armazenar os detalhes do administrador para que possamos remover esse preenchimento. Portanto, temos apenas dois preenchimentos para essa categoria, modelo ou coleção Então, adicionamos aqui nome ao objeto, tipo, à string necessária para verdadeira e também exclusiva para verdadeira. Em seguida, queremos que o nome da imagem do ícone seja objeto, tipo ou string, porque queremos armazenar o nome da imagem aqui e obrigatoriamente ser verdadeiro, e pronto. Agora, muitos estudantes se confundem ao armazenar imagens no back-end Deixe-me explicar a lógica. No banco de dados, não podemos armazenar imagens diretamente. Então, fazemos algo assim. Suponha que o usuário carregue essa imagem do front-end. No servidor de back-end, criamos uma pasta chamada uploads e nela armazenamos a Agora, enviamos um arquivo em nosso servidor com o nome que queremos dar a essa imagem. Depois disso, simplesmente armazenamos o nome da imagem no banco de dados. Além disso, algumas pessoas gostam de armazenar todo o caminho da imagem, mas isso não é necessário nesse caso, porque estamos armazenando essa imagem em nosso próprio servidor. Portanto, precisamos apenas preencher o nome da categoria e da imagem , que é o nome da imagem. Agora, depois disso, podemos criar um modelo com base nesse esquema A segunda categoria é igual ao modelo de pontos Mongos. Primeiro, passamos o nome singular da nossa coleção de categorias, que é categoria. E segundo, passamos o esquema e, no final, o módulo de exportação de pontos é igual a essa categoria. Feito. Agora, na próxima lição, adicionaremos API para criar uma nova categoria com upload de imagens. 115. Crie uma nova API de categoria com upload de imagem: Agora vamos criar uma nova API para a categoria. Para isso, criamos um novo arquivo na pasta Routes chamado category dot js. Neste arquivo, o que fazemos? Escreva, temos que criar um roteador usando o Express. Portanto, const Express é igual a require Express. E o próximo roteador const é igual ao roteador express dot. E também, por fim, temos que exportar esse roteador. As exportações de pontos do módulo são iguais às do roteador. Bom. Agora, antes de esquecermos de adicionar essa nova rota no arquivo JS de pontos de índice, vamos fazer isso. Eu cometi esse erro e tentei testar minhas APIs. Salve este arquivo, vá para o arquivo index dot js. Aqui, importamos rotas de categoria igual a exigir, aqui vamos para a pasta de rotas e nessa categoria. Agora, na parte inferior, usamos app dot g. Aqui, definimos o prefixo, que é a categoria de barra da API Depois disso, no segundo parâmetro, passamos rotas de categorias. Salve esse arquivo e volte para o arquivo de rotas de categorias. Bom. Agora vamos definir a API para criar uma nova categoria. Aqui, definimos uma nova rota usando o roteador dot post. 8.2 barra para frente, e aqui passamos chamada com a função de seta solicitação e resposta Aqui, queremos armazenar a imagem do ícone com o nome da categoria. Então, para armazenar a imagem, precisamos de um pacote chamado Multer. Esse é um pacote muito popular para armazenar todos os tipos de arquivos no aplicativo Express. Muitos desenvolvedores confundiram com Multer, mas é muito simples. Deixe-me te mostrar. Abra o terminal e escreva NPM install Multer no 1,4 0,5 traço ts dot um e Bom, minimize esse terminal. Agora, em nosso arquivo, primeiro adicionamos Const ulter é igual a require E depois disso, criamos uma variável chamada st upload igual a aqui, chamamos esse método Multer, e dentro dos parênteses, temos que passar o objeto com a propriedade dest, que é o destino Aqui, temos que especificar em qual pasta ou caminho queremos armazenar nossa imagem. Escrevemos a categoria de upload. Com isso, nossas imagens de categoria permanecerão em uma pasta separada. Agora temos que adicionar esse método de upload como middleware da nossa API de postagem Aqui, adicionamos o ponto de upload. Aqui temos muitos métodos, como single. Isso aceitará somente um único arquivo. Nenhum, isso não aceitará nenhum arquivo. A aceitará vários arquivos. N aceitará todos os arquivos e preenchimentos, o que aceita vários preenchimentos específicos Se você quiser se aprofundar neles , consulte sua documentação. Por enquanto, não se preocupe com isso. Aqui, queremos aceitar e salvar somente um único arquivo. Usamos aqui um único método. Agora, neste parêntese, temos que passar o nome do campo Suponha que passemos por aqui, ícone. Agora, a partir do front-end, temos que usar a tag de entrada, digitar o arquivo e, no campo do nome, passar o mesmo nome que é C. Por esse nome preenchido, Malta sabe qual arquivo deve salvar e pronto Multer salvará nosso ícone de arquivo na categoria de upload do caminho de destino e obteremos as informações sobre esse arquivo no arquivo de pontos da solicitação e obteremos o restante dos dados do formulário no corpo do ponto da solicitação, da mesma forma que antes Agora vamos escrever o resto do código para essa API. Então, primeiro de tudo, aqui adicionamos a condição I, e isso verificará se o nome do ponto do corpo do ponto da solicitação não está disponível ou o arquivo de pontos da solicitação não está disponível. Então, aqui retornamos o status do ponto de resposta, 400 para o ponto de solicitação inválida JSON, e aqui passamos o objeto com propriedade da mensagem e passamos aqui a mensagem de erro, nome e o ícone são obrigatórios agora e se tivermos esses dois Criamos uma nova categoria, const, nova categoria é igual a nova Aqui, precisamos do modelo de categoria. Portanto, no topo, a categoria de custo é igual à exigência, aqui está uma categoria de modelos dobrados Bom. Agora, na parte inferior, aderimos à nova categoria e aqui passamos objeto com propriedades dessa coleção. Primeiro, adicionamos nome ao nome do ponto corpo do ponto Nome do ponto. Temos apenas um preenchimento no corpo, e é por isso que não desestruturamos esse preenchimento da mesma forma que antes Em seguida, passamos a imagem para solicitar o arquivo de pontos. E aqui queremos salvar o nome do arquivo, então escrevemos o nome do arquivo Se você quiser armazenar o caminho completo do preenchimento, precisará aderir solicitar o caminho de pontos do arquivo de pontos. Além disso, podemos aderir ao log de pontos do console, solicitar o arquivo de pontos para ver o que obtemos no arquivo de pontos de solicitação, para não nos confundirmos. Depois disso, adicionamos await, nova categoria ponto c, e você sabe o que temos que fazer agora Sim, temos que fazer com que essa função seja para usar await; no final, enviamos a resposta com estatísticas para 01 para o novo ponto de dados Json Aqui, adicionamos um objeto com a propriedade messet, categoria adicionada com sucesso À medida que passamos de categoria para nova categoria. Agora vamos testar essa API. É um pouco diferente porque aqui temos que enviar o arquivo. Não podemos enviar um arquivo no formato JSON, então temos que usar o formulário aqui, e também não podemos fazer o upload do arquivo usando Thunder Client porque esse recurso está disponível apenas para usuários pagos Muitos desenvolvedores gostam do Postman e não gostam do Thunderclient por causa disso Usaremos o Postman aqui. Se você não conhece o Postman, eu lhe darei meu tutorial anterior para um guia rápido do Postman Então, para baixar o Postman, acessamos postman.com Aqui, podemos baixar esse aplicativo. Basta instalar este aplicativo. É muito simples. É assim que fica quando o abrimos pela primeira vez. Temos duas opções criar uma nova conta ou fazer login com a conta. Eu faço login rapidamente com minha conta aqui. Se você se inscrever ou fizer login, poderá criar aqui uma coleção como o cliente Thunder Aqui, criamos uma nova coleção em branco. Caris e em nosso projeto Cartws, adicionamos uma nova pasta chamada category Se você quiser ampliar , pressione Control and plus ou Command Plus. Nesta pasta, adicionamos uma nova solicitação, criamos uma nova categoria. Agora, em primeiro lugar, selecionamos o método de postagem, URL para STP, coluna, barra dupla, host local, coluna 3.000, categoria ABI coluna 3.000, categoria Agora, para enviar um arquivo no corpo, vamos até o corpo. Aqui, selecionamos os dados do formulário. Aqui, obtemos a chave, que é o nome, o valor e a descrição do preenchimento. Primeiro, adicionamos nossa chave, que é o nome completo de, digamos, laptops. Em seguida, inserimos nosso nome de preenchimento para o arquivo e o que foi isso? Lembre-se, escrevemos aqui o ícone. Então, aqui também, temos que escrever o ícone. Para carregar o arquivo no lado direito da chave, recebemos o texto e o menu suspenso, que é o tipo de conteúdo. Aqui, selecionamos Arquivo, clicamos em Selecionar Arquivo e selecionamos um novo arquivo na máquina local. Agora, para ícones de laptop, vá para a pasta de recursos, que você baixou anteriormente, ou você também pode baixá-la agora abaixo desta lição. Pasta de recursos, adicionei uma pasta para o Projeto dois. Nessa pasta, vamos para a pasta de categorias e, nela, você obtém todos os ícones da categoria. Selecione o arquivo PNG de pontos do laptop e abra I. Agora vamos enviar essa solicitação. Aqui eu recebo um erro. Desculpe, esqueci de iniciar este aplicativo. Portanto, anote bem os pontos de índice. Além disso, aqui eu noto que cometo esse erro, status do ponto de resposta. Salve as alterações, volte para o Postman e envie a solicitação Veja, aqui temos a nova categoria, laptops e imagem com esse nome aleatório. Além disso, vamos verificar se nosso arquivo foi salvo na pasta de upload ou não. Veja, aqui temos o arquivo com esse nome de arquivo aleatório. Portanto, está funcionando, há alguns problemas. Este arquivo, salve sem sua extensão, como ponto png ou ponto JPG, etc Sem extensão, nossa imagem não ficará visível no navegador. Esse é o problema número um. próxima edição está aqui, podemos fazer upload de qualquer tipo de arquivo, não apenas imagens. Suponha que, por engano, alguém carregue aqui um arquivo PDF de pontos, então o que faremos. Então, aqui também é necessário adicionar um filtro para isso. Somente pontos png ou pontos jpg ou GIF de pontos podem ser carregados para esse preenchimento de imagem, e resolveremos esses problemas na próxima lição 116. Defina o nome e o filtro do arquivo em mais: Na lição anterior, temos dois problemas. Não obtemos extensão para nosso arquivo de imagem e também no banco de dados. Em segundo lugar, não podemos filtrar somente imagens. Vamos resolver isso. Isso é muito simples. Deixe-me mover essa categoria acima do multer para que possamos ver isso claramente Aqui, passamos apenas a propriedade dest na função multer. Mas em multer, temos poucas propriedades a mais do que uma mesa. Remova esse destino e aqui podemos passar a propriedade de armazenamento , exceto a propriedade de armazenamento em vários discos Então, em vez de bagunçar o co aqui, podemos defini-lo em uma variável separada O custo de armazenamento é igual ao armazenamento em disco com vários pontos. Dentro disso, podemos definir como e onde os arquivos devem ser armazenados em nosso servidor. Passamos Objeto e a primeira propriedade é o destino onde queremos armazenar nosso arquivo. Isso, exceto a função Callback, que tem três propriedades, arquivo de solicitação Esse é o objeto do arquivo carregado e CB é uma função de retorno de chamada para especificar o caminho de destino Função de erro aqui, simplesmente chamamos essa função de retorno de chamada na primeira posição, passamos null, o que é para Depois disso, passaremos pelo nosso caminho de destino, que é a categoria de upload. Esse retorno de chamada definirá o destino como categoria de upload Se esse diretório não existir , teremos que criá-lo manualmente. Mas já temos essa pasta aqui. Se você não tiver, precisará criar esse caminho, fazer o upload e, nessa pasta, a pasta da categoria. Caso contrário, o Ulter nos dará um erro. Agora, depois do destino, aqui também podemos especificar a propriedade do nome do arquivo. Isso também aceita a função de retorno com as mesmas três propriedades, arquivo de solicitação, CB para retorno de chamada e função de seta Agora, nesta função, queremos definir o nome de arquivo específico e exclusivo para nosso arquivo. Nome de arquivo exclusivo porque se dois nomes de arquivo forem iguais, o último substituirá a primeira imagem. Em vez de uma foto feminina, usuário obterá uma foto masculina, e não é isso que queremos. Como prática comum, armazenamos o carimbo de data/hora no nome do arquivo desta forma Primeiro carimbo de data/hora e, em seguida, nome do arquivo com extensão. Isso significa que quase todos os arquivos receberão um nome exclusivo. secCttTmp é igual ao ponto de data agora. Com isso, obtemos a hora atual. Depois disso, também queremos fazer algo no nome do arquivo. nome SeconsOriginal é igual ao arquivo. Nome original do Dot. Com isso, obteremos o nome original do arquivo enviado, como laptops dot PNG. Agora, no nome do arquivo, talvez haja algum espaço, então é melhor substituirmos esse espaço pelo traço Isso tornará o URL do nosso nome de arquivo amigável. Nós adicionamos o método plex. Aqui, primeiro adicionamos a expressão regular e sua sintaxe é uma barra dupla entre elas, adicionamos uma barra invertida como espaço e mais para um ou mais No final da expressão regular, adicione G como sinalizador global, o que garante que todas as correspondências na string sejam substituídas, não apenas a primeira. Aqui, passamos o traço em códigos únicos, isso significa que todo o espaço será substituído pelo traço Agora, e se no nome do arquivo também obtivermos os caracteres especiais? Precisamos removê-los também. Adicionamos outro método de substituição. Primeiro, o que passamos? Expressão regular, e qual é a sintaxe, barra dupla Entre eles, estamos obtendo expressões regulares para obter os caracteres especiais. Aqui adicionamos A a Z, Alt A a Z de zero a nove, agora também queremos obter outros personagens que não façam parte disso, e esses serão nossos caracteres especiais. Para inverter isso, nós o envolvemos nos colchetes e após o primeiro colchete, adicionaremos Garret no final, também adicionaremos G para a também adicionaremos G Agora, queremos substituir esses caracteres especiais por nada. Só queremos removê-lo. Então, adicionamos aqui apenas códigos sem nada. Não se preocupe se você não sabe muito sobre expressões regulares, tudo bem. Agora, por esses dois métodos, se o nome do nosso arquivo for esse, ele ficará assim. Agora, no final, vamos misturar esse timestamp e o nome do arquivo original CB primeiro, passamos null por erro e, segundo, reescrevemos as tags, aqui adicionamos colchetes em dólares , carimbo de data/hora, colchetes em dólares Cully, nome original e pronto. Definimos o destino e também o nome do arquivo enviado. Agora podemos simplesmente passar essa variável de armazenamento aqui na função Multi Nosso primeiro problema foi resolvido. Agora vamos para a segunda edição para aplicar o filtro para arquivo. Na função multer, temos outra propriedade chamada filtro de arquivo Aqui também, temos que passar a função de retorno de chamada para que possamos defini-la em uma variável separada Custo, filtro de arquivo é igual à função de retorno de chamada com três parâmetros, solicitação, arquivo e função de erro CB, e nessa função, decidimos se o arquivo deve ser aceito ou Aqui, primeiro definimos uma variável, tipos permitidos, que é a matriz, e aqui adicionamos todos os tipos que aceitamos. Primeiro, imagens GPG, que são JPG com pontos e JPG com pontos. Em seguida, imagem png, para pontos png, e imagem GIF para GIF de pontos Aqui, podemos simplesmente colocar uma condição. Se o tipo While mime for desse, então nós o permitimos, caso contrário, o rejeitaremos Se permitir tipos, inclua pontos e entre parênteses, passamos o tipo Mme do ponto do arquivo Agora você pode perguntar qual é o tipo de Mme? tipo MIME significa o tipo de extensões multiuso do Internet Mail, que é um rótulo usado para identificar o formato do arquivo ou dos dados Aplicativos ou navegadores sabem como lidar com isso. Se fizermos o upload do arquivo PNG, tipo Mme será PNG com barra de imagem ou, se fizermos o upload do arquivo PDF, tipo Mme será o PDF com barra do aplicativo Se o tipo Mme estiver disponível no tipo permitido, chamamos a função CB e, primeiro, passamos null para erro e passamos por, exceto o arquivo Agora, se o tipo M for outra coisa, então esses tipos, então aderimos como condição e chamamos a função Cb, e no erro, passamos um novo erro, e aqui passamos a mensagem de erro, tipo de arquivo inválido, somente JPEG, PNG e GIF E para rejeitar esse arquivo, adicionamos aqui false. D. Agora temos que adicionar aqui, arquivo ao filtro de arquivo. Aqui, resolvemos os dois problemas. Deixe-me mostrar mais uma propriedade útil do ulter. Aqui na função múltipla, temos limites que nos ajudam a limitar o tamanho do arquivo Imagine que alguém carregue acidentalmente aqui o ícone de 10 megabytes Não precisamos de 10 megabytes para um ícone pequeno. Podemos limitar o tamanho do arquivo. Aqui, passamos o tamanho do arquivo do objeto. Aqui, temos que passar o tamanho do arquivo em bytes. Para nosso ícone de categoria, podemos definir o limite de dois MB, isso é mais do que suficiente, e para convertê-lo em bytes, adicionamos 10 a quatro. Com isso, obteremos kilobytes ou KB e novamente em 104. Com isso, converteremos esse KB em bytes. E pronto. Agora vamos testar essa API. Então vá para o Postman e aqui já temos nossos dados para laptops. Envie essa solicitação. Veja aqui que não obtemos resposta. Mas se verificarmos nossa pasta de categorias de uploads, obteremos um novo arquivo com nosso nome exclusivo Extensão, nossa imagem está sendo armazenada. Agora vamos verificar o erro e, se verificarmos nosso terminal , aqui podemos ver que obtemos erro de chave duplicada para nomes de laptops Lembre-se de que, na lição anterior, armazenamos a categoria de laptops com esse nome de arquivo aleatório e também no esquema da categoria, definimos a propriedade name como unique Temos que remover essa categoria anterior do Mongo Di B Compass Aqui, basta remover este documento. Além disso, removemos as duas imagens do nosso servidor. Nós não precisamos disso. Agora, enviamos novamente a solicitação. Veja, aqui recebemos a mensagem de sucesso. Recebemos um bom nome de imagem e também a imagem salva corretamente em nosso servidor. Ótimo. Agora vamos adicionar mais algumas categorias. Portanto, o nome da segunda categoria é smartphones. E para isso, nós carregamos o ícone do celular dot png. Certifique-se de remover a primeira imagem. Caso contrário, ele será enviado para imagens. Envie a solicitação. seguir, temos a categoria, relógios inteligentes e o ícone que selecionamos aqui watch dot png. E envie. Em seguida, temos fones de ouvido e ícone para pontuar o fone de ouvido PNG e enviar a solicitação Por último, temos consoles de jogos e, para ícones, pontos de videogame PNG, enviamos e pronto Agora, na próxima lição, você criará uma API para obter todas as categorias da nossa coleção. 117. Obtendo a API de todas as categorias: Vamos criar uma API para obter todas as categorias. É muito simples. Após a postagem da API, criamos uma nova API, ponto do roteador, barra frontal, porta para endpoint, função de retorno de chamada com resposta de solicitação, função de seta E dentro dessa função, primeiro, obtemos todas as categorias do modelo. Portanto, as categorias C são iguais a um peso, categoria dot find. E se você quiser enviar a categoria abreviada pelo nome da categoria, então adicionamos aqui o método shot, e aqui passamos o nome de preenchimento pelo qual queremos fotografar, que é o nome e simplesmente enviamos categorias JCN de ponto de resposta Além disso, aqui temos que fazer essa função funcionar. Salve as alterações e vamos experimentar essa API. Então vá até o carteiro ou cliente do concurso. Adicionamos aqui uma nova solicitação. No entanto, em todas as categorias, no endpoint, escrevemos a categoria de API Local host 3.000 Selecione o método Get e simplesmente envie a solicitação. Veja, aqui temos categorias encurtadas por seus nomes. Muito legal. Agora, se você precisar adicionar mais APIs, como atualizar ou excluir a categoria, também poderá fazer isso Realmente depende de você, por enquanto não precisamos disso aqui, então eu não os crio. 118. Compartilhando imagens estáticas do servidor: Atualmente, para dados de categorias, armazenamos a imagem em nossa pasta de upload de categorias Mas como nosso navegador pode acessar essas imagens? Eles estão disponíveis somente em nosso servidor. Para acessar as imagens do navegador, precisamos compartilhar os arquivos de imagem estática do nosso servidor. Já fiz isso na Seção cinco, Lição quatro. É muito simples. Então, indexamos o arquivo dot js aqui após express dot J e middleware, adicionamos app dot U. Aqui tínhamos o prefixo do caminho estático do arquivo, então o configuramos para Agora, para compartilhar os arquivos estáticos do servidor, precisamos usar outro middleware embutido chamado express dot E dentro dessa função, temos que passar o nome da pasta que queremos compartilhar. Carregue menos categorias. Lembre-se de que esse é o prefixo da URL e o caminho da pasta de nossos arquivos estáticos Salve as alterações e vamos tentar acessar essa imagem do laptop. Copie o nome completo desta imagem. Agora vá para o navegador. Aqui na URL, escrevemos nosso backend, host local, coluna 3.000 Aqui temos que adicionar o prefixo para arquivo estático, que é a categoria de barra de upload Passamos aqui a categoria de imagens, então também temos que escrever a categoria Imagens no URL do navegador. Por enquanto, nos limitamos à categoria Upload, e aqui também passamos pela categoria Upload, e aqui colamos o nome completo da imagem. Veja, aqui temos a imagem. É assim que, usando esse URL, o front-end exibirá esses ícones. Agora, na próxima lição, criaremos um novo modelo para produtos. Isso vai ser divertido. 119. Exercício — Definindo o modelo de produtos: Agora é hora de fazer um pouco de exercício. Você precisa definir o modelo de um produto. Neste modelo, temos os preenchimentos, e esses são os dados de amostra de um único produto Você precisa criar seu próprio esquema para esses preenchimentos, dedicar seu tempo, resolver este exercício e, em seguida, qual é a Espero que você resolva este exercício ou tente resolvê-lo. Dê crédito a si mesmo por isso. Agora vamos resolver esse exercício. Para o modelo do produto, criamos um novo arquivo na pasta de modelos chamado products dot js. Bom. Em primeiro lugar, custar mangas é igual a exigir mangas Depois disso, definimos que do produto de custo é igual ao esquema de pontos do Nu Mongoose Dentro disso, passamos o objeto no qual definimos o esquema. A primeira propriedade é title, que definimos para digitar como string, exigido como true, e também respeitamos o comprimento máximo a cem. Agora, a próxima descrição que queremos definir para digitar string requerida como verdadeira e seu comprimento mínimo é de 50 caracteres. Depois disso, precisamos de um vendedor que liste esse produto. Aqui, armazenamos o ID do vendedor, então digite o objeto no esquema de pontos do Mongoose Tipos de pontos ID do objeto, ref to user required to Agora, aqui você pode perguntar por que não usamos aqui a abordagem híbrida? Por que não incorporamos dados para o vendedor? Por que armazenamos o ID do vendedor. Aqui no front-end, nosso cartão de produtos terá a seguinte aparência. Na lista de produtos, não queremos exibir os detalhes do vendedor. Se quisermos exibir as informações do vendedor aqui , também podemos adicionar aqui o nome do vendedor e alguns detalhes obrigatórios, mas esse não é o caso aqui. Você precisa pensar assim: quando queremos vários dados em uma única chamada de API, vários dados significam dados de produtos em uma única chamada de API. Nesses dados, precisamos exibir os dados de referência ou não. Se, nesses dados, quisermos mostrar dados de referência , é melhor incorporar esses dados na coleção Com isso, nossa API não precisa executar uma consulta de preenchimento para cada dado incorporado Nesse momento, podemos usar a abordagem híbrida. Depois disso, precisamos de categoria. Agora me diga qual abordagem usamos aqui, incorporada ou de referência. Certo, usamos sua referência porque não queremos mostrar uma categoria com vários dados. Só precisamos de uma categoria para filtrar produtos. Então, novamente, usamos seu tipo de referência para esquema de pontos do Mongos dot ObjectID Refere-se à categoria e obrigatório para verdadeiro. Em seguida, temos o preço. Aqui, definimos o tipo como número, obrigatório como verdadeiro e médio como zero. Óbvio. Em seguida, duplicamos essa linha e alteramos esse preço para estoque, que é o número de produtos disponíveis no estoque Em seguida, temos imagens, que são a matriz, e também armazenamos o nome da imagem como string. O motivo pelo qual adicionamos uma matriz é porque os produtos podem ter várias imagens Como exigíamos que as imagens fossem verdadeiras. Isso garantirá que nosso produto tenha pelo menos uma imagem. Depois disso, temos as últimas avaliações de propriedades, que é a matriz do objeto de avaliação. Agora isso é interessante. Na matriz de avaliações, queremos vários objetos de avaliações. Temos que definir o esquema para esse objeto. Aqui, simplesmente passamos o objeto e, com isso, podemos definir o esquema para esse objeto, mesma forma que estamos fazendo anteriormente Neste objeto, queremos três usuários de informações que enviem esta avaliação. Então, eu me oponho, passamos type, esquema de pontos Mongos, tipos de pontos, dot Object ID, f para o usuário e required para Em seguida, para a revisão, precisamos de uma classificação, portanto, é do tipo para o número, e também precisamos do valor verdadeiro e médio de zero. Por fim, precisamos do comando, que pode ser uma string, mas não adicionamos aqui required a true porque nem todos os usuários adicionarão o comando. Eles só gostam de adicionar estrelas. Agora você pode ter dúvidas quando adicionamos um novo produto: é obrigatório Precisamos adicionar essas avaliações? Porque aqui passamos, precisamos de dois. Então, a resposta é não. Não precisamos adicionar avaliações obrigatórias. Isso é necessário para esse único objeto. Se tentarmos inserir um novo objeto de avaliação, ele deverá ter o ID do usuário e sua classificação. Caso contrário, não precisará disso. Basicamente, estamos adicionando um esquema para esse único objeto. Além disso, você pode perguntar: podemos incorporar os dados dos usuários aqui? Sim, podemos incorporar dados aqui, mas imagine que os usuários alterem o nome do usuário, então será muito difícil manter a consistência com esses dados e não se preocupar muito com o design do banco de dados Quase todas as empresas têm uma equipe para projetar o banco de dados, ou algum desenvolvedor sênior projetará o banco de dados. Estou apenas explicando por que usamos referência e por que não usamos a abordagem incorporada. Acho que isso esclarecerá suas dúvidas. Aqui, nosso esquema está completo. Agora podemos criar um modelo a partir disso. O produto de custo é igual ao modelo de pontos Mongoose. Aqui passamos o nome singular da nossa coleção, que é produto, e depois disso, passamos o esquema do produto e, por fim, exportamos esse modelo Portanto, as exportações do módulo são iguais ao produto. 120. Autorização baseada em função: Agora vamos criar uma API para criar um novo produto. Na pasta Routes, criamos um novo arquivo chamado products dot js. Agora temos que criar um novo roteador usando o Express. O SecStePress é igual a require Express. Em seguida, custo, o roteador é igual ao roteador express dot. Além disso, finalmente, temos que exportar esse roteador. As exportações de pontos do módulo são iguais às do roteador. Agora, vamos adicionar esse novo roteador no arquivo js index dot. Salve este arquivo, vá para o arquivo index dot js. Aqui, importamos rotas de produtos com custo igual ao exigido. Vamos para a pasta Routes e nesses produtos. Agora, na parte inferior, adicionamos app dot g. Aqui, definimos o prefixo, que é API slash E no segundo parâmetro, distribuímos os produtos, salvamos as alterações e voltamos ao nosso arquivo de rotas de produtos. Aqui, queremos criar uma API para adicionar novos produtos. Então, poste pontos do roteador, API e slide de apontar para frente. Aqui, garantimos que somente usuários logados possam acessar essa API. Então, podemos adicionar aqui o Osmalware. Veja aqui, eu recebo uma sugestão automática e também inserirá automaticamente o Omdalware na parte superior Agora, adicionamos a resposta da solicitação e a função de seta. Bom. Agora, antes de lidarmos com a forma de armazenar a imagem dos produtos, precisamos verificar se somente vendedores podem adicionar produtos, não usuários simples, apenas vendedores, e como podemos fazer isso? Usaremos middleware. Na pasta middleware, criamos um novo arquivo chamado cheseller Agora, como sabemos, o middleware é uma função. Definimos const, verificamos que o vendedor é igual à resposta da solicitação e a função next e arrow Nesta função, temos que verificar se a regra do usuário é vendedora ou não. Se não for vendedor, retornaremos o erro. Solicito que o usuário dot não esteja disponível, ou solicito que o papel dot user dot não seja igual ao vendedor, então retornamos o status de ponto da resposta, 403 para Xs dot JSON proibido E aqui passamos o objeto apenas com MeSetpperty em excesso Se você superar essa condição, somente então poderemos passá-las para o próximo middleware ou Agora vamos exportar essa função daqui. Portanto, as exportações de pontos do módulo são iguais a cheques do vendedor. Então, as mudanças. esse middleware após o middleware North na API de nossos produtos Vamos definir esse middleware após o middleware North na API de nossos produtos . Veja, novamente, a entrada automática funciona. Ótimo. Agora, aqui estão duas coisas para você. O primeiro está em nosso esquema de usuário, definimos apenas a opção de dois valores para a função Deixe-me mostrar o arquivo dot js dos usuários abertos. Aqui podemos ver que temos apenas usuário e administrador. Também precisamos adicionar aqui, vendedor, e salvar esse arquivo. Agora, a segunda coisa é: como podemos obter função de usuário na função de ponto de usuário da solicitação? Porque no usuário do ponto de solicitação, obtemos apenas os dados que passamos ao gerar o token. Lembre-se de que passamos apenas duas propriedades sublinhado ID e nome. Vamos ver isso também. Um ponto de usuário é roteado aqui na inscrição no final, C, passamos apenas o ID e o nome do sublinhado Aqui também temos que passar o papel. Vá para a nova função de usuário. Bom. Também no login no final, também adicionamos a função here e aqui temos que usar a função de ponto do usuário porque já temos o usuário aqui. Veja as mudanças. Agora, o que dizer autenticação baseada no Google e no Facebook. Também passamos apenas o ID e o nome do sublinhado. Também temos que aprovar a regra. Caso contrário, nosso medidor de adega apresentará erros. Então, no arquivo pothjs, onde precisamos alterar aqui, criamos essa função comum . Isso é bom. Veja, no topo, estamos encontrando o usuário, então isso é fácil para nós. Aqui na parte inferior, estamos gerando o token, então adicionamos here role à função de ponto do usuário. E pronto. Fizemos todas as alterações aqui. Salve as alterações e deixe-me fechar outros arquivos na API de produtos Basta retornar aqui o ponto de resposta. O vendedor SN está aqui. Vamos testar essa API. Em primeiro lugar, vamos adicionar a API de login no Postman porque acho que também não usaremos o cliente Tundar para produtos usaremos o cliente Tundar Em nossa coleção Cardwih, adicionamos uma nova pasta chamada usuários E adicionamos aqui uma solicitação chamada login de usuário. Primeiro, selecionamos e apontamos para o login do usuário da API. Certifique-se de que esse método esteja configurado para publicar. Agora, para os dados, eu simplesmente os copio do cliente Thunder de volta para o Postman, seleciono aqui o corpo, bruto e simplesmente os dados aqui e envio a solicitação Veja, aqui eu recebo um novo token, copio e para provar a API de produtos, você criará uma nova pasta no cartwdg Acho que temos que mudar permanentemente para o Postman. Quando comecei a pesquisar as pontuações na época, o recurso de upload de arquivos estava disponível na versão gratuita do cliente Tender. Mas agora o que podemos fazer mudar para Postman. Desculpe por isso. Aqui tivemos uma solicitação chamada criar um novo produto. Selecione o endpoint para cortar produtos pela API, solicitar é postado e enviar a Veja, aqui temos um erro, é necessário um token de autorização. Desculpe, não passamos o token no cabeçalho, vá para os cabeçalhos. Aqui, adicionamos autorização e, no valor, o que precisamos passar primeiro, adicionamos espaço de erro e colamos nosso token JWT aqui Agora vamos enviar essa solicitação. Veja, agora recebemos outra mensagem de erro, acesso negado somente para vendedores Então, para recapitular rapidamente, adicionamos um middleware para vendedor após o Othmdalware porque, por meio do orthomdalware, obtemos Se o token for verificado e a regra do usuário for o vendedor, somente a função Moware nos permitirá entrar na API do produto É assim que podemos realizar a autorização baseada em regras. Para entrar nessa API, precisamos transformar nossa conta corrente na conta do vendedor. Então, quando Mongo Di se tornar passe aqui na coleção do usuário, encontre sua conta pela qual você está logado e altere sua regra para vendedor Certifique-se de vendedor, não de vendedores. Agora temos que gerar um token de API de imprensa porque alteramos nossos dados. Envie a solicitação de login e copie esse token de volta para a API de produtos. Aqui no cabeçalho, substituímos o token antigo pelo novo token do espaço Barrer Agora vamos enviar a solicitação. Veja, aqui está o vendedor. Adorável. 121. Autorização personalizada baseada em funções: Agora, anteriormente, adicionamos a API de categorias. Aqui, não verificamos a função do usuário para adicionar uma nova categoria. Aqui também queremos. Somente o administrador pode adicionar categorias. Portanto, há duas opções para nós. Podemos criar um novo middleware, igual a esse middleware do vendedor de cheques, ou podemos criar um novo middleware que verifique Se nesse middleware, passarmos por admin, ele deverá permitir apenas Nós aprovamos o vendedor, então ele só deve permitir vendedores. Ambas as opções são boas. Realmente depende de você o que você quer escolher. Deixe-me mostrar a vocês dois. Para Admin, simplesmente copiamos o código inteiro do arquivo do vendedor de cheques e, na pasta middleware, criamos um novo arquivo chamado check admin dot gs e simplesmente colamos esse código Agora, aqui temos que fazer pequenas mudanças. Primeiro, alteramos o nome dessa função. Selecione isso e pressione F dois e escreva check admin. Depois disso, temos que alterar essa condição, função para administrador e também na mensagem de erro somente para administrador, e estamos prontos com nosso middleware de administração Podemos adicionar esse middleware em nossa API após o Osmalware da mesma forma que adicionamos Agora, deixe-me mostrar como podemos criar uma verificação geral de regras ou middleware É muito simples. Na pasta middleware, criamos um novo arquivo chamado check role dot js Aqui também, podemos simplesmente colar o mesmo código e alterar nome dessa função para verificar a regra. Agora você pode perguntar: como podemos passar uma regra nessa função? Porque, como sabemos, no lugar do middleware, basta adicionar essa função e chamá-la de função de retorno de chamada Aqui, podemos fazer simplesmente uma coisa. Podemos adicionar aqui mais uma função de seta. Então, após o sinal de igual, adicione o parâmetro de função e, em seguida, a função de seta. Portanto, antes de adicionar essa função de seta, para acessar esse retorno de chamada de resposta de solicitação, precisamos chamar a função de regra Jack Agora, depois de adicionar essa função de seta para acessar esse retorno de chamada de resposta de solicitação, temos que chamar a função de regra Jack Aqui, passamos a regra do usuário, digamos administrador. E depois disso, simplesmente ligamos mais uma vez. E com isso, podemos acessar esse retorno de chamada de resposta à solicitação Isso é chamado de função de ordem superior. Uma função de ordem superior é uma função que retorna outra função ou usa outra função como argumento. Aqui, estamos retornando essa função de retorno de chamada nesta função de regra de verificação Em uma sintaxe simples, é mais ou menos assim. Aqui está a função de regra de verificação e ela simplesmente retorna essa função de retorno de chamada É por isso que chamamos a regra de verificação pela primeira vez e depois precisamos chamá-la novamente para acessar essa função de retorno. Espero que isso esclareça suas dúvidas. Aqui, podemos substituir essa sequência de caracteres do vendedor pelo parâmetro da regra. E aqui, para uma mensagem de erro personalizada, convertemos esses códigos em retroescavações e, no local do vendedor, adicionamos a função do dólar e pronto Agora podemos usar esse middleware de verificação de regras personalizado com qualquer tipo de função Portanto, realmente depende de você se você gosta usar o check seller e o middleware check and mid, ou se você gosta de usar o middleware check rule Eu gosto de usar esse middleware de regras de verificação. Na API de produtos no local do vendedor do cheque, temos que chamar o middleware check Rule E aqui nós aprovamos a regra do vendedor. Esse vendedor de regras de verificação é o mesmo que o middleware do vendedor de cheques, ambos chamam isso de callback de resposta de solicitação Agora, para as categorias, também quero verificar a função de administrador. Na rota de categorias, queremos adicionar middleware para criar uma nova rota de categoria Agora, aqui está uma pergunta. Por que devemos adicionar o middleware de função de verificação Antes desse upload do multer ou depois dele? Certo, nós o adicionamos antes desse método de upload múltiplo porque primeiro verificamos a regra Se for administrador, armazenaremos a imagem do ícone em nosso servidor. Adicionamos o middleware Jack Roll após o método ulter, então ele primeiro armazenará a imagem em nosso servidor e depois verificará Então, adicionamos o middleware check roll antes disso e passamos aqui a função admin Além disso, antes de verificar o middleware Roll, precisamos adicionar o middleware Auth porque, sem isso, como podemos obter as informações do usuário na solicitação dot user na Salve as alterações e vamos experimentar nossa API de produtos. Envie esta solicitação e aqui eu recebo um erro. Deixe-me verificar. É um erro na verificação do arquivo de função. Oh, desculpe, eu esqueci de remover essa chamada de função. Veja as alterações e vamos enviar a solicitação novamente. Veja, aqui está o vendedor. Isso significa que nosso middleware está funcionando. Então é assim que podemos usar esse middleware de regras de verificação para qualquer tipo de autorização baseada em regras 122. Como lidar com várias imagens de produtos: Antes de salvar os dados reais dos produtos no banco de dados, vamos criar um método de carregamento múltiplo para armazenar imagens de vários produtos Então, aqui, o vendedor pode carregar no mínimo uma imagem ou no máximo oito ou dez imagens. Então, a partir da rota de categorias, eu simplesmente copio esse filtro de arquivo de armazenamento, carrego as variáveis e as colo antes da API de nossos produtos. Bom. Agora, primeiro de tudo, precisamos importar o pacote Multar Portanto, custar um multer é igual a exigir um multer. Além disso, podemos remover essa importação de middleware do jag seller. Nós não precisamos disso. Agora, aqui, temos que fazer algumas mudanças. Primeiro, alteramos o destino para fazer o upload de produtos slash Com isso, podemos garantir as imagens dos produtos sejam separadas do ícone da categoria. E, como sabemos, multer não cria um diretório sozinho, então precisamos criá-lo Na pasta de upload, criamos uma nova pasta chamada produtos. Aqui, armazenaremos a imagem de nossos produtos. Esses são pequenos detalhes que precisamos manter em mente ao trabalhar com nod Jas À medida que você trabalha mais em nod Jaz, você saberá todas Não se preocupe com isso. Agora, depois disso, o nome do arquivo está ok. O filtro de arquivos também está bom. Se você também quiser armazenar vídeos , precisamos adicionar esses tipos de MM na matriz de tipos permitidos. Por enquanto, não queremos isso, e o limite de tamanho é de dois MB, o que também é bom. Aqui você pode perguntar que esse limite de dois MB é para todas as imagens de tamanho combinado. Não, é para cada tamanho de imagem, não para tamanho combinado. Agora vamos adicionar esse método de upload nessa API. Após o middleware jackrll, adicione o ponto de upload, queremos armazenar várias imagens, para que possamos usar aqui a matriz ponto único é para um único arquivo e a matriz de pontos é Agora, aqui, temos que passar o nome do arquivo para essas imagens. Aqui, nós o configuramos para imagens. Então, a partir do front-end, eles precisam enviar todas as imagens dos produtos em imagens únicas preenchidas. Veremos que, ao provarmos essa API, agora, depois de passar o nome do campo, podemos ultrapassar o limite dos arquivos. Qual é o número máximo de arquivos que queremos armazenar? Para aplicativos de comércio eletrônico, oito é mais do que suficiente, mas você também pode ajustar essa contagem de acordo com suas necessidades Além disso, se você não quiser definir o limite máximo , não precisamos passar o segundo parâmetro. Mas aqui queremos oito imagens. Agora, como vimos, anteriormente, obtemos as informações do arquivo no arquivo de pontos da solicitação porque há um único arquivo. Mas aqui estamos lidando com vários arquivos, então obteremos os dados desses arquivos no plural de arquivos de ponto da solicitação Com isso, buscaremos cada nome de arquivo no banco de dados. Além disso, podemos criar aqui uma função ultter comum, mas isso criará confusão desnecessária É por isso que deixamos como está. Agora, na próxima lição, armazenaremos dados dos produtos no banco de dados. 123. Crie novos produtos: Vamos armazenar os detalhes do produto no banco de dados. Então, primeiro de tudo, neste retorno de chamada, obtemos todos os campos que vamos passar no corpo do ponto da solicitação Portanto, o custo dos pacotes CLI é igual ao corpo do ponto da solicitação. Agora, primeiro de tudo, neste corpo, temos título, descrição, categoria, que é o ID da categoria, preço e estoque. Agora, depois disso, temos que criar uma matriz de imagens, que é a matriz de nomes de imagens, e como podemos obter isso? Então, obtemos todos os detalhes das imagens na matriz de arquivos de pontos da solicitação, e cada dado da imagem está disponível no objeto desta forma. E aqui temos um nome de arquivo. Então, podemos fazer isso. O custo das imagens é igual aos arquivos de pontos solicitados dot MAP. Aqui obtemos a função de seta de cada objeto de imagem e simplesmente retornamos o nome do arquivo de pontos da imagem. Esse nome de arquivo é o que geramos na parte superior. Agora, por esse método de mapa, obtemos a matriz de nomes de imagens. Além disso, às vezes os vendedores se esqueciam de adicionar imagens. Podemos colocar aqui a condição se comprimento dos pontos das imagens for igual a zero. Se for verdade, simplesmente retornaremos status de ponto de resposta, JSON de 400 pontos E aqui passamos erro no objeto com propriedade confusa. É necessária pelo menos uma imagem. Agora, aqui temos todas as informações. Vamos armazenar rapidamente essas informações na coleção de produtos. Custo, novo produto é igual a novo produto. Veja, aqui obtemos autorização, produtos do modelo, bons, e aqui passamos um novo objeto de produto. Neste objeto, título a título, e como sabemos, se a propriedade do objeto e o nome do valor forem iguais, podemos simplesmente removê-los. Ambos funcionam da mesma forma. Em seguida, descrição até descrição, categoria, preço, estoque, imagens. E agora, finalmente, temos que armazenar o vendedor. Como podemos conseguir esse vendedor? Certo, podemos usar o ID de sublinhado ponto do usuário do ponto da solicitação porque nosso Osmitalware está definindo os detalhes de uso no usuário do ponto da Vamos contar os preenchimentos para ver se estão faltando preenchimentos ou Um, dois, três, quatro, cinco, seis e sete. Além disso, no esquema do produto, temos uma, duas, três, quatro, cinco, seis , sete e 80 avaliações, que não adicionaremos agora, então estamos no caminho certo Agora, vamos salvar esses dados. Aguarde o novo ponto c do produto para usar o await, temos que fazer com que essa função esteja agora na parte inferior, vamos retornar o status do ponto de resposta para 01 ponto GSN, e aqui enviamos os dados dos novos Salve as alterações, menos é essa API. Isso é realmente empolgante. Na pasta de recursos, adicionei projeto a pasta, e nela, você obterá a pasta Produtos e, dentro dela, adicionei imagens de produtos por categoria, e você também obterá o arquivo GSN de pontos de dados No qual adicionei título, descrição e todos os outros detalhes. Abra esse ponto de dados JSNfle no código VS. Veja aqui, eu adicionei o nome da categoria na parte superior e, na matriz de produtos, adicionei todos os dados dos produtos com título, descrição , preço, estoque, imagem é nome, para que você possa pesquisar imagem por isso. O motivo pelo qual eu não adiciono aqui o ID da categoria porque para cada ID de categoria pode ser diferente porque, anteriormente, adicionávamos a categoria manualmente. Aqui está minha categoria de smartphone e aqui está o ID. Você pode compará-lo com o ID da sua categoria. Não pode ser o mesmo. Copie este ID, vá para Postman, aqui, primeiro vá para os dados do formulário Aqui, simplesmente adicionamos a categoria-chave e, em valor, além do ID da categoria dos smartphones. Em seguida, temos que adicionar título, descrição, preço e estoque. Eu copio todos esses detalhes um por um do arquivo JSON e os colo aqui. Primeiro, selecione o título , cole aqui, descrição. O preço é 1299 e o estoque é oito. Então, passe a descrição, preço 1299, que é USD e o estoque até oito Agora precisamos adicionar somente imagens para este produto. Na parte inferior, adicionamos outras imagens importantes. Aqui, selecionamos o tipo para arquivo e agora selecionamos as imagens do iPhone 14. Então vá para a pasta Produtos, smartphones e vamos para a pasta iPhone 14 Pro. Aqui, selecione todas as imagens 1-4. Agora vamos enviar esses dados. Veja, aqui temos os dados desses novos produtos. Aqui temos a categoria do vendedor, os nomes das imagens na matriz e também em nosso back-end, na pasta de upload de produtos, obtemos essas imagens. Fizemos um ótimo trabalho. Estou adicionando todos esses detalhes de produtos no meu banco de dados. Quando executamos a consulta do produto GD com paginação , obtemos Você também pode adicionar todos os produtos em seu banco de dados, se quiser. Caso contrário, você pode simplesmente pular essa parte. Agora eu copio o próximo título do produto, colo aqui. Não toque no ID da categoria porque ainda estamos na mesma categoria. Descrição. Cole aqui e preço é 399 e o estoque até 50 Agora vamos selecionar imagens para Samsung a 54. Envie essa solicitação. Bom. Assim, você pode adicionar todos os produtos ou pelo menos dez produtos. Basta alterar o ID da categoria ao alterar a categoria do produto. Sei que isso é chato, mas podemos usar esses dados para testar nossa API get products Então, coloque uma música relaxante e crie esses produtos. Eu também estou fazendo isso, até a próxima lição. 124. Obtendo todos os dados de produtos: Então, na lição anterior, adicionamos produtos no banco de dados. Veja, eu adicionei todos os 24 produtos no banco de dados. Agora vamos obter esses produtos por meio da API, porque é assim que os dez primeiros obterão esses dados. Então, após a API de postagem, adicionamos o ponto Get do roteador e apontamos para a barra frontal Agora, aqui não adicionamos nenhum middleware porque queremos que qualquer usuário possa ver todos os produtos, não apenas os usuários logados Então, adicionamos diretamente aqui retorno de chamada final com solicitação e resposta Bom. Agora, aqui, primeiro obtemos todos os produtos, então const products é igual a products dot find Não passamos aqui nenhuma condição porque queremos todos os produtos. E aqui temos que adicionar await para a consulta. E, para aguardar, adicionamos aqui async e, no final, simplesmente retornamos o ponto de resposta JCNPducts simplesmente retornamos o ponto de resposta Então, com as mudanças, vamos testar essa implementação. No carteiro, criamos uma nova solicitação na coleção de produtos, produtos G A. Aqui, inserimos o endpoint para APIs Products, selecionamos Method to G e simplesmente enviamos a solicitação Veja aqui que obtemos todos os dados dos produtos em uma matriz. E nessa matriz, obtemos objeto para cada produto com todos os campos. Agora, minha pergunta é: precisamos de todos os detalhes aqui? Podemos reduzir o tamanho dos dados que estamos enviando do back-end? Se passarmos o mouse sobre esse tamanho, obteremos o tamanho da resposta com cabeçalho e corpo separados Observe o tamanho atual dos dados de 14,39 KB. Agora, deixe-me mostrar como nossa página de produtos deve ficar no front-end. Veja, aqui temos a lista de todos os produtos, e é quase semelhante à Amazon ou a qualquer aplicativo de comércio eletrônico Se você prestar atenção ao cartão de produtos, realmente não precisamos de todos os detalhes. Vamos escrever os preenchimentos que queremos exibir no cartão de produtos O primeiro é o ID para identificar o título do preço do produto, estoque se os produtos estiverem em estoque, só então exibimos o botão de ir até o cartão. Em seguida, é claro, exiba a imagem, que será a primeira imagem da matriz de imagens. Em seguida, precisamos de detalhes sobre avaliações, e isso é tudo. Em nossa consulta, adicionamos método select para selecionar os preenchimentos. Agora, em vez de adicionar o nome de todos os preenchimentos, podemos escrever quais preenchimentos não queremos Para isso, basta adicionar ou subtrair antes do nome do campo. Não precisamos de descrição. Além disso, não queremos exibir o vendedor. Também não é categoria, e não queremos sublinhado V. Não é necessário. Aqui estão as mudanças e dê uma olhada. Vamos enviar a mesma solicitação novamente e verificar o tamanho. Veja, ele é reduzido em um terço porque a descrição tem mais dados do que qualquer outro campo, e é por isso que removemos preenchimentos desnecessários Agora vamos tornar esses dados mais restritos. Aqui também não queremos todas as imagens. Só queremos que a primeira imagem apareça na capa. Agora, existem duas soluções para isso. primeira é que podemos criar um preenchimento separado em nosso modelo de produtos, como imagem de exibição ou imagem de capa. Quando estivermos armazenando o novo produto, nesse campo, armazenaremos o nome da primeira imagem. Essa é uma solução. Outra solução é extrair o nome da primeira imagem de cada produto e adicioná-la ao mesmo objeto de produto que estamos enviando do back-end. Dessa forma, não temos problemas de duplicação de dados. Veja que as duas soluções são ótimas. Aqui, não podemos aplicar a primeira solução porque adicionamos todos os produtos. Vou te mostrar a segunda solução, que também é ótima. Primeiro de tudo, aqui escrevemos o mapa de pontos dos produtos. Agora, aqui estamos obtendo um único objeto de produto e a função de seta. Agora, como sabemos, o que quer que retornemos dessa função, será o item da nova matriz. A lógica é que retornaremos todos os dados que temos em um único produto e, em seguida, não queremos enviar a matriz de imagens, então substituiremos essa propriedade de imagens pelo primeiro elemento de imagens. Queremos uma matriz de imagens, quando não adicionamos uma nova propriedade com o mesmo nome, podemos fazer com que ela exiba uma imagem ou outra coisa, mas aqui não queremos enviar uma matriz de imagens. É por isso que estamos dando o mesmo nome. Deixe-me te mostrar. Aqui retornamos o objeto. Dentro disso, em primeiro lugar, adicionaremos todas as propriedades de um único operador de ampla distribuição de produto. Nós adicionamos todas as propriedades de um único produto como ele está. Depois disso, para substituir a propriedade images, adicionamos aqui imagens e aqui como valor, definimos o ponto do produto Images, primeiro elemento, que é o índice zero. Feito. Agora, esse método de mapa retornará uma nova matriz com todos os objetos de produto único atualizados. Nós o armazenamos em variáveis chamadas produtos atualizados. No local dos produtos, simplesmente devolvemos os produtos atualizados em resposta ao ponto JSO Salve as alterações e vamos ver se estamos entendendo corretamente ou não. Veja, aqui estamos obtendo um objeto estranho e no final de cada objeto, estamos obtendo essa propriedade de imagens, estamos obtendo essa propriedade de imagens que significa que nosso método de mapeamento está funcionando Mas por que estamos recebendo esse objeto estranho. Vamos simplesmente const dot log nesta matriz de produtos e Al na resposta dot json, enviamos novamente o objeto products Salve as alterações e vamos enviar a solicitação. Veja, aqui obtemos a matriz de produtos regulares e voltamos ao código VS, abra o terminal, e veja aqui que estamos obtendo a mesma matriz de produtos. Agora vamos tentar mover essa linha do console no método map. E no lugar dos produtos, nós consolamos o registro de pontos do único produto. Salve as alterações e vamos enviar a solicitação. Um terminal, S, aqui temos novamente o objeto normal de produto único. Acho que quando adicionamos o operador de propagação, quando obtemos as propriedades desse objeto, em vez de um único produto, nós o envolvemos no objeto e adicionamos aqui o operador de propagação. Faça as alterações e envie a solicitação. De volta ao VSCode Veja, aqui estamos pegando esse objeto estranho. O que está acontecendo aqui. Então, isso acontece quando estamos obtendo dados com mangas, não obtemos um objeto Javascript simples. Obtemos o objeto de documento Mongoose, que inclui os dados brutos do documento no cão e propriedades e métodos adicionais como sublinhado em dólar, sublinhado, dólar é um novo fornecido pelo mongoose Agora, o problema é que não queremos essas propriedades e métodos. Quer um objeto JavaScript simples do banco de dados, não um objeto de documento de manga Para resolver isso, basta adicionar uma propriedade no final dessa consulta. Isso remove todas as propriedades específicas extras das mangas. Agora podemos devolver aqui produtos atualizados na resposta. Salve as alterações e dê uma olhada. Envie esta solicitação e veja, aqui substituímos a matriz de imagens pelo nome da primeira imagem e, se verificarmos o tamanho dos dados, reduzimos mais. Adorável. É assim que depuramos e encontramos o erro Agora, aqui está uma coisa também. Aqui estamos enviando uma matriz completa de avaliações pois temos um objeto que tem detalhes de uso, a classificação e também um comentário. Atualmente, para todos os produtos, não temos avaliações. É por isso que não podemos ver dados tão grandes. Também no front-end, queremos apenas mostrar a média de classificação e o número total de avaliações. Também podemos substituir a matriz de avaliações por apenas duas propriedades. Deixe-me te mostrar. Removemos esse console. Nós não precisamos disso. Em primeiro lugar, crie um novo número de avaliações de custo variável igual ao produto dot rev dot LNT Aqui, Jack, você tem resenhas ou resenhas. Eu tenho uma avaliação, então continuo com a avaliação de pontos do produto. Agora, como podemos encontrar a média? A média é basicamente, temos que somar todos os números de classificação e dividi-los pelo número total de avaliações. Definimos uma nova variável Cast sum of ratings é igual a now para somar as classificações, usamos reduce, que é o método de matriz. Revisão de pontos do Badu, que é redução de pontos de matriz. Agora, aqui temos dois parâmetros. O primeiro é total, ou podemos dizer soma, e o segundo é o valor atual, que é uma única revisão. E o que você quer fazer nesse retorno de chamada? Basta somar mais a leitura dos pontos de avaliação. Depois disso, no segundo parâmetro, você pode definir o valor padrão dessa soma, que definimos como zero. Esse método reduzido usará dois argumentos. primeira é a função de retorno de chamada, que usamos para fazer algumas operações matemáticas, e a segunda é o valor padrão do parâmetro sum Agora temos a soma das avaliações, classificação média de custo é igual à soma da classificação, dividida pelo número de avaliações. Agora, aqui está uma coisa. Se o número de avaliações for zero, o que acontecerá? 0/0 nos dará indefinido. Se o número de avaliações for zero, ASir ou operador um Isso evitará esse erro. Agora, vamos substituir a matriz de revisão por essas duas propriedades. Depois das imagens, retornamos a avaliação ao objeto, ao número de avaliações, ao número de avaliações ou, para simplificar, removemos a segunda propriedade, a classificação média à classificação média. Salve as alterações e dê uma olhada. Envie a solicitação novamente e veja como podemos analisar como objeto. Então, a partir da consulta, enviamos apenas o que o front-end precisa. Então é assim que temos que pensar quando estamos enviando dados do back-end. 125. Paginação ou consulta infinita: Agora, atualmente, estamos enviando todos os 24 produtos do banco de dados. Imagine que, em nosso banco de dados, temos 100 ou mil produtos , enviar todos os produtos em uma única resposta tornará nossa API lenta. Diga-me o que devemos fazer nessa situação? Certo, podemos enviar dados página por página, para que nosso front-end possa implementar recursos paginação ou rolagem infinita Já vimos isso na Seção sete. Vamos implementar paginação ou consulta de rolagem infinita. O back-end é o mesmo para os dois recursos. Em primeiro lugar, obteremos o número da página atual a partir do parâmetro de consulta e como podemos acessá-lo? Certo, por solicitação, consulta de pontos. A página de custo é igual à página de pontos de consulta da solicitação. Agora, essa página de ponto de consulta de ponto de solicitação é string porque tudo o que obtivermos do parâmetro de consulta, será string. Temos que converter esta página em número inteiro, envolvê-la com parênteses e Em seguida, temos que definir quantos dados de produtos queremos enviar em uma página. Portanto, const por página é igual a oito. Agora, precisamos simplesmente adicionar dois métodos em nossa consulta. O primeiro é o dot Skip e aqui passamos entre parênteses menos um por página Se a página for uma, então um menos um, zero em oito, que também é zero Nossa consulta ignora zero produtos. Se a página for duas, então dois menos um, que é um em oito, que é oito Portanto, nossa consulta Ignore os primeiros oito produtos. Agora, depois de Skip, temos que adicionar a propriedade Limit e, nela, passamos por página Então, limite é quantos dados queremos buscar do banco de Simples assim. Vamos testar essa implementação, enviar a solicitação. Veja, nós só temos oito produtos. Agora você pode perguntar: não passamos a página no parâmetro de consulta. Ainda assim, estamos recebendo oito produtos. Sim, estamos recebendo oito produtos porque essa página de ponto de consulta por pontos de solicitação não está definida. Portanto, o método skip ignorará zero itens e, em seguida, definimos o limite para oito É por isso que estamos recebendo oito produtos. E se quisermos tornar essa consulta mais personalizada para o front-end? Imagine que nosso front-end queira aumentar os produtos por página no parâmetro de consulta Suponha dez produtos em uma única página. Nós podemos fazer algo assim. Em vez desse Ed codificado, obtemos o parâmetro de consulta request query dot perpge. Novamente, nós o convertemos em inteiro usando parse integer. Mesmo que o front-end não queira passar por parâmetro por página, passe aqui o valor padrão, ou seja, o operador oito. E podemos lidar com essa página adicionando operador e o valor padrão será um. Veja as mudanças e vamos obter os dados da página dois. Portanto, colocamos um ponto de interrogação no final da URL para passar o parâmetro de consulta. A página é igual a dois. Além disso, passamos por página para dez e enviamos a solicitação. Veja, nossa consulta, pule primeiros dez registros e depois envie a página dois, que é de 11 a 20 produtos Agora, aqui está uma coisa. No front-end, muitas vezes eles precisam mais detalhes, como o número total de produtos. Com isso, eles decidirão quantas páginas precisam exibir ou quantas vezes podem obter os dados do back-end. Então, eles querem o número da página atual e alguns outros detalhes. Vamos obter rapidamente esses detalhes e passá-los na resposta. Em primeiro lugar, após esses produtos de atualização, podemos fazer algo assim. O custo e o total de produtos são iguais aos documentos aguardados do produto Isso contará todos os produtos. Agora, depois disso, também podemos contar o número total de páginas, o custo, total de páginas é igual ao total de produtos, dividido por página. Suponha que temos 50 produtos e por página é oito, então obtemos 6,25, o que significa seis páginas completas, e precisamos de mais uma página para exibir dois produtos Então é melhor, sempre selamos esse número. Para isso, precisamos apenas envolver essa equação com a função matemática de pontos SL. Isso converterá esses 6,25 em sete. Agora, no local de envio dessa matriz de produtos atualizada, passamos aqui o objeto. Primeiro atribui os produtos aos produtos atualizados, total de produtos, ao total de produtos, ou também podemos remover isso. Além disso, passamos o total de páginas. Além disso, podemos enviar página, que é a página atual, e postar por página por página. Eu adicionei aqui todas as informações, mas você pode adicioná-las de acordo com suas necessidades. Salve as alterações e vamos enviar a mesma solicitação. Veja, obtemos uma variedade de produtos e, com isso, obtemos esses detalhes. Isso é tudo o que precisamos fazer para paginação ou consulta infinita 126. Como enviar produtos por categoria: Ao adquirir produtos, talvez queiramos obter apenas produtos por categoria. Para isso, não precisamos criar uma nova API. Também podemos simplesmente implementar isso nessa consulta. Primeiro, obtemos o nome da categoria no parâmetro de consulta, a consulta de custo é igual à categoria de ponto da consulta de solicitação. Se não passarmos na categoria, passaremos aqui ou null Agora, depois disso, para consulta, adicionamos a variável let query. Nós o configuramos como objeto vazio. Aqui, passamos esse objeto de consulta nesse método fino. Agora podemos preencher essa consulta de acordo com nossas necessidades. Essa consulta é o objeto de comparação. Passamos aqui se a categoria de consulta de condição estiver disponível e, em seguida, primeiro precisamos adicionar a propriedade da categoria ao ID da categoria nesse objeto de consulta. Agora, se do front-end obtivermos diretamente o ID da categoria, poderemos passar esse ID diretamente no objeto de consulta. Mas, na maioria das vezes, obtemos nome da categoria do front-end. Temos que encontrar o ID da categoria em nosso banco de dados. A categoria de custo é igual a um ponto da categoria de peso Fine Vn. Aqui, passamos o nome do objeto de comparação para a categoria de consulta. Certifique-se de importar esse modelo de categoria na parte superior. Portanto, a categoria de custo é igual à exigência. Aqui está uma pasta na categoria de modelos. Agora, e se não financiarmos a categoria? Aqui, verificamos se a categoria não está disponível. Simplesmente retornamos a resposta com o código de status 404, não encontrado no método Jason, passamos o objeto com a propriedade da mensagem, categoria, não No final, simplesmente definimos que categoria da consulta é igual ao ID do sublinhado do ponto da categoria Agora, nosso objeto de consulta se parece com isso. Se passarmos isso em nosso método fino , ele atuará como objeto de comparação. Agora, vamos testar isso do Mongoi become pass, vá para a coleção de categorias, copie qualquer categoria Suponha que eu copie a categoria de relógios inteligentes. Agora, de volta ao Postman na URL, adicionamos outro parâmetro de consulta e a categoria é igual aos relógios inteligentes Certifique-se de escrever o mesmo nome que temos na coleção de categorias e enviar essa solicitação. E aqui temos uma matriz vazia. Oh, aqui passamos que a página é igual a dois, e nesta categoria, não temos muitos dados que possamos mostrar na página também. Então, mudamos essa página para uma e enviamos a solicitação. Veja, aqui temos todos os produtos de relógios. 127. Enviando produto por pesquisa: Em nosso aplicativo, o usuário também pode pesquisar os produtos e querer ver todos os produtos de acordo com sua pesquisa. Também podemos implementar isso nessa única consulta. Não é obrigatório adicionar todos os recursos nessa consulta, mas estou mostrando a prática do mundo real Depois dessa categoria, a pesquisa de consulta de custo é igual ao ponto de consulta de solicitação SRG ou a definimos como Null Após essa condição de categoria, adicionamos outra condição if, pesquisa de consulta está disponível e definimos outra propriedade no objeto de consulta. O título do ponto de consulta é igual ao objeto. Aqui adicionamos dollar jx, para query surge e para tornar essa consulta insensível a maiúsculas e minúsculas, passamos outra propriedade, dollar options, para a string I. Além disso, na parte inferior, nos produtos deste tutor, temos que passar o objeto de consulta no método count document Esqueci de passar na lição anterior e pronto Salve as alterações e dê uma olhada. Adicione aqui outro parâmetro de consulta e o surto é igual a aqui adicionamos o aplicativo e enviamos a solicitação. Veja, obtemos apenas um dado porque, em seu título, ele tem Apple. É assim que podemos personalizar esse Gtquery para obter todos os produtos Além disso, noto uma coisa. Armazenamos com sucesso as imagens de nossos produtos na pasta do servidor, mas não conseguimos acessá-las. Precisamos definir esses arquivos estáticos como fizemos para categorias de imagens. No arquivo index dot js, após essa categoria static, adicionamos app dot ug Aqui, adicionamos o prefixo para o caminho do arquivo estático. Nós enviamos produtos. Agora, depois disso, usamos o Express dot static Middleware para compartilhar os arquivos estáticos do servidor e, dentro dessa função, temos que passar o nome da pasta que queremos Então, carrega produtos. Lembre-se de que esse é o prefixo do URL e esse é o caminho da pasta de nossos arquivos estáticos e pronto 128. Exercício — obtendo dados de um único produto: Agora, quando no front-end, alguém clica no cartão de produtos, devemos mostrar a eles todos os detalhes sobre esse único produto Aqui está o exercício para você. Você precisa definir uma nova API para obter detalhes únicos do produto. Portanto, nossa API deve ter essa aparência. Produtos da API Slash, ID do produto Slash. Este ID, você precisa encontrar o produto. Além disso, tente obter dados reais do vendedor, como ID do vendedor, nome do vendedor e ID de e-mail, não um simples ID do vendedor. Tente resolvê-lo e, se você esqueceu de preencher , assista às aulas de seis e sete de preenchimento e tente resolvê-lo Então, espero que você resolva esse exercício ou tente resolver isso. Não se preocupe se você cometer um erro ou travar em algum momento. É a parte do aprendizado. Eu também costumava ficar muito tempo onde aprendia nodo pela primeira vez. Não se preocupe com isso. Agora vamos ver a solução. Então, escrevemos o roteador dot Gt. O que passamos na URL? Como podemos saber quais detalhes do produto queremos? Certo. Aqui, adicionamos o ID da coluna como parâmetro raiz, e esse é o ID exclusivo de um único produto. Agora, novamente, não adicionamos aqui middleware porque qualquer usuário pode ver detalhes de um único produto Nós passamos diretamente a função de retorno com solicitação e resposta Em primeiro lugar, precisamos desse ID, então Const ID é igual ao ID de ponto da VM da solicitação Agora, por esse ID, podemos encontrar esse produto. Portanto, o produto C é igual a aguardar a localização do ponto do produto por ID. Aqui, passamos o ID do produto. Também tornamos essa função assíncrona. Depois disso, podemos colocar a condição I que o produto não está disponível e, em seguida, retornamos a resposta com código de status 404 pontos JSNObject com a propriedade da mensagem, produto, não com a propriedade da mensagem, produto, Agora, se obtivermos o produto do banco de dados , simplesmente responderemos ao ponto Json deste produto Diga as mudanças e vamos testar essa API. Copie essa primeira ID do produto porque precisamos dela. No carteiro, criamos uma nova solicitação chamada Obter produto único Bom, selecione o produto URL API. E aqui colamos nosso ID do produto. Verifique se a solicitação é G e envie a solicitação. Veja, aqui temos os dados completos de um único produto. Agora, se passarmos aqui algum ID aleatório e enviarmos a solicitação , não obteremos os dados. E se verificarmos nosso terminal, veremos que nosso aplicativo travou Isso acontece porque não lidamos com erros em nossa API. Não se preocupe, faremos isso na próxima seção. Atualmente, temos que reiniciar esse aplicativo com o mod de nó. Vamos passar novamente o ID original e enviar a solicitação. Agradável. Agora, aqui temos um pequeno problema. Na página única de produtos, queremos mostrar as informações do vendedor como nome e e-mail. Mas aqui temos o ID do vendedor, então temos que preencher esses dados da coleção do usuário Além disso, não queremos que essa categoria seja preenchida. Outras coisas estão bem. Em primeiro lugar, após o método fino, passamos o dot populate. No primeiro parâmetro, passamos qual campo queremos preencher. Certo, é vendedor, em quais dados queremos preencher ID de sublinhado, nome, e-mail Agora, também, queremos preencher o usuário, que estará disponível na matriz de avaliações Aqui, temos que preencher os dados do NASD. Também é muito simples. Passamos por outro método de preenchimento. No primeiro parâmetro, adicionamos review, que é a matriz para acessar o usuário, temos que escrever dot user. Agora, no segundo parâmetro, queremos novamente os mesmos preenchimentos. ID de sublinhado, nome e e-mail. Bom. Salve as alterações e dê uma olhada. Envie a solicitação. Veja, agora recebemos o objeto do vendedor com ID, nome e e-mail preenchidos. Atualmente, não temos avaliações. É por isso que não podemos ver isso. Além disso, esquecemos de remover esse preenchimento de categoria. No final, passamos o método de seleção de pontos e aqui menos a categoria e menos o ID do sublinhado Então, as mudanças e dê uma olhada. Envie esta solicitação, C, removemos a categoria e sublinhamos a propriedade de sublinhado V. É assim que o node js é simples. No começo, você acha que é difícil. Mas se você fizer a implementação passo a passo, poderá dominá-la adequadamente. E é por isso que eu explico o código linha por linha. Agora, na próxima lição, criaremos uma API para excluir um único produto 129. Exercício. — Excluindo o produto: Agora vamos criar uma API para excluir um único produto. Então, aqui escrevemos router dot delete. Aqui, obtemos novamente o ID como parâmetro de rota. Agora, aqui precisamos de middleware ou não. Certo, precisamos de middleware porque somente usuários logados podem excluir o produto, e também queremos obter detalhes sobre Em primeiro lugar, passamos pelo middleware Oath. Em seguida, passamos a função de retorno de chamada da API com solicitação e resposta Agora, primeiro, obtemos ID do produto a partir do parâmetro de rota. Custo, a ID do produto é igual à ID de ponto dos parâmetros da solicitação. Agora temos que encontrar o produto a partir desse ID. O produto fundido é igual a aguardar a localização do ponto do produto por ID, na medida em que passamos a ID do produto Agora, a partir dessa consulta, precisamos apenas do ID do vendedor. Adicione o método de seleção, e aqui passamos os vendedores preenchidos e, também na parte superior, ativamos essa função Agora colocamos aqui a condição para que o produto seja encontrado ou não. Então, simplesmente copiamos essa condição da API anterior e a colamos aqui. Bom. Agora, se encontrarmos um produto , verificamos que o usuário é administrador ou o usuário é o vendedor desse produto. Escrevemos I request user dot rule é igual a admin ou request dot user, dot underscore ID é igual ao produto, dot seller Se alguma dessas condições for verdadeira, poderemos excluir esse produto. Agora a pergunta é: como podemos remover esse produto? Neste objeto de produto, que obtemos do banco de dados, o Mongoose também passa um método com ele, que é dot delete E é isso. Com isso, o produto será removido do banco de dados. Além disso, usamos aqui um método de exclusão porque anteriormente obtemos o produto do banco de dados. Se precisarmos remover diretamente esse produto , usaremos o método find by ID e delete. Além disso, temos que adicionar aqui uma espera porque essa é uma operação assíncrona Agora, depois disso, simplesmente retornamos ponto de resposta Json com propriedade da mensagem, produto excluído com sucesso Agora, atualmente, comentamos essa lógica de exclusão para verificar essa implementação. Nós o habilitaremos depois de algum tempo. Agora, se essa condição não for verdadeira, retornaremos aqui a resposta com o código de status 403, 44 Biden dot Json com propriedade mesa, Somente o administrador ou o vendedor podem excluir este produto. Agora vamos experimentar essa implementação, copie qualquer ID de produto da nossa lista de produtos. Eu copio esse último ID, agora no post win, crio uma nova solicitação chamada tilt, um produto nesse método para excluir, aqui escrevemos URL, produtos de API, e aqui passamos nosso ID do produto e garantimos que o método seja excluir e enviar a solicitação Desculpe, também precisamos enviar o token JWT no cabeçalho, acessar a API de login, fazer login com seus dados de usuário, quem é o vendedor desse produto Veja, aqui eu pego a chave JWT, copio isso e, em excluir API, vamos aos cabeçalhos e adicionamos aqui a autorização na Como valor, passamos erro, espaço e colamos a chave JWT aqui Agora, envie a solicitação. Veja, aqui o acesso é negado, então não entramos nessa condição I. É por isso que recebemos esse erro. O problema está nessa condição, vamos simplesmente registrar pontos no console. Copie essa primeira condição e cole-a aqui, vírgula, copie a segunda condição e cole-a aqui Diga as alterações e, novamente, envie a solicitação. Agora, voltando ao código do VS, abrimos um terminal aqui para a primeira condição, obtemos false, o que é verdadeiro porque não somos administradores. Depois disso, por uma segunda condição, também nos tornamos falsos. Por que essa conta é vendedora desse produto. Selecione separadamente, consulte o log de pontos, essas duas propriedades. Remova essa primeira condição e, no lugar dos iguais, adicionamos Veja as mudanças e, novamente, envie a mesma solicitação de volta para o código VS e, no terminal, veja, primeiro obtemos o ID do objeto em string e, em seguida, obtemos o novo ID do objeto, que é o ID do objeto do Mongoose É por isso que a string e o ID do objeto não coincidem. Então, ou temos que converter isso em ID de objeto ou podemos converter isso em string. Ambos funcionarão. Então, convertemos esses dois em string. Em JavaScript, temos o método de string de dois pontos para converter dados em string. Passe essa sequência de dois pontos para os dois IDs e remova esse console. Salve as alterações e vamos enviar a solicitação novamente. Veja, agora o produto foi excluído com sucesso. Agora, se quiser, você pode ativar esse método de exclusão de um. Agora, depois de excluirmos o produto do banco de dados, é melhor excluir também as imagens desses produtos do servidor. Para excluir o arquivo do servidor, podemos usar o módulo FS Então, no topo, Fs é igual a exigir promessas de Fs. E também precisamos do módulo de caminho. Portanto, const path é igual a require Path module. Agora, na parte inferior, após esse método de exclusão, adicionamos fs unlin Agora, neste método, temos que passar o caminho completo do arquivo que queremos remover. Mas na matriz de imagens, temos apenas o nome do arquivo, mas precisamos aqui do caminho completo. Para isso, precisamos usar o módulo Path, que é outro módulo embutido do node jazz. Deixe-me mostrar que o caminho completo de Const é igual a path dot join Primeiro, passamos para disco e Discord o nome deles, que é todo o caminho do diretório do nosso projeto Em seguida, escrevemos nossa pasta na qual armazenamos as imagens. Aqui subimos uma pasta porque atualmente estamos na pasta routes, carregamos produtos de barra e , no terceiro argumento, adicionamos o nome da nossa imagem Agora, aqui não temos apenas uma única imagem. Temos matrizes de imagens, então temos que executar um loop para isso Antes disso, adicionamos imagens de pontos do produto. Então, para acessar imagens, aqui no método select, temos que passar imagens. Bom. Agora, as imagens de pontos do produto pontuam para cada uma. Aqui, obtemos o nome de cada imagem, função de seta e, nisso, moveremos essas duas linhas. Agora, aqui no fs dot unlink, passamos esse caminho completo, e isso como dot unlink é uma operação assíncrona Portanto, temos que aderir a um peso e, para isso, temos que tornar essa função de cor assíncrona. Bom. Agora, antes de executar esta página, é melhor verificar se temos uma matriz de imagens ou não. As imagens de pontos do produto I estão disponíveis e o comprimento do ponto das imagens de pontos do produto é maior que zero. Só então executamos esse loop. Mova esse código aqui. Nessa operação de desvinculação, pode ocorrer um erro. Antes desse deslink do fs dot, adicionamos o blog try and cache Mova esse método de desvinculação no tr Blog e, no blog de cache, obtemos essa exceção Simplesmente consultamos erro de ponto na métrica, erro, exclusão, arquivo, colchetes em C, caminho completo, vírgula, adição Veja as mudanças e dê uma olhada. Vamos testar essa implementação, copiar o ID do último produto. Veja também o nome da imagem. Essas imagens devem ser excluídas. Substitua esse ID do produto esse ID e envie essa solicitação de exclusão. Veja, aqui o produto foi excluído com sucesso e, se verificarmos nossa pasta de produtos, veja nesta pasta, não obteremos essas imagens. É assim que excluímos o produto e suas imagens. Agora vamos também adicionar o produto que acabamos de excluir. Então, crie uma nova API de produto e aqui eu altero esse título para o novo nome do produto. Selecione aqui as imagens. E simplesmente envie essa solicitação. Aqui, recebo um token válido porque o anterior expirou Vamos para a API de login, copiamos o token e, nos cabeçalhos, colamos esse token Agora, vamos enviar essa solicitação. Veja, aqui temos novos dados. Adorável. Nos vemos na próxima aula. 130. Pesquisar produto por título [OPCIONAL]: Agora, em todos os aplicativos de comércio eletrônico, temos o recurso de pesquisa em que, na parte inferior da barra de pesquisa, podemos exibir sugestões Então, temos que definir a API para isso. Além disso, essa API será chamada quando cada caractere entrar na barra de pesquisa. Portanto, dot cat externo, endpoint, duas sugestões de barra, função de retorno de chamada assíncrona com solicitação e resposta Em primeiro lugar, obtemos o que o usuário está pesquisando. Portanto, a pesquisa de custo é igual a solicitar ponto de consulta ponto Sarge aqui, temos que usar a expressão regular para comparar e encontrar a string no título Portanto, Const products é igual a await product dot find passier condition Object, title to object Aqui, usamos dollar regex, que é a forma mais recente de escrever expressões regulares no Mongo Aqui, passamos nosso texto de pesquisa e, para desativar a distinção entre maiúsculas e minúsculas, passamos aqui as opções em dólares para a string I. Aqui, comparamos nossa string de pesquisa com nosso título. Isso nos dará produtos que tenham essa palavra ou sequência. Além disso, na sucessão, não queremos mostrar todos os detalhes, como descrição e tudo mais como descrição e Portanto, podemos adicionar aqui o método Selec e obtemos apenas o ID de sublinhado e a propriedade do título Além disso, podemos limitar esses dados a dez no front-end, sugerimos apenas dez produtos na parte inferior da barra de pesquisa. No final, simplesmente respondemos dot Json a esses produtos. Salve as alterações e vamos experimentar essa API. Abra o Postman, crie uma nova solicitação chamada Obter sugestões URL para produtos de API, sugestões de barra, interrogação para passar o parâmetro de consulta, pesquisa é igual ao IP Certifique-se de selecionar o método Get e enviar a solicitação. Veja, aqui não temos produtos. Vamos ver o que temos no terminal. Veja, aqui estamos tendo alguns problemas com o ID do objeto. Mas em nossa API de sugestões, não temos nenhum ID de objeto. Então, por que estamos chegando aqui, erro de ID do objeto. Na verdade, essa chamada de API não está chegando à API de sugestões. Ele está se movendo dentro dessa API de obtenção de um único produto. Deixe-me explicar isso para você. Aqui está o primeiro URL da API para um único produto. Temos produtos de API que cortam o ID do produto. Adicionamos outros produtos de API e reduzimos as sugestões. Agora o Express está ficando confuso. Essa sequência de sugestões é o ID do objeto ou não. Por causa disso, nossa API de produto único está em execução. Qual é a solução aqui? Nada, só precisamos mover nossa API de sugestões antes dessa API de produto único. Com isso, o Express compara nossa API com a sequência de sugestões e, se isso não corresponder, somente o Express passará para a API de produto único. Mudanças de fase e verifique se o servidor está funcionando corretamente. No carteiro, vamos enviar a mesma solicitação. Veja, agora recebemos sugestões de produtos. Eu criei esse erro intencionalmente para mostrar o que pode acontecer quando você cria um projeto sozinho Agora, na próxima seção, aprenderemos como lidar com erros como profissionais. C na próxima seção. 131. Seção 11 - Por que lidamos com erros?: Atualmente, estamos executando nosso aplicativo no mundo ideal. Tudo está funcionando perfeitamente. Mas no mundo real, tudo pode dar errado. Qualquer erro pode ocorrer. Por exemplo, algum arquivo não foi encontrado ou nossa conexão com o servidor Mongo Deb não teve sucesso ou o usuário não passou as informações válidas ou algo pode dar errado Nesses casos, temos que lidar com erros, e aqui estão alguns motivos para lidar com erros. Em primeiro lugar, quando lidamos com erros, podemos enviar uma mensagem de erro amigável e exibir esse erro amigável na página da web, como se o servidor tivesse alguns problemas Tente novamente mais tarde, desta forma. Segundo motivo para lidar com erros, podemos registrar ou, em palavras simples, armazenar os erros em um arquivo separado e, em seguida, analisar esses erros, quais erros estão acontecendo com muita frequência e, com isso, podemos resolvê-los em nosso aplicativo. Portanto, lidar com erros também pode melhorar nosso aplicativo. Agora, deixe-me mostrar um erro. Vamos executar nosso aplicativo usando nodemon index dot js. Agora, no carteiro, também estamos recebendo sugestões do Sargento Agora, suponha que o servidor Mongoib falhe. Então, para demonstrar, podemos comentar o código de conexão do arquivo index dot js. Salve as alterações e vamos voltar para o carteiro. Envie a mesma solicitação novamente. Veja aqui que temos carregamento, carregamento e carregamento. E depois de 10 segundos, obtemos um erro. E se verificarmos nosso terminal de aplicativos, veja aqui que obtemos os produtos de operação de erro do Mongoose , ponto Find Buffering Time out E depois disso, nosso aplicativo pode falhar. Suponha que, no mundo real, nosso servidor Mongo Deb fique desligado por até dois a 3 minutos e, em seguida, nosso aplicativo possa travar na produção Depois de algum tempo, o servidor Mongo Di B volta ao ar. Mesmo que esteja ativo, nosso aplicativo permanecerá travado e não poderemos enviar dados para o cliente É importante lidar com esses tipos de erro Além disso, lidar com erros não significa que o erro não aconteça. Lidar com erros significa que, com esse erro, nosso servidor não travará Atualmente, esse aplicativo está em execução, mas antes dessa versão anterior do node Jaz, os aplicativos do node estavam travando Durante esta seção, veremos como lidar com erros e registrá-los. 132. Como lidar com promessas rejeitadas: Em primeiro lugar, vamos lidar com os erros que acontecem quando lidamos com promessas de API. Nesta API de sugestões, chamamos aqui essa coleção de produtos. E, como sabemos, essa é uma operação assíncrona, por isso usamos await Então, temos aqui uma promessa e essa promessa é rejeitada. Mas aqui não lidamos com erros no bloco de secagem e captura, que aprendemos na seção seis. Lembre-se, então aqui no try and catch block, aqui no blog de cache, obtemos o objeto de erro. Agora, o que queremos fazer neste blog de cache? No blog de cache no mundo real, primeiro registramos o erro ou a exceção em algum lugar do arquivo ou do banco de dados e, depois disso, retornaremos resposta com o código de status e a mensagem de erro relevantes. Atualmente, estamos apenas registrando o erro no console. No futuro, salvaremos esse erro ou exceção em um arquivo separado. Agora, depois de registrar o erro, retornamos a resposta com o código de status 500, que é um erro do servidor. Depois disso, também retornamos o objeto JSON com a propriedade de mensagem chamada erro interno do servidor Ou você pode escrever algo que deu errado no servidor. Podemos escrever qualquer mensagem de erro que quisermos. Bom. Agora podemos mover todo o nosso código neste blog seco. Vamos ver o que acontece, ver as mudanças e aqui nosso aplicativo é reiniciado. Mesmo assim, nosso banco de dados Mongoib não está conectado. Agora vamos enviar a solicitação de sugestões. Deixe carregar. Após 10 segundos, veja, aqui obtemos a resposta com o código de status 500 e com nossa mensagem de erro. Além disso, vamos ver o que temos no console. Veja, aqui temos esse erro do Mongoose, o mesmo de antes, e também nosso aplicativo não é interrompido por esse Ainda assim, nosso aplicativo está em execução, resolvemos com sucesso nosso erro de promessa rejeitada. Aqui, não consultamos ou registramos esse erro em nosso terminal, nem sabemos que houve um erro. Agora, se tentarmos acessar nossas outras APIs, por exemplo, enviaremos essa solicitação para todos os produtos Após 10 segundos, recebemos um erro e, no terminal, nosso aplicativo não falha Então, como podemos ver como podemos lidar com erro de rejeição de promessas usando o bloco try and catch. Dessa forma, nosso aplicativo não falha, e é por isso que lidar com erros é importante Para todas as rotas, temos que agrupar todo o nosso código com o bloco try and cache. Mas aqui em nosso aplicativo, temos quase dez a 15 rotas de API. Temos que incluir todo o nosso código de rota de API no blog try and catch, que está se repetindo Além disso, se um dia quisermos alterar a mensagem de erro ou alterar a lógica de registro , teremos que atualizá-la em todas as nossas rotas. Agora você pode perguntar: existe algum atalho para isso? Sim, existe um atalho e veremos isso na próxima lição 133. Crie erros de middleware: Na lição anterior, vimos que precisamos repetir esse erro de registro e retornar a resposta de erro em cada rota de API. Nesta lição, criaremos um middleware comum no qual escreveremos código para esse erro de registro e retornaremos a resposta de erro Não se preocupe, é muito simples. Primeiro de tudo, em nosso arquivo index dot gs na parte inferior, depois de todas as rotas, adicionamos app dot g aqui passamos a função e, como sabemos, aqui obtemos três parâmetros, resposta da solicitação e próxima função. Agora, nesta função, escreveremos toda a lógica para tratamento de erros. Em primeiro lugar, adicionamos aqui o log de pontos do console. Erro, o middleware está sendo executado apenas para garantir que esteja Agora, de volta à nossa rota, corte esse código dentro do bloco de cache e simplesmente cole-o em nossa nova função de middleware Agora, se quisermos alterar a mensagem de erro ou qualquer lógica relacionada ao tratamento de erros , precisamos fazer as alterações aqui em um único lugar. Agora, aqui está uma coisa. Como podemos obter esse objeto de erro nessa função? Recebemos esse objeto de erro como primeiro parâmetro nessa função de retorno Certifique-se de obter o objeto de erro como primeiro parâmetro. Agora vamos ver como podemos chamar esse middleware? Então, saia daqui e aqui no bloco de cache para chamar o próximo middleware, o que temos que fazer Certo, podemos usar a próxima função. Aqui, obtemos a próxima função como parâmetro e simplesmente chamamos a próxima função no bloco de cache e passamos o objeto de erro na próxima função. Se você está um pouco confuso, deixe-me mostrar o fluxo de código desse middleware de erro Como sabemos em nosso back-end, estamos executando apenas um único arquivo, que é esse ponto de índice js. Então, node, comece a executar esse código. Primeiro, esse middleware e o código estático serão executados. Depois disso, temos todas as rotas e depois adicionamos o middleware de erro Agora, quando executamos a próxima função em qualquer uma dessas rotas, essa próxima função executará esse middleware de erro Em todas as rotas, chamaremos a próxima função e, como primeiro argumento, passaremos o objeto de erro do bloco de cache. Se em nosso triplog algo der errado, esse método case será executado e esse método de cache chamará essa próxima função, e isso executará essa função de middleware de erro Simples assim. Veja as mudanças e vamos verificar se está funcionando ou não. Atualmente, nosso aplicativo está funcionando, bom, abra o carteiro e envie a solicitação de sugestões E depois de 10 segundos, recebemos um erro e, em nosso terminal, ramiddalware está em execução, o que significa que nosso ramiddleware está funcionando que significa que nosso ramiddleware E depois disso, obtemos o erro do Mongoose, ótimo. Portanto, se quisermos alterar alguma coisa no tratamento de erros de rotas , precisamos fazer as alterações em apenas um único local. 134. Remova blocos de tentativa: Agora, nossa implementação atual é boa. Se você estiver de acordo com isso, poderá usar essa abordagem. Mas muitos desenvolvedores não gostam dessa abordagem. Você pode ver que temos aqui o bloco try and cache, e temos que repetir esse bloco try cache em cada manipulador de rota ou função de retorno de chamada, que parece um pouco confuso No mundo ideal, devemos escrever apenas essa lógica. Então, como podemos fazer isso? É muito simples. Acabei de verificar esta atualização do Express Fi. Nesta versão Express Five, Express trata automaticamente o erro de rejeição de promessa ou esses erros que ocorrem durante a operação assíncrona O Express chama automaticamente esse próximo middleware com o objeto de erro, que executará nosso middleware de erro global Deixe-me te mostrar isso. Então, agora aqui não precisamos desse blog seco e em cache. Nós podemos removê-lo. Então, aqui estamos de volta à nossa sintaxe de rota original. Salve esse arquivo e vamos verificar isso. Abra o carteiro e envie a mesma solicitação de cugion. Após 10 segundos, obtemos esse erro. E se verificarmos nosso terminal de código VS, veja, aqui primeiro obtemos o erro de que o middleware está em execução e, em seguida, obtemos nosso erro, o que significa que nosso middleware de erro global Isso é muito legal, certo? Na versão mais antiga, como o Express four, esse tratamento automático de erros não está funcionando. Com isso, temos que agrupar cada lógica de rota em blocos secos e de cache, mas agora não precisamos fazer isso. O Express faz isso automaticamente, temos que definir o middleware de erro global no arquivo index dot js . Simples assim. 135. Registrar erros no arquivo: Portanto, nesta lição, registraremos nossas mensagens de erro em um arquivo de log separado, como este. É muito interessante. Vamos fazer isso. Portanto, atualmente, estamos registrando apenas a mensagem de erro no console. Agora é hora de armazenar essas mensagens de erro em um arquivo separado. Assim, no futuro, podemos ver os erros que acontecem com frequência, podemos encontrá-los e melhorar nosso aplicativo. Portanto, para registrar os erros em um arquivo, use outro pacote NPM, que é o Winst Essa é uma das bibliotecas mais populares para registrar os erros e também a torna muito simples. Então, abra o terminal e escreva o NPM, instale o WinsterNF usando exatamente a mesma versão, escrevemos no direto 3.17 Agora configurar o Winston é muito simples. Em primeiro lugar, importamos Winston, const, Winston é igual require e passamos Agora, esse Winston, por padrão, nos dê um Esse registrador é suficiente para tipos pequenos e médios de aplicação Assim, podemos personalizar esse registrador conforme quisermos para tipos de aplicativos grandes e complexos Agora, esse Winston ou lenhador tem transporte. Esse transporte é como um veículo de entrega para seus registros. Ele decide para onde o registro deve ir. Um transporte pega as mensagens do registrador criadas por Winston e as envia para um Agora, o destino pode ser o console , que imprime o log no terminal ou na linha de comando. Em seguida, temos um arquivo para salvar os registros em um arquivo em nosso sistema, SDTP para enviar o log para uma API e, em seguida, temos um banco de dados para armazenar os registros em um banco de dados como o Mongo DB Por fim, temos serviços em nuvem para enviar registros para serviços como AWS, Datadog, etc. Todos esses são transportes fornecidos pela Winston. Deixe-me mostrar alguns deles. Este pacote Winston, por padrão, usa o transporte Consult para imprimir os registros no terminal, mas aqui também queremos salvar os registros em um arquivo separado e, para isso, precisamos configurá-lo Então, aqui escrevemos Winston dot Create Logger. Agora, nesta função, temos que passar o objeto de configuração, ou podemos dizer o que queremos personalizar. Agora, a primeira configuração está nivelada. Essa propriedade de nível define quais tipos de mensagens queremos armazenar ou registrar. Por exemplo, queremos armazenar apenas erros, ou queremos registrar avisos e erros, ambos, ou queremos registrar todos os tipos de mensagens Então, em Minston, temos muitos níveis de registros. O primeiro é o erro, que é o nível mais alto de registro para problemas sérios. Exemplo, falha na conexão do banco de dados. Em seguida, temos uma guerra por avisos, informações por mensagens informativas, como servidor rodando na porta ou um GTB conectado, etc Em seguida, temos os verbos SDDP debug, Ci. Esse é o nível máximo e mínimo de registros. erro é o nível mais alto e CLI é o nível mais baixo de registros Agora, se no rótulo, passamos informações, recebemos mensagens de registro de informações de nível superior, que é um aviso, e também recebemos um registro de erros. Se no rótulo, passamos por bobagem, então recebemos todas as mensagens dos níveis superiores Para uma melhor prática, passamos aqui informações porque não queremos armazenar mensagens bobas em nosso arquivo de log Agora, depois do rótulo, temos os transportes, e aqui temos que passar todos os transportes que queremos adicionar na matriz Em palavras simples, para onde queremos enviar nossos registros. Queremos mostrá-lo no console ou armazená-lo em qualquer arquivo. Então, primeiro de tudo, para avisos de informações e erros, queremos mostrar os registros no console. Então, adicionamos aqui novos transportes de pontos Winston. Certifique-se de que seja um console de transporte, não de transporte e pontos Por enquanto, vamos apenas consolá-lo. Em apenas um minuto, armazenaremos esses registros em um arquivo separado. Agora, para usar esse registrador, nós o armazenamos em uma variável chamada logger E agora podemos usar esse registrador em nosso aplicativo. Mas aqui está uma coisa. Como esse registrador pode saber qual nível de mensagem estamos enviando É uma informação, aviso ou erro? Qual deles? Suponha que aqui na parte inferior, tenhamos essa mensagem simples do servidor de log de pontos do console em execução. Isso é uma informação. Então, ao usar o log de pontos do console, podemos usar o logger, que acabamos de criar, e esse registrador tem todos os métodos de acordo com Então, se quisermos enviar uma mensagem como informação , usamos aqui as informações de pontos do logger Se tivermos um aviso , usamos o logger dot one Agora queremos informações sobre os pontos do registrador, e vamos ver se estamos recebendo esse log no console ou não. Veja onde estão as mudanças. E se verificarmos nosso terminal, veja aqui que obtemos esse nível de objeto para o servidor de informações e mensagens escutando na porta 3.000 Ótimo. Agora, esse não é um bom formato para o log. No mundo real, não precisamos apenas de rótulo e mensagem. Precisamos de muito mais informações sobre o registro, como registros de data e hora, etc Então, na configuração, temos mais uma propriedade chamada format. Aqui, definimos como as mensagens de log aparecem. Aqui escrevemos o formato winston dot, dot Combine. E nisso, podemos passar um pouco do formato de Winston. Assim como adicionamos o formato de pontos Winston, ponto T Stem e, depois disso, formato de pontos winston, ponto JSON Não se preocupe Temos que configurar Winston apenas uma vez. Depois disso, usamos esse registrador para imprimir e enviar registros Compartilhe as mudanças e dê uma olhada. Veja, agora também temos carimbo de data/hora. Agora, em nosso middleware de erro, aqui, veja, usamos o log de pontos do console para esse objeto de erro Então, podemos usar aqui agora, a mensagem de pontos do logger. Temos que passar a mensagem de erro, que é a mensagem de ponto de erro, e também enviar todo o objeto de erro. Vamos ver o que obtemos. Salve as alterações e vamos provar isso de volta para Postman. E enviamos aqui uma solicitação de sugestão. Agora, depois de dez segundos, volta ao código Vas, abra o terminal. Veja, aqui obtemos a mensagem de erro de nível a nível para a mensagem de erro e, na propriedade stack, obtemos todo o objeto de erro, que passamos no método de erro logger dot e, no final, obtemos o limite de tempo Agora vamos tornar esse registro mais avançado. Aqui estamos apenas recebendo a mensagem de registro e a pilha de registros, mas aqui não sabemos qual rota causou esse erro ou qual método criou esse erro Queremos adicionar isso em nosso registro. Isso nos dará informações específicas. É muito simples. Então, no erro de ponto do logger, no lugar desse segundo argumento, podemos passar o objeto Neste objeto, podemos definir quais são as outras propriedades que queremos mostrar. Então, primeiro, adicionamos pilha à pilha de pontos de erro. Em seguida, queremos o método API, ou seja, método para solicitar o método de ponto. Em seguida, queremos um caminho para solicitar o URL original do ponto. Certifique-se de escrever aqui o nome correto da propriedade. Além disso, podemos solicitar essas propriedades. Suponha que queremos mostrar o veado no final e, primeiro, queremos o método e depois o caminho Então, neste objeto, também podemos definir a ordem das propriedades. Mas para isso, em nosso formato, temos que adicionar esse formato JSN Caso contrário, não funcionará. Guarde as informações e dê uma olhada. Envie a solicitação novamente a partir das sugestões após 10 segundos volta ao código VS no terminal. Veja, aqui obtemos o método de mensagem de erro para obter o caminho para nossa API, que causou esse erro, pilha completa desse erro e a data e hora desse Adorável. Então, terminamos a formatação do nosso registro Agora, vamos armazenar o log em um arquivo separado, não apenas no console. Então, aqui no transporte, adicionamos outro novo arquivo de transporte de pontos Winston dot transports Aqui passamos o objeto dentro da propriedade, nome do arquivo, logs, smlogs dot log Certifique-se de usar sua extensão de arquivo dot log, o que nos ajudará a entender o que está no arquivo. Agora diga as mudanças e dê uma olhada. No terminal, obtemos essas informações de log e, se verificarmos nosso aplicativo, nosso arquivo de log é criado em logs slamlogs dot E se abrirmos esse arquivo, veja, obtemos informações adicionadas ao arquivo. Se enviarmos novamente, recebermos a solicitação do Postman e, após 10 segundos, obteremos um erro e, se voltarmos ao nosso VSCode, obteremos um novo nível de log Agora, alguns desenvolvedores gostam de registrar apenas erros no arquivo, não informações e avisos Eu acho que é muito melhor. Também podemos fazer isso. De volta a Winston. Aqui, após o nome do arquivo, também podemos especificar o nível de erro. Isso significa armazenar apenas erros neste arquivo e também podemos alterar o nome do arquivo para errors dot log Portanto, se em qualquer um desses transportes, não especificarmos o nível de log, esse transporte usará esse nível de log global E se especificarmos o nível de log nos transportes , ele substituirá esse nível de log global Suponha que, para o transporte do console, adicionemos o nível do objeto à depuração Então, agora, para todos os níveis relacionados à depuração, mostraremos o login no console e somente os erros serão armazenados no arquivo de log de pontos de erros É assim que armazenamos os registros em um arquivo separado e, em seguida, podemos melhorar nosso aplicativo de acordo com isso. Então, para resumir, o log de pontos do console não é ruim. Mas usando o Winston, podemos armazenar nossos registros em um arquivo separado, o que torna nosso aplicativo mais profissional 136. Erros de log no mongoDB: Agora, nesta lição, armazenaremos nossos registros em nosso banco de dados Mongo DB desta forma É muito simples, vamos fazer isso. Para armazenar os registros no Mongo DB, precisamos de outro pacote Winston, abra o terminal e aqui escreva NPM install Winston Mongo DB, na Minimize esse terminal, ótimo. Agora, para adicionar esse pacote na parte superior, precisamos do Winston des Mongo Agora, na configuração do Winston, precisamos adicionar outro transporte para o Mongo Então, após esse transporte de arquivo, adicionamos novos Winston dot transports dot MongoDB E nesse transporte, temos que definir algumas opções. O primeiro é DB. Aqui, temos que adicionar o URL do banco de dados. Simplesmente copiamos esse URL de conexão do Mongo DB e o colamos aqui Além disso, podemos passar a propriedade de nível de log por nível para erro, e pronto. Veja as mudanças e vamos simplesmente verificar essa implementação. Vamos executar nosso servidor se ele não estiver em execução e enviar a mesma solicitação de sugestões. Após 10 segundos de volta ao código Vas, aqui obtemos o erro no console e, se verificarmos nosso banco de dados, obtemos uma nova coleção de registros e, nela, obtemos nosso erro mais recente. Aqui, obtemos o timestamp, o nível do log, que é erro, a mensagem de erro e, por último, obtemos Este é o mesmo objeto que passamos no segundo parâmetro do logger dot error Veja, aqui temos o método, o caminho e a pilha completa do erro É assim que é simples registrar erros no banco de dados. Se você quiser armazenar registros no banco de dados, poderá continuar com esse transporte. E se você quiser armazenar os registros em um arquivo separado , podemos continuar com esse transporte de arquivos. Mostre os dois lados , você pode usar qualquer um deles de acordo com sua escolha. Realmente depende de você. 137. Exceções não detectadas: Portanto, até agora, neste projeto, temos erros de tratamento que ocorrem no manipulador de rotas e o manipulador rotas passará o erro ou a exceção para o middleware de erro global Agora, e se obtivermos um erro no resto do aplicativo do nó? Nós não lidamos com isso, certo? Então, para demonstrar isso, eu removo o comentário da conexão do Mongo DB e simplesmente lanço um novo erro a partir daqui Então, lance um novo erro, e aqui passamos a mensagem de erro, algo falha no aplicativo node. Então, as alterações e, em nosso terminal, interrompem nosso aplicativo e executamos nosso aplicativo usando node index dot js. Veja, aqui temos um erro, algo falha no aplicativo do nó e também nosso aplicativo está travado Isso é chamado de exceção não capturada. Uma exceção não detectada é como um convidado surpresa em uma festa Você não está preparado para isso e isso causa caos porque não há um plano para lidar com isso. Em palavras simples, sempre que um aplicativo de nó se um problema ou uma exceção que não sabe como lidar, ele chama uma exceção não codificada Esses são erros em nosso código, que não são detectados por um try and catch adequado ou não são tratados adequadamente e, como resultado, o Node simplesmente não sabe o que fazer e nosso aplicativo falha À medida que nosso aplicativo falha, nosso front-end não obtém os dados do nosso back-end Nossa API não funcionará. Portanto, é importante lidar com essas exceções de descodificação. Agora, a questão é: como podemos lidar com exceções de uncode em nosso aplicativo Node Porque essas exceções ou erros podem acontecer em qualquer lugar. Como podemos lidar com isso? Então, para isso, temos que adicionar um ouvinte para nosso aplicativo de nó. Deixe-me te mostrar. Então, aqui depois do Winston, escrevemos o processo ponto a ponto Isso nos ajudará a adicionar ouvintes para um evento específico. Agora, em qual evento, queremos ouvir. Escreva, é uma exceção não codificada. Certifique-se de escrever o mesmo nome do evento. Caso contrário, não funcionará. Agora, o que queremos fazer quando exceção não codificada acontece em nosso aplicativo? Que adicionamos a função de retorno e ela tem erro ou exceção Na função de retorno de chamada, por enquanto, simplesmente consultamos um registro desse objeto de erro Esse processo, pontualmente, é como um observador. Ele está de olho em nosso aplicativo e, se em nosso aplicativo ocorrer alguma exceção de uncod, ocorrer alguma exceção de uncod processo dot on executará essa função de retorno de chamada Portanto, no lugar de usar o log de pontos do console, podemos usar o erro de pontos do logger E nisso, temos que primeiro passar a exceção não capturada da string e, em seguida, passar todo o stag de erro Vamos verificar se está funcionando ou não. Salve as alterações e, no terminal, vamos examinar o terminal com o comando CLS e, em seguida, executamos nosso aplicativo usando node index dot js Veja, aqui temos nosso erro no console e nosso aplicativo não é classificado sozinho Mas, como podemos ver, também não obtemos as informações do servidor em execução na porta 3.000, o que significa que o servidor não está em execução Portanto, nosso aplicativo está pendurado no meio. O servidor não está em execução e o aplicativo não está funcionando. Portanto, nosso aplicativo não está no estado estável. Então, o que queremos fazer agora é sair desse estado instável Então, após o erro de ponto do registrador, simplesmente escrevemos process dot exit e aqui passamos um como código de saída Um significa erro. Além disso, temos o código de saída zero, o que significa que está tudo bem, mas ainda assim queremos sair. E se passarmos o código de saída um, isso significa que algum erro ocorre, e é por isso que saímos. Então, as mudanças, e vamos executar nosso aplicativo mais uma vez. Node, index dot Js e C, agora saímos com sucesso do nosso aplicativo. Linda. Agora, você pode fazer essa pergunta se, depois de lidar com a exceção, ainda estamos encerrando nosso aplicativo, então qual é o objetivo de lidar com a exceção não detectada Portanto, lidar com exceções não capturadas não significa impedir o estabelecimento. Trata-se de garantir que a configuração ocorra de forma ordenada, segura e informativa Quando ocorre uma exceção não detectada, estado do nosso aplicativo é imprevisível Depois de uma falha não aceita, partes do nosso aplicativo podem não funcionar como queremos Por exemplo, temos conexões de banco de dados interrompidas, memória corrompida, solicitação incompleta, etc Reiniciar o aplicativo garante que ele seja reiniciado sem problemas decorrentes do Além disso, na produção, ferramentas como PM two, Docker ou Kubernets monitoram Quando nosso aplicativo é encerrado, essas ferramentas o reiniciam automaticamente. O tratamento do erro garante que o aplicativo saia claramente usando o processo dot exit V, além de facilitar a reinicialização do aplicativo pela ferramenta de monitoramento sem problemas pendentes. Além disso, uma coisa que encontro aqui é que, quando estamos processando dot exit, nossos registros não estão sendo armazenados no arquivo ou no banco de dados, mas você pode ver o log no console. O que há de errado aqui? Então, quando processamos dot exit, nosso aplicativo de nó é encerrado imediatamente Ele não está esperando que uma tarefa assíncrona como fazer login em um arquivo ou banco de dados, seja concluída Em palavras simples, o processo dot exit one não espera que essas operações terminem, então a parte do log pode ser parcialmente ou completamente ignorada Agora, como podemos resolver esse problema? É muito simples. Preciso sair do processo depois nosso registrador concluir o processo de registro Então, após esse erro de ponto do registrador, escrevemos o ponto do logger em, e você adivinhou corretamente, esse também é o ouvinte Aqui, passamos o nome do nosso evento, que é finish, e no segundo argumento, passamos a função Callback, e nela, podemos simplesmente mover esse processo ponto para sair um Para uma melhor prática, também registramos pontos. Salve as alterações e vamos ver se está funcionando ou não. Execute este aplicativo e, se verificarmos nosso arquivo de registro, veja, aqui obtemos um novo log, então ele está funcionando 138. Rejeições de promessas não processadas: Suponhamos que, em nosso aplicativo node, tenhamos alguma promessa que foi rejeitada e esquecemos de lidar com esse erro usando try and cache Blog ou o método cache Essa promessa rejeitada precisa ser cumprida. Então, para demonstrar isso, removemos isso por engano e criamos aqui uma nova promessa. Digamos que a promessa rejeitada de custo seja igual a uma nova promessa. Como sabemos, aqui, temos que passar a função de retorno de chamada com dois parâmetros, dissolver e rejeitar Agora, para rejeitar a promessa, simplesmente chamamos aqui o método de rejeição e, aqui, criamos um novo erro e passamos uma mensagem de erro. O que escrevemos como erro? Digamos que há um erro na promessa. Desculpe pela mensagem de erro. Agora vamos consumir essa promessa. Rejeite um ponto de promessa então e nessa função de erro e simplesmente consultamos o log de pontos, a promessa está funcionando. Pode até usar aqui OD, mas para isso, temos que envolvê-lo com uma função sin. É por isso que eu uso o método then, e aqui não lidamos com o erro usando o método cache. Agora vamos ver o que vai acontecer. Salve os ings e vamos executar nosso aplicativo com node index dot js. Aqui, obtemos o registro desse erro e, como podemos ver, a exceção não capturada é chamada novamente. Nas versões do nó 15 e acima de 15, rejeição de promessas não tratadas é tratada mais como uma exceção não contabilizada Se não lidamos com a rejeição de promessas , ela pode fluir para um manipulador de exceções sem cortes Para armazenar separadamente a rejeição do UnhandlePmise, podemos duplicar esse código e simplesmente alterar o evento para não tratar a Também no registrador, passamos aqui a mensagem de erro como rejeição de promessa não tratada Veja as mudanças e vamos executar esse aplicativo mais uma vez. Veja, agora recebemos aqui uma mensagem de erro, rejeição de promessa não tratada Então, é assim que podemos lidar com exceções não detectadas e rejeição de UnhandlePmise e rejeição de UnhandlePmise Agora, em nosso aplicativo, vamos alterar esse registro de pontos do console para a conexão Mongo Di B. O que escrevemos aqui? Informações sobre pontos do registrador E no método de cache, substituímos esse registro de pontos do console pelo erro de pontos do registrador Além disso, após a falha na conexão, podemos sair do nosso aplicativo porque todo o nosso aplicativo depende dessa conexão. Então, envolvemos esse código com colchetes. Simplesmente dos ouvintes globais, copie esse ponto do registrador e cole Isso permitirá que nosso aplicativo armazene o log no arquivo e no banco de dados. Agora, também, não precisamos dessa promessa de erro e também desse método then. É assim que lidamos com os erros e os registramos para melhorar e acompanhar nosso aplicativo. 139. Recapitulação do manuseio e registro de erros: Vamos recapitular rapidamente esta seção. Portanto, antes desta seção em nosso aplicativo, não lidamos com erros. Então, primeiro, tratamos os erros dos manipuladores de rotas da API. Qualquer erro que ocorra no manipulador de rotas, esse erro será enviado para o próximo middleware pelo Express mais recente e, após todas as rotas no arquivo index dot js, adicionará um middleware de erro que manipula todos os erros dos manipuladores Agora, depois de lidar com os erros, podemos armazenar esses erros nos arquivos ou no banco de dados. Então, para registrar os erros, usamos o pacote Winston e Winston Des Aqui, configuramos o registrador Winston no qual especificamos formato global do rótulo do nosso registro e alguns transportes para enviar nosso registro para o console, arquivo e até mesmo Com isso, podemos armazenar erros de manipuladores de rotas. Mas e se algo der errado fora do expresso? Portanto, definimos dois ouvintes globais, um para exceções não detectadas e outro para rejeição e outro para Lembre-se de que, se não adicionarmos um ouvinte para rejeição não tratada, por padrão, o node tratará a rejeição por padrão, o node tratará promessa como uma exceção não detectada Além disso, nesses ouvintes globais, registramos os erros e seguida, configuramos nosso aplicativo normalmente. No final, esse ponto do registrador deixará de gravar novos registros, encerrará quaisquer registros pendentes e fechará fluxos de transporte, como fluxos de arquivos, SDDPRquest ou conexões de banco SDDPRquest Isso é tudo sobre como lidar e registrar erros. Agora, na próxima seção, adicionaremos mais recursos em nosso aplicativo de comércio eletrônico 140. Seção 12 — criando o modelo de carrinho: Bem-vindo a outra seção importante do curso definitivo de No Jz Nesta seção, avançaremos em nosso projeto de comércio eletrônico. Primeiro, adicionaremos alguns recursos do cartão e, em seguida, integraremos gateway de pagamento em nosso aplicativo, o que é muito importante e divertido de criar. Estou muito animada e espero que você também esteja. Então, vamos começar esta seção. Até agora, em nosso projeto, adicionamos categorias de usuários e API de produtos. Agora, quando o usuário quiser comprar qualquer produto, ele adicionará o produto no cartão. Portanto, o cartão funciona como uma cesta ou carrinho no supermercado. Adicione todos os produtos que queremos comprar e depois pagamos por esses produtos. Nós já sabemos disso, certo? Então, criaremos um novo modelo para dados CAT. Então, na pasta models, criamos um novo arquivo chamado cart dot js. Agora, para definir o esquema, primeiro Cost Mongoose é igual a require mangoose E depois disso, definimos que esquema ST CAT é igual ao novo esquema de pontos do mangoose Aqui, adicionamos nosso esquema de cartão. Neste modelo de cartão, armazenaremos os detalhes do cartão de todos os usuários. Então, primeiro de tudo, precisamos armazenar o tipo de objeto do usuário esquema de pontos do Mongoose, tipos de pontos, ID do objeto de ponto, ref para o usuário e simplesmente torná-lo obrigatório como verdadeiro Agora, depois do usuário, queremos quais produtos o usuário adicionou em seu cartão. Então, adicionamos produtos preenchidos e, como sabemos no CAT, usuário pode adicionar vários produtos. Então, será a variedade de produtos. Agora, para cada produto, armazenamos o objeto de produtos e, nesse objeto, armazenamos a primeira ID do produto. Isso é novamente uma referência, então eu simplesmente copio esse objeto de esquema para o usuário Cole-o aqui para obter a ID do produto e certifique-se de alterar esse usuário de referência para produto. Agora, depois do ID do produto, precisamos da quantidade desse produto. Então, adicionamos quantidade ao objeto, tipo, ao número necessário para verdadeiro porque isso é necessário. Caramba, também podemos adicionar padrão a um por segurança. Agora, se imaginarmos nosso front-end, queremos mostrar dados como esses. Primeiro, queremos mostrar o nome ou o título do produto, depois o preço, depois a quantidade e o total. Se armazenarmos apenas a ID do produto nos dados do cartão , precisaremos executar o preenchimento para obter detalhes do produto, como título, preço, imagem etc., mas levará mais tempo para obter os dados do cartão Podemos usar aqui a abordagem híbrida. Se as necessidades do seu aplicativo forem diferentes, você deverá seguir a única abordagem de referência. Portanto, se você quer desempenho , usa o híbrido e, se deseja a consistência dos dados em que seus produtos se intitulam, as imagens de preços estão mudando com mais frequência , é necessário usar a abordagem de referência. Então, após a quantidade, adicionamos title, type à string e required a true. Depois disso, precisamos do preço, do tipo para o número, do necessário para verdadeiro. Depois do preço, talvez precisemos uma imagem que será a imagem da capa do produto, digitada como string e obrigatoriamente como verdadeira. Por fim, precisamos do preço total, que é o preço total desse produto atual, do tipo para o número e do necessário para verdadeiro. Esse preço total, contaremos por preço em quantidade, certo? Isso é tudo o que precisamos no objeto de produtos. Agora, o que precisamos de mais no carrinho? Vamos ver a página do GRT novamente. Em primeiro lugar, em qualquer site de comércio eletrônico, obtemos o número de produtos no Nepar ou em E também para a página CRT, precisamos exibir o preço final do produto Portanto, precisamos de mais dois campos em nosso esquema de cartões. Primeiro, o número total de produtos a serem digitados é zero. Se em nosso cartão tivermos dois iPhones e três relógios inteligentes , nosso total de produtos será cinco E depois do total de produtos, precisamos do preço total do cartão. Podemos associar como preço final, mas o preço total do cartão parece mais legal. Portanto, o preço total do cartão, digite o número e também o padrão seja zero. Agora, aqui você pode perguntar por que precisamos armazenar o preço total do cartão? Por que não podemos calcular os valores quando enviamos os dados do cartão? A razão pela qual armazenamos o preço total do cartão é porque, em primeiro lugar, a exibição é mais rápida. Portanto, quando o usuário visualiza o cartão, o site pode mostrar o preço total instantaneamente, sem recalculá-lo Isso economiza tempo, especialmente se houver muitos produtos no cartão. Em segundo lugar, reduza o trabalho do servidor. Isso ocorre porque não precisamos calcular o preço final várias vezes em vez Então imagine que nosso usuário tenha dez produtos diferentes em seu cartão. Sem o preço total do cartão, nosso servidor precisa examinar todos os dez produtos e somar seus preços toda vez que você abre a página do cartão. Agora, com o preço total do cartão, nosso servidor apenas obtém o preço total já armazenado Isso economizará tempo e esforços, e é por isso que armazenamos aqui preço total do cartão no banco de dados. Agora temos nosso esquema de cartão pronto. Se, no futuro, quisermos adicionar mais campos ou remover algo , também podemos fazer isso. Não há nada de errado nisso. Além disso, não se limite a uma abordagem. Como desenvolvedores, precisamos sempre pensar no que torna nosso aplicativo ou produto mais útil e rápido para os usuários finais. Simples assim. Agora vamos criar um modelo de carrinho, segundo cartão igual ao modelo de pontos de manga Primeiro, adicionamos um nome singular, que é cart e, no segundo argumento, passamos o esquema do carrinho Finalmente, no final, faremos com que o módulo de exportação de pontos seja igual ao CAT. 141. Definindo a lista de API para carrinho: Agora, antes de começarmos a criar as APIs para cartões, vamos ver quais e quantas APIs precisamos criar Isso nos dará clareza. Então, aqui está meu processo para definir a lista de APIs. Comecei a imaginar o front-end da perspectiva do usuário. Em palavras simples, eu me coloco no lugar do usuário normal, o que o usuário quer fazer com o cartão. Primeiro, eles querem simplesmente adicionar o produto no cartão. Portanto, essa é nossa primeira API. Depois de adicionar o produto ao cartão, eles querem ver seu próprio carrinho, quais produtos adicionaram e quanto dinheiro precisam comprar. Portanto, precisamos da API para obter o carrinho do usuário atual. Além disso, na barra Novo, eles gostam de ver o número de produtos disponíveis no carrinho. Assim, podemos criar uma API separada apenas para números de cartão. Depois disso, na página do carrinho, eles podem aumentar a quantidade de produtos ou diminuir a quantidade dos produtos, além de excluir todos os produtos do cartão. Aqui, precisamos de mais três APIs, uma para aumentar, a segunda para diminuir e a última para excluir o produto Então, aqui temos a lista de APIs para o carrinho. Obviamente, podemos adicionar ou remover APIs dessa lista. Isso realmente depende de nós. 142. Como adicionar produtos ao carrinho: Vamos começar com nossa primeira API para CAT, que é adicionar um único produto ao cartão. Então, na pasta routes, criamos um novo arquivo chamado card dot js. Bom. Agora, dentro desse arquivo, criamos o Router for API. Portanto, Const Express é igual a require Express e, depois disso, cost Router é igual ao express dot Router E, como sabemos, no final, as portas de pontos do módulo são iguais ao roteador. Agora, antes de definirmos a API, vamos configurar esse roteador em nosso arquivo index dot js. Caso contrário, nossas APIs de carrinho não funcionarão. Salve este arquivo, vá para o arquivo index dot js e simplesmente aqui const CAT routes é igual a require periods routes CART Certifique-se de escrever aqui, não é obrigatório. Recentemente, eu cometo esse erro. Agora, na parte inferior, adicionamos app dot g. Aqui adicionamos o prefixo API slash Aqui, adicionamos rotas de cartas. Adorável. Agora, vamos começar com a API Head to Cart. Então, aqui nós adicionamos o Roteador. E você pode me dizer qual método usaremos? Certo, usaremos o método post. Portanto, o ponto final do roteador ponto após é o slas de encaminhamento aqui. Depois disso, adicionamos o retorno de chamada da rota com solicitação Agora, o que queremos do front-end? Precisamos principalmente de duas coisas. Primeiro, precisamos do ID do produto que o usuário deseja adicionar ao cartão. E segundo, queremos saber a quantidade de seu produto. Por vez, o usuário só pode adicionar um produto com sua quantidade e, se quiser adicionar outro produto, precisará chamar essa API novamente. Simples assim. Então, primeiro, obtemos detalhes no corpo do ponto da solicitação. Podemos reestruturá-lo aqui e obter o ID e a quantidade do produto Além disso, para maior comodidade, obtemos o ID do produto no parâmetro de consulta. Portanto, remova-os daqui e, no endpoint, adicionamos dois pontos de identificação do produto E para obter esse ID do produto, adicionamos aqui o ID do produto de custo é igual ao ponto da solicitação, ponto PRAM, ponto, ID do produto Bom. Agora, depois disso, o que queremos? Sim, também precisamos do ID do usuário. E como podemos fazer isso? Sim, podemos adicionar orthomidalware aqui e, para obter o usuário, podemos escrever const user ID igual a request dot user dot underscore ID a request dot user dot Agora, aqui está uma parte lógica do que realmente queremos fazer na API Head to Cart. Em primeiro lugar, verificaremos ID e a quantidade do produto em primeiro lugar, ou não. Sempre comece com a validação. Adicionamos que, se a ID do produto condicional não estiver disponível ou a quantidade não estiver disponível, retornaremos o erro. Portanto, retorne a resposta, o status do ponto, 400 para os campos ausentes e o objeto JSON do ponto com propriedade Menset, sem os preenchimentos obrigatórios Bom. Agora, depois disso , verificamos se o front-end passa o ID do produto válido ou não. Existe algum produto com esse ID em nosso banco de dados? Para isso, escrevemos o custo, produto é igual ao peso do ponto do produto find By ID, e aqui passamos o ID do produto. Além disso, se a entrada automática não funcionar , teremos que inserir manualmente esse modelo de produto. Então, para usar await, temos que tornar essa função assíncrona Agora, na parte inferior, podemos colocar aqui se a condição, se o produto não estiver disponível, retornamos a resposta com status 404 pontos Json E na propriedade messet, passamos o produto não encontrado Agora, novamente, estou perguntando o que queremos fazer na API Adicionar ao carrinho. Vamos passo a passo. Não se confunda. Queremos simplesmente fazer uma coisa. Criamos um novo cartão para o usuário e simplesmente adicionamos o produto atual na matriz de produtos com os preenchimentos necessários Mas existe a possibilidade de esse cartão de usuário já estar disponível. Aqui, não queremos criar cartões duplicados, então verificamos que const card é igual a await Veja se a entrada automática funciona, ponto do cartão Fine One. E aqui no objeto de condição, passamos o usuário para o ID do usuário. Agora, como sabemos por vez, um usuário tem apenas um cartão, porque se você fizer o check-out dos produtos após o pagamento bem-sucedido, excluiremos o cartão do usuário do banco de dados. Se esse usuário tiver seu cartão , nós o obteremos na variável do cartão. E se o usuário não tiver carrinho? Pode ser o primeiro produto para cartão. Então, verificamos as condições. Se o carrinho não estiver disponível, o que queremos fazer? Certo, criaremos um novo cartão. Então, cartão novo. E aqui passamos Object. Primeiro, adicionamos o usuário ao ID do usuário, produto à matriz vazia por enquanto. Total de produtos em zero e preço total do cartão em zero. Agora, isso devolverá o carrinho. Aqui, podemos simplesmente usar essa variável do cartão e substituir seu valor porque, se o cartão não estiver disponível, somente então criaremos um novo CAT. Caso contrário, obtemos o objeto do cartão nessa variável do cartão. Usamos aqui o cartão igual ao novo carrinho. Então, para substituir essa variável do cartão, temos que defini-la usando let. Caso contrário, obteremos um erro. Você está claro até agora? Além disso, se você estiver um pouco confuso, não se preocupe. Quando concluirmos essa API, recapitularemos essa API do zero Com isso, toda a sua confusão desaparecerá. Portanto, temos o carrinho e basta inserir o produto na matriz de produtos com quantidade e outros campos que definimos no esquema Assim, podemos fazer cart dot products dot push. E aqui passamos o objeto do produto, que queremos empurrar. Então, objeto, que são os campos, eu realmente esqueço. Deixe-me dar uma olhada no modelo CAT. OK. Então, primeiro, ID do produto para ID do produto, quantidade para quantidade. Depois disso, temos o título. Agora, aqui, como podemos obter o título do produto? Porque o front-end só passará o ID do produto. Pense sobre isso. Portanto, obtemos detalhes do produto a partir dessa variável do produto. Veja aqui também verificamos se o produto é válido ou não. Se o produto for válido, obteremos seus detalhes na variável do produto. Então, agora faz sentido o motivo pelo qual encontramos o produto. Ele validará o ID do produto e também obteremos outros detalhes Então, título a título do ponto do produto. Preço em relação ao preço pontual do produto, que é o preço atual do produto, imagem, que é a imagem da capa, então imagem pontilhada do produto, que é matriz, e simplesmente definimos a primeira imagem. Agora você pode se perguntar por que não recebemos esses detalhes do front-end. Imagine que obtemos esse detalhe de preço desde o início. Se você ultrapassar zero para qualquer produto, o preço será armazenado como zero para o carro dele Portanto, claramente não podemos confiar nos dados do front-end. É melhor obtermos dados reais do banco de dados. Agora, depois dessa imagem, temos o preço total desse produto, que é o preço atual em quantidade. Portanto, o preço do produto é dividido em quantidade. E isso é tudo o que precisamos na matriz de produtos. Agora temos que fazer apenas duas coisas. Temos que contar o total de produtos do cartão e, em seguida, o preço total do cartão. Ambos são muito simples. E você sabe qual método usaremos para contar a soma? Certo, usaremos o método reduzido. Escrevemos que o total de produtos pontos do carrinho é igual aos produtos com pontos do carrinho, que é array dot reduce Como sabemos, precisamos passar dois argumentos no método reduzido. primeira é a função de retorno de chamada, na qual calcularemos a quantidade dos produtos e, em seguida, valor padrão da quantidade que é zero Agora, no retorno de chamada, obtemos dois parâmetros, total e produto, que são um único objeto de produto A partir do retorno de chamada, simplesmente retornamos total mais a quantidade de pontos do produto Em resumo, esse método reduzido executa o ciclo de cada produto e nos dá a soma da quantidade do produto. Ótimo. Agora, precisamos apenas calcular o preço total do cartão e usaremos novamente o método de redução para isso. total do cartão por pontos é igual ao preço total dos produtos do carrinho, redução de pontos. Aqui, novamente, passamos dois argumentos. primeira é a função callbeck com a função seta do objeto total e do produto E depois disso, simplesmente usamos valor padrão desse total, que é zero. O que retornamos dessa função de retorno de chamada. Simplesmente devolvemos o total mais o preço do produto em pontos na quantidade do produto. Ou, para simplificar, podemos retornar o total mais o preço total, que calculamos aqui. Além disso, acho que não precisamos desse campo de preço total. Na verdade, não está causando impacto. O que você acha? Sim, então vamos removê-lo do método push, e também temos que removê-lo do esquema Vá para o esquema do carro e remova esse preço total preenchido do objeto de produtos Simples assim. Agora temos todos os preenchimentos de cartões preenchidos com detalhes, então podemos simplesmente salvar o cartão Aguarde o ponto C. Depois de salvar o cartão, simplesmente retornamos a resposta, status do ponto, 201 e 200 pois aqui podemos criar um novo cartão ou simplesmente adicionar os produtos Além disso, pontilhe o objeto Json com a mensagem, produto foi adicionado ao cartão com sucesso E depois disso, simplesmente devolvemos o carrinho cheio na resposta. Se você não precisar enviar, também poderá removê-lo . Agora vamos testar essa implementação da API porque o teste é muito importante. Veja as mudanças e voltemos ao carteiro. Aqui em nosso projeto, criamos uma nova coleção chamada CAT. E na coleção CAT, criamos uma nova solicitação chamada de produtos ED para CAT. Primeiro, alteramos o método para postar APIURL no host local, a coluna 3.000 API slash CART SLS e aqui temos que passar o ID do produto, que queremos adicionar Por enquanto, eu apenas passo um e envio a solicitação. Veja, aqui obtemos um token de autorização necessário porque, em nossa API, adicionamos o middleware Vamos gerar um novo token, enviar a solicitação de login e aqui obtemos o token. Copie isso. Agora, na API do cartão, vamos aos cabeçalhos e adicionamos aqui a autorização no valor, adicionamos espaço para cerveja e colamos nosso token sem nenhum código duplo Agora envie a solicitação. Veja, aqui temos um erro interno do servidor. E se verificarmos nosso terminal de código VS, aqui não podemos desestruturar a propriedade, quantidade do corpo do ponto da solicitação Isso acontece porque não passamos a quantidade no corpo do ponto da solicitação. Então vá para o Mongoi B Compass. Na coleção de produtos, basta copiar esse ID do iPhone 14 volta para o Postman aqui no local deste, colamos o ID do objeto E no corpo, deixe-me remover essas duas propriedades. Agora vemos bruto e simplesmente passamos seu objeto com uma propriedade, que é quantidade para duas. E vamos enviar essa solicitação. Veja, aqui temos o produto adicionado ao cartão com sucesso. E aqui também podemos ver o cartão. Deixe-me aumentar isso. Veja, aqui obtemos o usuário, total de produtos para dois porque passamos a quantidade para dois, preço total do cartão para 2598, o que também está correto Também temos aqui uma matriz de produtos com todos os objetos do produto. Aqui podemos ver que também obtemos a quantidade, o título, o preço e a imagem atuais . Agora vamos tentar algo mais. Vamos alterar a quantidade para uma e simplesmente armazenar o mesmo produto. Veja, aqui temos o produto morto com sucesso, total de produtos e o preço total do carrinho, ambos também estão corretos. Mas se verificarmos nossa matriz de produtos, veja, aqui temos outro objeto de produto, mesmo que esse mesmo produto já esteja disponível na matriz de produtos. Em nossa API, temos um problema. Como podemos ver aqui, colocamos diretamente o produto na matriz de produtos. E se esse produto já estiver disponível na matriz de produtos? Nesse caso, temos que apenas aumentar a quantidade de seu produto. Então, aqui, antes que os produtos de cartão sejam enviados, temos que verificar se os produtos que estamos adicionando já estão disponíveis na matriz de produtos ou não. É muito simples. Então, para encontrar o produto, adicionamos produtos CRT dot, dot Find index Aqui, obtemos um único objeto de produto, função de seta, e aqui passamos a condição, produto, ponto ID do produto, ponto dois é igual à ID do produto ponto toString Agora, como sabemos, esse método de índice fino retornará o valor do índice do produto que passou por essa condição. Então, armazenamos isso em uma variável chamada índice de produto existente. E se o produto não for encontrado na matriz de produtos , ele retornará menos um como índice Portanto, podemos usar isso em caso de condição. Portanto, o índice do produto existente não é igual a menos um, o que significa que o produto já está disponível na matriz de produtos Nesse caso, vamos apenas aumentar a quantidade desse produto e como podemos encontrar esse objeto de produto? Certo, usando esse índice de produtos existente, ou seja, coloque os produtos entre colchetes, adicionamos o índice de produtos existente Com isso, obtemos a quantidade de pontos do objeto do produto. Mais é igual à quantidade atual . É isso mesmo. E se o produto não for encontrado na matriz de produtos, somente então colocaremos todo o objeto do produto na matriz. Então, aderimos e movemos esse método push para o blog s, e pronto. Veja as mudanças. E agora, antes do teste final, vamos remover o cartão inteiro do banco e criar um novo cartão. De volta ao Postman, envie a solicitação. Ótimo, temos um produto. Agora vamos alterar a quantidade para duas e simplesmente enviar a solicitação. Veja, agora nossa quantidade só aumenta, e também o total de produtos e o preço total do cartão estão corretos. Agora, há um pequeno problema nessa implementação. O produto pode ter estoque suficiente ou não. Precisamos verificar isso antes de adicionar o produto ao GAT. Então, aqui, depois de obtermos o produto, passamos por uma condição como esta. produto, o estoque de pontos é menor que a quantidade, então simplesmente retornamos o status do ponto de resposta, objeto Json de 400 pontos com a propriedade da mensagem O estoque não é suficiente. Agora, aqui está mais um caso. Suponha que nosso estoque de produtos seja quatro e queiramos adicionar o produto ao carrinho com a quantidade três. Isso passará por essa condição. Agora, e se esse produto, que tem apenas quatro em estoque, já adicionássemos duas quantidades de produtos anteriormente e agora quisermos adicionar mais três quantidades para o mesmo produto. Nesse caso, temos que evitar que a quantidade do nosso produto aumente. Então me diga onde escrevemos nossa condição. Escreva, na condição de índice existente. Eu carrego produtos com pontos entre colchetes, produtos existentes, quantidade de pontos de índice mais a quantidade que queremos adicionar é maior ou igual ao estoque de pontos do produto Se for verdade, retornamos a mesma resposta com o código de status 400 e, no método Jasen, objeto com propriedade de mensagem, estoque não é suficiente E, finalmente, concluímos nossa API head to cart. Então, vamos recapitular rapidamente essa API. Em primeiro lugar, verificamos se o ID do produto quantidade é passada pelo front-end ou não, o que podemos dizer como validar entradas Depois disso, verifique se o produto está disponível em nosso banco de dados ou não. Se não estiver disponível, retornaremos um erro na resposta, produto não encontrado. Depois disso, verifique se o produto tem estoque ou não. Se não houver estoque ou menos estoque do que a nossa quantidade , retornamos a resposta com mensagem, estoque não é suficiente. Depois disso, verifique se o usuário tem cartão ou não. Se ele não tiver carrinho, só então criaremos um novo carrinho. Depois disso, verificamos que o produto que queremos adicionar já está disponível no carrinho ou não. Se estiver disponível, verificaremos novamente o estoque final. Se também estiver disponível, basta aumentar a quantidade. Além disso, se o produto não estiver disponível, somente então colocamos o objeto do produto com os detalhes do produto. E, finalmente, contamos o total de produtos e preço total do carrinho usando método reduzido e salvamos o carrinho de forma simples. É assim que criamos a API head to cart. 143. Como chegar ao carrinho do usuário: Agora é hora de se exercitar. Quero que você crie uma nova API para obter os detalhes atuais do cartão do usuário de login. É muito simples. Eu sei que você pode fazer isso. Agora, vamos ver a solução. Então, o roteador dot gt e aponte para a barra frontal. Depois disso, adicionamos função de retorno de chamada assíncrona com solicitação Agora, na função de retorno de chamada, const card é igual a await card dot Aqui, passamos Object with user para solicitar dot user dot dot underscore ID e, no final, basta responder dot json, este Além disso, para obter o usuário na resposta, precisamos adicionar o middleware Orth E é isso. Vamos experimentar essa API, abrir o carteiro no cartão, criar uma nova solicitação chamada Obter o cartão de usuário URL para SDP, barra dupla da coluna, host local, barra da coluna 3.000, barra da API, barra CAT E agora aqui precisamos passar o token. Então vá para os cabeçalhos e aqui adicionamos a autorização. No valor, passamos o espaço do portador. Agora vá até a API de login, envie a solicitação, pegue aqui o novo token, copie isso e simplesmente em nossa API, colamos esse token. Agora vamos enviar a solicitação. Veja, aqui temos os dados do cartão. Parece simples. Além disso, é possível que o usuário atual não tenha o cartão porque nunca teve nenhum produto no cartão. Se for esse o caso, temos que retornar uma resposta diferente. Escrevemos se o cartão não estiver disponível e, em seguida, retornamos o ponto de resposta com status 404 não encontrado. Objeto Json de ponto com a propriedade de mensagem, cartão de usuário está vazio No final, se encontrarmos o cartão , enviaremos esse cartão como está. 144. Aumente a quantidade do produto: Agora, como sabemos, na página do cartão, talvez precisemos aumentar e diminuir a quantidade do produto em um. Então, vamos definir a API para esse recurso. Então, ponto do roteador, qual método usaremos. Então, como sabemos, nos dados do nosso cartão, precisamos apenas atualizar uma pequena parte dos dados, que é a quantidade, total de produtos e o preço total do cartão. Então, para atualizar poucos dados, qual método usaremos, certo, usaremos o método patch 0.2 increase e aqui precisamos do produto cujo usuário deseja aumentar a quantidade no carrinho. Também adicionaremos aqui o ID do produto como parâmetro de rota, o mesmo de antes. Além disso, precisamos de utensílios ortomodais porque somente o usuário de login pode aumentar a quantidade no cartão Depois disso, adicionamos a função de retorno de chamada ACN com a função de seta de solicitação e resposta Em primeiro lugar, obtemos o ID do produto a partir do ponto de solicitação PRMs, ID do produto Agora, vamos à parte lógica da consulta. Muitos estudantes me perguntam: como posso entender a lógica da consulta ou de qualquer recurso? Deixe-me te dar meu truque. Sempre que você quiser aplicar qualquer lógica , primeiro descreva essa lógica em linguagem humana simples. Por exemplo, aqui queremos encontrar a lógica de aumentar a quantidade em um para esse determinado ID de produto. Significa simplesmente que precisamos primeiro encontrar o cartão de usuário atual porque queremos atualizá-lo. Depois disso, encontraremos esse produto na matriz de produtos de cartão. E depois de encontrarmos o produto, simplesmente aumentamos o campo de quantidade do produto. Também podemos aumentar o total de produtos um e o aumento total do preço do cartão pelo preço atual do produto. Por fim, simplesmente salvamos o cartão atualizado. Veja como isso se torna simples depois de escrever as etapas lógicas. Primeiro, encontramos o cartão de usuário atual. O carrinho Const é igual a um ponto de peso do carrinho Fine one. No objeto de comparação, adicionamos o usuário para solicitar o ID de sublinhado do ponto do usuário Agora é possível que não encontremos o cartão, então é melhor retornar a resposta com erro. Se o carrinho não estiver disponível, retornaremos o status de ponto de resposta 404 pontos JSON, Objeto com cartão de mensagem não encontrado Bom. Agora vamos para a próxima etapa, que é encontrar o produto na matriz de produtos CAT. Já fizemos isso na API Head to Cart. Lembre-se, sim, aqui usamos o método de índice fino. Escrevemos um índice fino de pontos para produtos CAT dot. Aqui obtemos um único objeto de produto, função de seta e aqui retornamos a condição, ponto do produto, ID do produto. Esse é um ID de objeto, então temos que convertê-lo em uma string igual ao ID do produto, que obtemos do parâmetro de consulta. Essa expressão retornará o índice do produto que queremos atualizar. Então, armazenamos isso em uma variável chamada índice. Agora obtemos o índice. Em seguida, precisamos aumentar a quantidade desse produto de índice. Portanto, produtos com pontos de carrinho entre colchetes, passamos a quantidade de pontos de índice mais é igual a um Isso significa aumentar um na quantidade atual. Depois disso, também aumentaremos o total de pontos do carrinho de produtos, mais é igual a um, e também o preço total do cartão por ponto do cartão, mais é igual aos produtos do ponto do carrinho entre colchetes, preço do ponto índice E no final, aguardaremos o card dot CV. E, finalmente, o ponto de resposta Json pass Object com a propriedade da mensagem, produto e quantidade aumentou com sucesso Além disso, enviamos o cartão apenas para teste e pronto. Veja como nossa API parece simples e limpa. Agora vamos testar essa API, ver as mudanças e abrir o post Van. Aqui, criamos uma duplicata desse método de cartão postal e removemos seu nome para aumentar a quantidade do produto Agora podemos adicionar HECRT, aumentar reduzir o ID do produto que você deseja atualizar Além disso, aqui temos a autorização do cabeçalho e também alteramos o método para patch. Agora, vamos simplesmente enviar a solicitação. Veja, aqui eu recebo um token inválido porque meu token expirou Então, vá para a API de login e gere um novo token. Bom. Copie esse token. Simplesmente na API de aumento, paga o token no cabeçalho. Agora vamos enviar essa solicitação. Veja, aqui recebemos uma mensagem de sucesso, e anteriormente tínhamos três iPhones em nosso cartão, e agora temos quatro, então está funcionando Além disso, o total de produtos e preço total do cartão também estão funcionando. Deixe-me te fazer uma pergunta. E se passarmos a ID do produto, que não está disponível na matriz de produtos. Nós não lidamos com isso. Então, aqui, depois de obter o índice, passamos que o índice da condição I é igual a menos um, o que significa que não podemos encontrar o índice nos produtos do cartão Em seguida, retornamos o objeto Json de 404 pontos com status de ponto de resposta com o produto de mensagem não encontrado no cartão Vamos provar isso. Portanto, no local desse ID do produto, basta passar um e enviar a solicitação. Veja, aqui temos um produto não encontrado no carrinho. Ótimo. Agora, o que pode dar errado na API. Vamos pensar sobre isso. Quando aumentamos a quantidade do produto, ideal é que esse produto esteja em estoque. Por exemplo, se o iPhone 14 tiver apenas seis em estoque e já tivermos seis iPhones no carrinho e tentarmos aumentar mais um iPhone 14, idealmente, podemos fazer isso Não podemos aumentar a quantidade de iPhone para sete porque temos apenas seis iPhones em estoque Também podemos colocar mais uma condição antes de atualizar os detalhes do cartão. Se o cartão colocar os produtos em um pacote quadrado, indexe a quantidade de pontos, igual ao produto, estoque pontilhado Em seguida, retornamos o status do ponto de resposta, objeto JCN de 400 pontos com mensagem, produto, esgotamento de estoque. Gant aumenta o produto Agora, a questão é: como podemos obter esse estoque de pontos do produto? Certo, precisamos encontrar um produto da coleção de produtos. Na parte superior, após esse ID do produto, podemos constar que o produto é igual ao ponto do produto Fine By ID, e aqui passamos o ID do produto Agora, isso pode acontecer. Esse ID do produto não é válido, então podemos colocar aqui também uma condição. Já fizemos isso na API de postagem. Veja aqui. Então, vamos copiar essa condição e colá-la em nossa API de aumento. No comando antes do método find, verifique se o produto existe. Agora, vamos provar essa implementação. Então vá até o Postman, envie a solicitação. Veja, agora temos um erro interno do servidor. Agora selecione o endpoint e pressione Control plus D ou Command plus D. Obtendo a ID original do produto Envie a solicitação, C, aumento de quantidade em um. Novamente, envie a solicitação. C, recebemos seis iPhone, nosso estoque é oito, então enviamos a solicitação mais duas vezes. Veja, agora temos oito iPhones e vamos enviar a solicitação mais uma vez Veja, aqui temos um erro, produto está sem estoque, não é possível aumentar o produto em um. Agora nossa API está funcionando bem. 145. Reduza a quantidade do produto: Agora vamos definir rapidamente uma API ou diminuir a quantidade do produto. Também será o mesmo. Vamos copiar essa API aumentada e colá-la na parte inferior. Agora, primeiro de tudo, adicionamos aqui o comentário principal, diminuímos a quantidade do produto. Além disso, aqui alteramos o endpoint para diminuir o ID do produto. Agora vamos verificar essa API passo a passo, para garantir que não esqueçamos nada. Primeiro, obtemos o produto que também precisamos. Depois disso, achamos o carrinho bom. Depois disso, encontramos o índice, bom, agora aqui está uma coisa para diminuir a quantidade do produto para um, não precisamos verificar o estoque Mas também precisamos verificar mais uma coisa. Se atualmente estiver em nosso cartão, temos apenas uma quantidade de produto e tentamos diminuir essa quantidade de produto para uma. Nesse caso, temos que remover o objeto completo do produto da matriz de produtos. Não se preocupe, escreveremos uma lógica para isso depois de concluirmos a atualização. Lembre-se de que estou adicionando aqui um comentário, verifique a condição da quantidade um. Depois disso, temos que diminuir a quantidade do produto para menos igual a um Além disso, para o total de produtos, menos é igual a um, e aqui também, preço total do carrinho menos é igual a, aqui nós menos o preço do Em seguida, salvamos um cartão e alteramos essa mensagem para que a quantidade do produto diminua com sucesso. Agora temos que fazer pequenas mudanças nessa API. Vamos ao nosso comentário. Aqui adicionamos a condição I, ponto do carrinho, os produtos, o colchete, quantidade do índice é maior que o pão e depois diminuímos a quantidade Movemos essa linha no bloco I e depois disso, caso contrário, temos que remover objeto completo do produto que está disponível neste índice. Para remover o item da matriz em JavaScript, usamos o método Plis Portanto, os produtos com pontos de cartão pontuam Slic Index, que é o índice que queremos remover E então, no segundo argumento, passamos um, o que significa que queremos remover apenas um item. Com essa expressão, todo o objeto do produto será removido da matriz de produtos. Agora, aqui está uma coisa. Depois de remover todo o objeto do produto da matriz de produtos, não podemos deduzir preço total do cartão pois aqui precisamos do preço do produto Então, temos que fazer algo assim. preço total do cartão menos é igual ao preço do produto em pontos preço deste produto será obtido da coleção de produtos. Portanto, no aumento da API, alteramos esse ponto do cartão: o preço total do cartão mais é igual ao preço do ponto do produto. Portanto, o preço original do produto será adicionado ao total. Salve as alterações, vamos nessa API. Duplique essa API aumentada do produto e altere seu nome para diminuir. Altere o endpoint da API para cartão diminua e envie a solicitação Veja, agora temos apenas sete iPhones. Vamos diminuí-lo mais duas vezes. Veja, agora temos cinco iPhones e total de produtos e o preço também estão funcionando É assim que diminuímos a quantidade do produto. 146. Como remover um produto único do carrinho: Agora, em nossa página do cartão, talvez tenhamos a opção remover o produto completo do cartão. Não queremos diminuir a quantidade do produto um por um. Então, vamos definir a API para remover o produto do cartão. Então, começamos com a página de pontos do roteador, ponto final a barra, remova a coluna de barra, ID do produto Além disso, precisamos dos detalhes atuais do usuário, então adicionamos o middleware Orth e seguida, uma função de retorno de chamada com solicitação Agora, existem etapas muito semelhantes às da nossa API de diminuição. Vamos ver a API, o que precisamos no produto de remoção. Veja primeiro, precisamos obter um produto e depois um carrinho. Além disso, precisamos encontrar o índice do produto e também precisamos dessa condição. Copie esse código até aqui e cole-o na API de remoção. Agora, volte para diminuir a API e, como podemos ver, para remover todo o produto, precisamos apenas dessa linha. Copiamos isso e colamos em nossa API. Bom. Agora, depois disso, temos que atualizar o total dos produtos carrinho e o preço total do carrinho do carrinho. Vamos um por um. ponto total de produtos do carrinho menos é igual a, aqui precisamos da quantidade desse produto que temos no objeto do produto Suponha que tenhamos um total de sete produtos e quatro iPhones na matriz de produtos Agora, se tentarmos remover os dados completos do telefone do carrinho , para o total de produtos, teremos que menos sete menos quatro é igual a Portanto, temos que encontrar a quantidade que está disponível na matriz de produtos. Então, antes desse método de emenda, podemos fazer algo assim Total de produtos do carrinho, menos é igual aos produtos com pontos do carrinho. Aqui, acessamos objeto do produto que queremos remover, colchetes, índice e, seguida, pegamos a quantidade desse produto Você adivinhou corretamente. Podemos fazer o mesmo com o preço CAT total do ponto CAT menos é igual aos produtos com pontos de cartão, colchetes, quantidade de pontos de índice em produtos com pontos de carrinho entre colchetes, pontos de índice O motivo pelo qual removemos todo o objeto do produto no final é porque, se removermos esse objeto antes, como podemos acessar a quantidade e o preço do produto? Agora, por fim, simplesmente aguardamos o ponto C do cartão e, depois disso, o objeto Json do ponto de resposta com a propriedade de mensagem do produto foi removido com sucesso e também enviamos o cartão com ele objeto Json do ponto de resposta com a propriedade de mensagem do produto foi removido com sucesso e também enviamos o cartão com Agora, antes de experimentarmos essa API, podemos adicionar mais uma condição a ela. Então, imagine que temos apenas um produto no carrinho e também removemos esse produto. Agora, em vez de armazenar o cartão em branco no banco de dados, é melhor remover esse cartão para esse usuário. usuário deseja adicionar um novo item ao carrinho e , na API Head to Cart, já colocamos o código para criar o novo carrinho. Podemos verificar se esse produto é o único produto ou não no carrinho. Aqui, após essa condição de índice, podemos adicionar mais uma condição if. Aqui, verificamos se comprimento do ponto dos produtos do carrinho é igual a um e os produtos com pontos CAT entre colchetes, índice e ID do produto são iguais à ID do produto, que obtemos das permanentes Se essa condição for verdadeira, podemos remover o CAT completo. Portanto, aguarde CAT dot Fine By ID e DLT e passe GAT dot Em seguida, retornamos, respondemos, certifique-se de adicionar aqui return. Caso contrário, o código inferior também será executado. Portanto, certifique-se de adicionar aqui retornar. Objeto Json de ponto de resposta com propriedade de mensagem, carrinho removido com sucesso Além disso, você precisa converter o ID do produto do cartão, ponto em string Caso contrário, nossa condição não funcionará e pronto. Vamos experimentar nossa implementação, ver as mudanças e abrir o carteiro Duplique essa API de diminuição, altere seu nome para remover o produto do carrinho Bom. Agora, vamos enviar o endpoint da API para o Slash Cart, remover o ID do produto e enviar a solicitação E como temos apenas um produto em nosso carrinho, carrinho foi removido com sucesso. Então, como você pode ver, definir a API não é tão difícil. Basta dar os passos um por um e, se ficar confuso, escreva comentários para cada etapa que esclarecerão muitas de suas dúvidas. 147. Criando modelo de pedidos: Agora, antes de adicionar o gateway de pagamento, vamos criar uma nova coleção de pedidos para armazenar as informações sobre todos os pedidos e seu status. Então, na pasta models, criamos um novo arquivo chamado orders dot js. Bom. Agora, em primeiro lugar, importamos mangas const que é igual ao que exigimos de mangas Depois disso, o esquema de ordem de custo é igual ao esquema de pontos nu Mongoose E aqui definimos nosso esquema de coleção. Nós já sabemos disso, certo? Criamos um esquema várias vezes. Agora, na coleção de pedidos, precisamos de todas as coisas que adicionamos na coleção de cartões. Então, copiamos o esquema completo do carrinho. No esquema do pedido, colamos nosso esquema Temos usuários que solicitam produtos, total de produtos e também o preço total do cartão. Agora você pode se perguntar por que precisamos desses dados de todos os produtos? Precisamos dos dados desses produtos para armazenar o histórico do pedido do usuário. Se o usuário quiser ver quais produtos ele pediu anteriormente, temos que mostrar essa lista de produtos. Portanto, cartão e pedido são duas coisas distintas. Na coleção de cartões, armazenamos todos os produtos que o usuário deseja comprar. Os produtos no cartão podem ser adicionados, atualizados ou removidos. Mas quando o usuário finaliza a compra e efetua o pagamento, os dados do cartão são convertidos em um pedido, e nós removemos esses dados do cartão da coleção do cartão. Na coleta de pedidos, armazenamos dados permanentes para transações concluídas. E com isso, os usuários podem ver seus pedidos anteriores. Agora, nesta coleção, temos que adicionar mais alguns preenchimentos. Primeiro, transformamos o preço total do cartão no preço total. Em seguida, precisamos do ID de pagamento, do tipo string e do valor necessário para verdadeiro. Esse é o ID do pagamento. Obteremos esse ID no gateway de pagamento. E por esse ID, podemos ver qual método de pagamento o usuário usa para o pagamento, UPI ou cartão ou Net banking ou qualquer outra coisa. Em seguida, insira o status do pagamento para o objeto, digite a sequência de caracteres necessária para verdadeira. E nesse status, podemos mencionar o pagamento pago ou preenchido. Em seguida, o que queremos é o endereço de entrega, digite como string e requerido como true. À medida que movemos isso abaixo do preço total, por conveniência. Isso não importa. Agora, depois disso, queremos o status do pedido, digite a string e aqui podemos adicionar valores possíveis para esse campo, que é enum para array O primeiro valor pode estar pendente. Em seguida, podemos processar em seguida, CB. Além disso, ele pode ser entregue ou cancelado por padrão. Faremos com que o status do nosso pedido seja Faremos com que o status do nosso pedido Aqui não é o status do pagamento, é o status do pedido. Agora, podemos armazenar a data em que o usuário fez esse pedido, criado em tipo de objeto até a data e valor padrão como ponto de data agora. Como queremos a data em que esse pedido seja entregue, entregue no tipo de objeto até o momento. Por enquanto, esses campos são suficientes. Se, no futuro, precisarmos de mais campos , como sabemos, podemos facilmente adicionar preenchimentos a essa coleção Agora vamos criar uma coleção. Portanto, a ordem de custo é igual ao modelo de pontos Mongoose. Aqui, passamos um nome singular, que é ordem, e aqui passamos o esquema de pedidos Depois disso, finalmente, vamos modular exportações de pontos iguais à coleta de pedidos, e pronto. 148. Fluxo de trabalho de pagamentos: Anteriormente, adicionamos e atualizamos os recursos do cartão. Agora, quando nosso usuário quiser comprar as coisas disponíveis no cartão, precisamos integrar o pagamento em nosso aplicativo. Portanto, antes de mergulhar diretamente no código, vamos primeiro entender o fluxo de trabalho completo do pagamento. Então imagine que este é nosso usuário, veja os produtos adicionados ao cartão e, na página do cartão, clique no botão de finalizar compra ou pagar A etapa número um é, chamaremos nossa API de checkout pressionando este botão, como sabemos, temos os detalhes do nosso cartão em nosso banco de dados, então obtemos o valor total do preço do cartão dela Além disso, podemos informar em qual moeda ela deseja pagar. Agora, na segunda etapa, os detalhes, o preço e a moeda, enviaremos para o Payment Gateway. Agora, etapa número três, o Payment Gateway criará um formulário de pagamento e o exibirá em seu navegador ou telefone. Etapa número quatro, insira os detalhes de pagamento dela como cartão, UPI ou carteira que deseja usar, insira esses detalhes no formulário de pagamento e clique em pagar Lembre-se de que os detalhes de pagamento do usuário vão para o gateway de pagamento, não para o back-end, e é por isso que são seguros. Agora, passo a passo, gateway de pagamento, envie os detalhes de pagamento ao banco, valide os dados de pagamento pelo Se for verdade, o banco retornará com sucesso e, se for falso ou se nosso usuário não tiver saldo suficiente ou algo der errado, banco falhará na devolução. Portanto, o banco enviará esse status de sucesso ou falha ao Payment Gateway. Agora, etapa número seis, gateway de pagamento, envie o status de sucesso ou falha para nosso back-end. Se for bem-sucedido, executaremos alguma tarefa no back-end que queremos realizar, como adicionar os dados do cartão à coleta de pedidos, definir o status do pagamento como pago ou qualquer coisa que desejemos fazer. Agora, depois de concluir todo o processo na etapa sete, no back-end, mostramos que o pagamento do usuário bem-sucedido ou o pagamento falhou, simples assim. Portanto, o gateway de pagamento é como um intermediário que cuida dos pagamentos seguros, do modo de pagamento e transfere dinheiro diretamente para nossa Agora, existem muitos meios de pagamento disponíveis, como stripe, paper, razor pay e muito mais Mas esses três são os melhores. Agora, como podemos decidir qual gateway de pagamento queremos usar? Portanto, se estamos visando o público global , o Stripe é uma boa opção porque permite pagamentos internacionais e também permite Agora, as pessoas também permitem pagamentos internacionais, e as pessoas também são uma boa opção. Agora, se nosso negócio está sediado na Índia, então o sorpay é o melhor para nós Resorpay também pode lidar com pagamentos internacionais, mas só é adequada para empresas sediadas em transações estrangeiras na Índia Em palavras simples, em palavras simples, empresa está registrada na Índia e também deseja obter uma transação estrangeira. Para empresas globais e internacionais, portais como listras ou papel podem ser a melhor opção Portanto, neste curso, mostrarei a vocês duas reservas para empresas indianas e, se sua empresa estiver fora da Índia, também mostrarei a integração em papel A razão pela qual eu não posso te mostrar o stripe é porque, para o Demos, stripe não permite contas em alguns países, mas não importa qual gateway de pagamento eu mostre Se você entender a lógica do gateway de pagamento, poderá aplicar qualquer gateway de pagamento por conta própria. E esse é meu foco principal. Então, basta ver essas lições. Vou esclarecer a lógica por trás do gateway de pagamento. 149. Como implementar o gateway de pagamento Razorpay: Vamos configurar o resupe para nosso aplicativo Cardwig node. Criaremos e experimentaremos pagamentos como esse. Vai ser divertido. Além disso, se você estiver fora da Índia, poderá pular esta lição porque só poderá se registrar no currículo se estiver na Índia ou se sua empresa estiver registrada na Índia ou se sua empresa estiver registrada na Após esta lição, aplicaremos o pagamento em papel no qual qualquer usuário do país poderá criar uma conta. Agora vamos ver aproximadamente como esse pagamento funcionará. Então, quando o usuário clicar no botão PayNW, front-end chamará uma API. Vamos dar uma olhada. Nessa API, criaremos um pedido para AserPay fornecendo algumas informações sobre nosso exemplo, quanto valor queremos cobrar do usuário e em qual moeda queremos receber o pagamento. Agora, quando o RSR PE obtém essas informações, ele gera ordem, que é o objeto da informação com ID de objeto exclusivo E então precisamos passar esse ID de objeto para o front-end. Esse é o trabalho da primeira API. Agora, quando o front-end obtiver o ID do objeto, front-end abrirá a janela de pagamento do sor P. Passe o ID do objeto e alguns detalhes. Agora você pode perguntar por que precisamos passar o ID do objeto. Por meio desse ID de objeto, somente o revendedor PA obtém as informações sobre o pagamento Também nos ajudará na verificação do pagamento e em muitos outros benefícios. Agora, o usuário inserirá os detalhes do pagamento e clicará em pagar agora. Se o pagamento for bem-sucedido, Reser Pay gerará uma ID de pagamento exclusiva com assinatura e, em seguida, chamaremos nossa segunda API, que verificará nosso pagamento Na segunda API, verificaremos o pagamento. Motivo pelo qual precisamos verificar isso porque essa API está chamando do front-end. Qualquer pessoa pode manipular facilmente essas informações e fazer com que o pagamento seja bem-sucedido Portanto, verificaremos o pagamento de uma forma muito segura, o que também implementaremos nesta lição. Somente após o processo de verificação, se for bem-sucedido, criaremos um novo pedido em nossa coleção de pedidos e, em seguida, removeremos esse cartão de usuário. Pense no sor pay como um balcão de ingressos de cinema. Para a API 1, você vai até o balcão, que é o Razor Pay, diz a eles qual filme você quer assistir, informando o valor e a moeda, e então eles lhe dão o ingresso, que é um ID de pedido exclusivo Agora, para a API dois, depois de mostrar o ticket para a segurança, você assiste ao filme, o contador verifica se o ticket foi usado corretamente e atualiza os registros Portanto, para o razor pay no back-end, precisamos criar duas Primeiro, para criar uma ordem de pagamento razor, e a segunda API é para verificar o pagamento do razor Se verificarmos o pagamento com sucesso, depois disso, na última etapa, criaremos um novo pedido na coleta de pedidos e removeremos nosso cartão. Agora vamos começar criando a primeira API, que é para criar uma ordem de pagamento do usuário. Na pasta route, você criará um novo arquivo chamado orders dot gs. Agora, para adicionar rapidamente o roteador, abrimos o arquivo Route da placa, movemos essa linha do roteador na parte superior e copiamos essas duas primeiras linhas. Em nosso arquivo JS de pontos de pedidos, nós o colamos aqui. Agora, na parte inferior, temos que fazer com que as portas de pontos do módulo sejam iguais ao roteador. Agora vamos ver esse roteador no arquivo JS de pontos de índice. Então, no topo, const, order, Rowe é igual a require Aqui vamos para a pasta de rotas e pedidos. E na parte inferior, após as rotas do cartão, adicionamos app.us slash API slash Order e passamos aqui Order e passamos Bom. Agora podemos nos concentrar na criação de APIs Então, poste ponto do roteador, aponte para a barra do checkout Além disso, precisamos de um middleware mariposa porque queremos que apenas os usuários logados possam fazer o check-out e, finalmente, executar uma função de retorno de chamada com solicitação porque queremos que apenas os usuários logados possam fazer o check-out e, finalmente, executar uma função de retorno de chamada com solicitação e resposta. Aqui nesta API, queremos criar uma ordem de pagamento do usuário. E para isso, precisamos ser uma instância de pagamento. Então, no terminal, instalamos o pacote reser pay, NPM instala o ser pay na taxa de 2,9 0,5, que é a versão mais recente enquanto estou gravando Bom. Agora, no topo, inserimos o custo ser P igual a exigir ser P. Você pode me dizer por que eu dou essa letra maiúscula? Certo, porque é aula. Agora, em nossa API, criamos Cast reserp Instance igual a New reserp. Dentro dela, precisamos passar um objeto com duas propriedades ID de sublinhado da chave. Esse é o ID da chave do nosso aplicativo de pagamento de reservas. Em nosso aplicativo, armazenaremos essa chave no arquivo DOT ENV porque precisamos mantê-la privada Então, processe ponto por ponto reser py underscore key underscore ID Não se preocupe, nós os definiremos em algum momento. Depois da ID da chave, precisamos da chave sublinhada secreta para processar ponto por ponto ser pay, sublinhado, chave, sublinhado Agora, vamos definir essas duas variáveis no arquivo DOT ENV. Ou pagar, sublinhado, chave, ID de sublinhado é igual a deixá-lo E a seguir reserpunerScore, chave, sublinhado secreto. Nós os adicionaremos quando criarmos uma conta resorpay. Por enquanto, vamos concluir nossa API de checkout e, depois disso, criaremos uma conta reser pay Depois de criar a instância, podemos criar o pedido. A ordem de custo é igual a await reserpy instance dot orders dot Crie aqui, temos que passar o objeto de opções para este O primeiro é o valor. Digamos que passaremos aqui 500. Depois disso, precisamos passar a propriedade monetária. Isso especificará em qual moeda queremos prosseguir com o pagamento. Suponha que queiramos fazer o pagamento em rupia indiana, então passamos aqui o INR e, se quisermos fazer o pagamento em dólares americanos, passamos Mas certifique-se de que, se você usar a moeda de outro país , o pagamento interno de suas contas de pagamento de reserva deve estar ativo. Por enquanto, simplesmente passamos o INR. E por último, precisamos passar um recibo exclusivo. Isso é como uma etiqueta de nome para o pedido. Isso não afeta o pagamento, mas ajuda desenvolvedores ou empresas a reconhecer qual pedido é qual. Por exemplo, se tivermos vários pedidos, podemos usar esse ID de recibo para encontrar um pedido específico no painel do RSR Pi ou em nosso banco de dados Então, passamos aqui os backticks recebidos sublinhados em dólares, calibackets, data e ponto agora para gerar RECIPs exclusivos Isso gerará um pedido para nós. Aqui, simplesmente retornamos ponto de resposta Json, aqui passamos um objeto com poucas propriedades Primeiro, do sucesso à verdade, o que significa que criamos pedidos com sucesso. Em segundo lugar, ID do pedido para ID do ponto do pedido. Próximo valor para pedir o valor do ponto e moeda para pedir a moeda do ponto. Isso é tudo para a primeira API. Esta não é a API final, vamos melhorá-la mais tarde. Agora, antes de testar essa API, vamos também criar uma segunda API para que você não se confunda quando fizermos testes. Eu sei que você tem muitas perguntas, mas não se preocupe no final desta lição, tudo ficará claro. Depois dessa API, criamos uma nova API de postagem e apontamos para reduzir o pagamento e verificar se também precisamos do middleware OS para essa API e, por fim, função ASN com Agora, nessa API, precisamos de três coisas do corpo da solicitação. O segundo objeto é igual ao corpo do ponto da solicitação. O primeiro é ser pay, underscore order, underscore ID Em seguida, use pagamento, pagamento com sublinhado, ID de sublinhado e último usuário pague assinatura com sublinhado Com a ajuda desse ID do pedido e do ID de pagamento, precisamos criar um tipo de assinatura. Se essa assinatura e o usuário sublinhado, a assinatura será igual quando considerarmos que nosso pagamento foi verificado. Não se confunda. É muito simples. assinatura gerada pelo Secst é igual a aqui, temos que usar um módulo nodejs embutido que No topo, importamos que a criptografia const é igual à criptografia necessária Na parte inferior da nossa segunda API, crie o HMAC. Este é o método Nojs para criar um código de autenticação de mensagem base, HMAC Agora, no primeiro parâmetro, temos que escrever o algoritmo para criar o HMAC, que é um desses 256 No segundo parâmetro, temos que passar o segredo de resorp. Então processe dot Env dot ResorpUnderscore, K, underscore secret. Agora, após esse método create HMAC, adicionamos outro método chamado update Isso pega quais dados queremos ter. Aqui, devolvemos ticks, dólares em pacotes de Cali, redefinimos sublinhado, pedido e ID de sublinhado Aqui adicionamos símbolo de barra, dólar, pacotes Cully, sor pe, sublinhado, pagamento, ID de sublinhado Depois disso, adicionamos outro método dot digest e aqui passamos X. Eu recebo esse código da documentação do reser P. Você pode ler a documentação para obter mais detalhes. Esse código gerará uma assinatura. Agora podemos compará-lo com essa assinatura de sublinhado do reser Se a assinatura gerada não é igual à assinatura de sublinhado do usuário paga Se não forem iguais, aqui, retornamos o status de ponto de resposta, GSN de 400 pontos com objeto, sucesso para falso e mensagem para assinatura de pagamento inválida E depois disso, simplesmente respondemos JSON como verdadeiro e a mensagem ao pagamento foi verificada com sucesso verdadeiro e a mensagem ao pagamento Portanto, se, a partir do front-end, alguém passar um ID de pedido ou ID de pagamento falso, então, por esse processo, poderemos verificá-lo. Se o pagamento não for verificado, retornaremos a resposta com uma mensagem preenchida. E se for verificado, retornaremos a resposta com mensagem de sucesso. Portanto, esse não é um código completo. Vamos atualizá-lo após a degustação. Agora, antes de testar essa API, precisamos do ID da chave e do segredo do pagamento do revendedor. Lembre-se de que deixamos variáveis vazias no arquivo Dart NV. Vamos criar uma conta de ser pay e gerar esse ID de chave e chave secreta. Eles são muito semelhantes ao ID e à chave secreta que geramos ao implementar a autenticação do Google e do Facebook. Acesse o site reserp.com. E, como você pode ver aqui, temos apenas as opções Índia, Malásia e Cingapura, o que significa que somente essas empresas baseadas em países podem configurar o pagamento de revenda Mas também podemos aceitar pagamentos de qualquer país. Então, glicon se inscreva, digite seu endereço de e-mail Em seguida, crie uma senha. Certifique-se de seguir esses padrões de senha e clique em Continuar. Isso enviará a OTP por e-mail, então eu adiciono rapidamente a OTP aqui e clico em Agora, aqui está a coisa. Selecione o país sua empresa está incorporada, que é a Índia. Pode continuar, e agora temos que seguir mais alguns passos. Obviamente, estamos aceitando o pagamento. Não é uma configuração simples, pois estamos chamando outra API do site. Temos que fornecer nossos detalhes. Além disso, essas plataformas de pagamento podem mudar sua interface com muita frequência. Portanto, se no futuro você não tiver a mesma interface que eu , não se confunda. Basta fornecer os detalhes que eles estão solicitando e criar uma conta no Reser Pay Depois de criar uma conta, podemos criar o ID da chave e o segredo da chave. Aqui está perguntando, onde você gostaria de aceitar o pagamento? Por enquanto, selecione online e comece a embarcar. Agora, a seguir, de onde seus clientes estão pagando? Se seus clientes forem da Índia, selecione Índia. Mas aqui, eu seleciono fora da Índia e começo a embarcar. Vai levar algum tempo. Agora escrevemos nosso nome. Certifique-se de escrever seu nome legal. Continuar. Em seguida, verifique seus detalhes de contato, escreva seu número de celular e ele enviará o ODP, escreva esse ODP e clique em Continuar Agora aceite o pagamento aqui que eu seleciono no meu site. Se você quiser um aplicativo ou qualquer coisa , você também pode selecioná-los e continuar. Aqui, temos que adicionar o link do nosso site. Além disso, verifique este site. É legal ou não? Então, se você tem seu site, adicione-o aqui. Por enquanto, eu não tenho, então clique em adicionar carta e adicionar carta. Agora selecione seu tipo de negócio. Eu seleciono não registrado. Além disso, se você selecionar um tipo de negócio não registrado, não poderá aceitar pagamentos internacionais no modo ao vivo Para isso, você precisa de uma empresa registrada. Atualmente, não temos nenhum negócio registrado, mas se você tiver, selecione registrado. Além disso, não se preocupe em aceitar pagamentos internacionais. Não precisamos fazer nenhum trabalho extra. Só precisamos de uma empresa registrada, e o Reserpy permitirá que você aceite pagamentos internacionais Agora adicione seu número pessoal do Pan, que todos nós editamos aqui e clique em Continuar. Aqui, recebo um erro no meu nome, então escrevo meu nome legal, que tenho no cartão Pun, e continuo Agora carregue seu cartão PN pessoal, selecione, carregue, selecione seu documento e abra-o. Isso levará algum tempo. E continue. Agora eles estão sugerindo que concluamos o QIC. Selecione sua categoria de negócios, eu seleciono sua educação. Se você tiver outra categoria, selecione de acordo com ela. Em seguida, selecione sua subcategoria, selecione o que você deseja. Em seguida, qual é o seu modelo de negócios? Além disso, selecione isso de acordo com suas necessidades e continue. Depois disso, temos que adicionar detalhes bancários. Aqui, precisamos do número da conta e do código IFSE da agência da sua conta Vocês dois entram na sua caderneta. Certifique-se de escrever o número da conta na qual você deseja aceitar o pagamento. Eu preencho esses detalhes e clico em Continuar. Ele verificará esses detalhes. E pronto. Em seguida, temos que selecionar o código de propósito. Deixe-me tentar continuar diretamente. Está dando erro. Temos que selecionar o código de propósito. Podemos pesquisá-lo pelo grupo. Mas para testar, eu simplesmente seleciono esse p00 14 e continuo Em seguida, você tem um código importador-exportador? Não, eu não aceito os termos e clico em Continuar. Agora é hora da política de negócios. Aqui, eles fazem muitas perguntas importantes, como cancelamento e tempo de reembolso. Eu os seleciono para sete dias, você pode selecionar de acordo com suas necessidades, tempo de processamento do reembolso para três a cinco dias, o que é bom, mas nove a 15 por segurança. Além disso, o tempo de salto é de oito a 14 dias. Agora, também precisamos fornecer o número de contato de suporte. Eu também tento pular isso, mas está dando um erro Então, escrevo meu número e também escrevo meu endereço de e-mail e clico em Criar páginas de política. Aqui você pode ver as páginas, clique em Continuar. Aqui temos links de políticas. Continuar. Envie sua inscrição. Aqui, tento concluir o processo de KYC do vídeo, mas aqui recebo um erro, então tento várias vezes, mas nada acontece Eu decido pular isso. Eu fecho todas as páginas e tento abrir serpy.com. E tente fazer o login com a conta que acabei de criar, mas ela está carregando e carregando. Então abra a janela anônima e abra o openerp.com. Se você gostar do login, digite o e-mail, continue e digite sua senha. Bom. Aqui temos o painel SRP Por enquanto, estamos no modo de degustação. Podemos mudar isso a partir daqui, mas não mude por enquanto. Agora, para obter a APIKey, vamos para a opção de conta e configuração E aqui, na configuração do site e do aplicativo, usamos as chaves de API e geramos a chave Taste, ela nos enviará OTP, escreverá a OTP e simplesmente clicará em Veja, aqui temos o ID da chave e o segredo da chave. Agora, primeiro, copiamos o ID da chave de volta para o código VS e, no arquivo ENV, colamos o ID da chave dessa variável Novamente, copie o segredo da chave e cole-o na variável secreta do arquivo ANV Salve esse arquivo e , no site, basta clicar em Baixar para fazer backup. Agora, vamos testar nossas duas APIs. Está funcionando ou não. Então, como sabemos, precisamos de um front-end para testar essas APIs, porque no front-end, abriremos a página RSRPEPayment Então, aqui eu criei uma página SDML simples chamada RSRPFront end Você verá esta página abaixo desta lição, e ela também está disponível na pasta Resources project to. Faça o download e simplesmente faça isso em seu projeto atual. Agora, vamos executar esse arquivo STML. Então, clique com o botão direito sobre isso e clique em Copiar caminho. Em nosso navegador, siga esse caminho. Veja, aqui temos o título e um botão simples. Se você quiser ver o que aconteceu quando clicamos nesse botão , você pode assistir ao arquivo STML, é muito simples Deixe-me mostrar também que temos que mudar alguns valores. Então, aqui na parte inferior, na tag do script, eu adicionei uma variável que você pode passar para seus dados. Primeiro, temos o endpoint do pedido, que é o endpoint da nossa primeira API E segundo, temos o endpoint de verificação. Você tem endpoints diferentes pode substituí-los de acordo com seu endpoint Em seguida, temos o endereço de entrega. Aqui você pode escrever seu endereço. Depois disso, a moeda do usuário, que é definida como INR, mas você também pode passar USD ou Euro, etc., se o pagamento do usuário tiver um pagamento internacional ativado Depois disso, temos o ID da chave SRP. Aqui, você precisa escrever sua ID de chave. Eu copio meu ID de chave do arquivo ENV e colo aqui. Certifique-se de escrever seu próprio ID de chave. Caso contrário, isso não funcionará. Em seguida, temos togon. Aqui, você precisa passar seu token JWT. Agora, atualmente, em nosso aplicativo, definimos um prazo de validade de apenas 2 horas, que é um pouco irritante para Porque temos que criar o token JWT repetidamente. Assim, podemos remover a expiração do login e simplesmente adicionar a expiração na fase final do projeto Abra as rotas do usuário e, na parte inferior, removemos esse objeto com a propriedade expirada Agora vamos gerar um token que nunca expirou. Abra o Postman e abra a API de login e simplesmente envie a solicitação Aqui, copiamos esse token e, no arquivo SDML, simplesmente o colamos aqui Em seguida, adicionei esse evento ao clicar para esse botão de pagamento. Em primeiro lugar, chamamos essa API de pedidos usando o método fetch e com esse token Como sabemos pela API do pedido, obteremos os dados do pedido. Nós temos isso aqui. Se os dados não tiverem sucesso , mostraremos alerta com mensagem de falha. Agora, e se recebermos ordem de pagamento do revendedor com sucesso do back-end Em seguida, abriremos a janela de pagamento do Resb. Aqui, a partir do front-end, temos que passar por essas opções com reserp. Veja, aqui temos o valor da chave, moeda, nome, ID do pedido e, finalmente, temos o manipulador Esse manipulador é muito importante, que é a função. O RSR P executa essa função de manipulador quando o usuário insere as informações corretas e o pagamento é processado com sucesso. Então, após um pagamento bem-sucedido, chamamos nossa segunda API para verificar o pagamento. Se essa verificação for bem-sucedida, mostraremos um alerta de sucesso e, se falhar , mostraremos erro de campo. E, finalmente, para abrir o resorpe, criamos uma nova instância reserp e passamos opções inteiras aqui Então, simplesmente usando reserp dot Open, abrimos a página reserpPayment com Por fim, temos esse campo de ponto de pagamento que será executado quando o usuário inserir detalhes de pagamento incorretos ou se não tiver saldo suficiente , essa função será executada de forma simples. Agora, vamos simplesmente experimentar nossa implementação. Estou muito empolgado com isso. Salve esse arquivo e volte ao nosso navegador, atualize a página e simplesmente clique no botão de pagamento Taste Uma coisa acontece, isso não é justo. Vamos verificar o que acontece. Então, ao inspecionar usando F 12 aqui no console, podemos ver que recebemos um erro acesso à API FechTo checkout da origem nula foi Esse é um erro muito popular para desenvolvedores full stack. Isso acontece porque, por padrão, nosso aplicativo Express não pode aceitar chamadas de API de nenhuma origem. É necessário habilitar o curso em nosso aplicativo Express. Então, de volta ao código VS, abra um novo terminal e escreva, curso de instalação do NPM e pressione Enter Agora, no arquivo JS com pontos de índice na parte superior, importamos o curso de custo igual ao curso obrigatório. Então, na parte inferior, antes desse ponto expresso JS e no meio, onde adicionamos app dot Ug aqui , chamamos essa função de curso e pronto Salve as alterações e certifique-se de que nosso servidor esteja funcionando. Bom. Agora atualize a página e vamos clicar novamente no botão de pagamento Veja, a janela de pagamento RSR P está aqui. Aqui temos esses tipos de métodos de pagamento, como cartões, internet banking, carteira, carta, etc Acho que a UPI não está aqui porque minha empresa não foi verificada Agora, no lado esquerdo, obtemos o resumo do preço, que é cinco rúpias no final do valor, passamos de 500 aqui e estamos recebendo pi Por quê? Portanto, no valor preenchido, temos que passar o valor na menor unidade da moeda. E qual é a menor unidade em nosso país, o PSA, que é 100 PSA, é igual a uma E aqui passamos 500 PSA, que se converte em rupia Pi Então, se mudarmos isso para, digamos, 50.000, salve as alterações e atualize a E se clicarmos novamente no botão de pagamento, veja, aqui temos 500 rúpias Portanto, certifique-se do valor do pagamento. É por isso que criei esse modelo de front-end, para que você possa entender todo o processo com muita clareza. Além disso, no canto superior direito, podemos ver que estamos no modo de degustação porque criamos o ID da chave e o segredo da chave para o modo de degustação Agora, vamos provar o pagamento. Então, para provar o pagamento, primeiro, vamos até os cartões Aqui, para fins de degustação, ser pay fornece alguns detalhes do cartão Além disso, eles forneceram detalhes completos sobre a documentação. Eu lhe darei o link desta página no lado direito abaixo desta lição. Então, aqui vamos às cartas. Vamos testar o cartão indiano, copiar o número desse cartão e, em nossa página, colá-lo aqui. Agora passe aqui qualquer data futura de expiração, como 12 barra 30 e número CVV, vamos passar 111, fazer o pagamento, proteger o cartão, talvez mais É o processamento e qual cenário queremos testar primeiro, sucesso ou fracasso, vamos escolher o fracasso. Está carregando. E veja, o pagamento falhou, e também recebemos o alerta de falha no pagamento. Agora vamos tentar o sucesso. Novamente, no número do cartão, veja se está carregando, selecione sucesso. E aqui temos essa bela animação e, em seguida, recebemos o pagamento bem-sucedido. Além disso, recebemos aqui o pagamento verificado com sucesso , obtido de nossa segunda API. Portanto, nossas duas APIs estão funcionando bem. Se quiser experimentar outro método de pagamento , você também pode fazer isso. Basta verificar a documentação desse método de teste. Agora vamos atualizar nossa API para uso real. Então, como sabemos, nosso pagamento está funcionando. Agora podemos melhorar nossas APIs e torná-las realistas. É muito simples. Deixe-me te mostrar. Então, o que você deseja alterar na API de pedidos? Número um, atualmente estamos passando quantidade estática aqui, mas isso não está certo. Temos que repassar o preço total do cartão do usuário. Em segundo lugar, também estamos passando o IR em sua moeda , mas o usuário pode decidir em qual moeda deseja pagar. Então, queremos fazer apenas essas duas mudanças. Vamos começar obtendo o valor do cartão. Portanto, antes dessa instância de reinicialização, escrevemos const, cart e await cart C, a entrada automática Então, na parte superior, o custo carrinho é igual a exigir que coloquemos uma pasta nos modelos e coloquemos nesse carrinho. Agora, em nosso carrinho de API, dot Fine one, e aqui no objeto, passamos o usuário para solicitar o ID de sublinhado do ponto do usuário do ponto Agora, isso retornará o objeto do carrinho, mas temos que passar a condição se o CAT não estiver disponível ou o comprimento do ponto do produto CAT for igual a zero, então retornaremos a resposta com mensagem JCN de status 404 pontos para Agora, no lugar desse valor, temos que passar o preço total do CRT do ponto do carrinho para cem, porque temos que passar o valor na menor unidade da moeda Vamos provar isso, salvar as alterações, atualizar a página e clicar em Taste Payment Se verificarmos o console, veja, aqui obtemos um erro. É o erro 404, que significa que o cartão não foi encontrado Ah, lembre-se, na lição de remover carrinho, removemos o carrinho removendo o último produto da matriz de produtos, então temos que adicionar um produto em nosso carrinho, acessar Postman, abrir na API do carrinho Aqui temos que atualizar o Togan, copiá-lo da API de login e colá-lo no cabeçalho de autorização Bom. Agora envie a solicitação, produto adicionado. É um iPhone, ótimo. Agora, volte ao navegador e atualize a página e, novamente, experimente o pagamento Veja, aqui temos o preço do nosso cartão. Agora, como sabemos, no banco de dados, armazenamos todos os preços dos produtos em dólares americanos, e é por isso que estamos recebendo dois iPhones nesse preço Mas se você estiver usando o Razor Pay, sua empresa estará na Índia e, muito provavelmente , seus usuários-alvo também serão indianos Então, nesse caso, no banco de dados, você precisa armazenar o preço na moeda indiana. Agora, vamos supor que você queira atingir público global e armazene o preço em dólares americanos. Nesse caso, você precisa converter o preço do dólar moeda indiana e depois repassá-lo no valor. Deixe-me mostrar como podemos fazer isso. Portanto, para converter o valor do dólar na moeda indiana, precisamos da taxa de câmbio atual Não podemos confiar na taxa de câmbio estática. Então, chamaremos uma API para obter a taxa de câmbio exata. Então vá até o noivo e pesquise a taxa de câmbio api.com. Essa é a popular API de taxas de câmbio. Agora, para obter a taxa de câmbio, precisamos da chave de API para isso. Então, aqui inserimos nosso e-mail e simplesmente clicamos em GetVree Key Aqui, temos que criar uma senha, aceitar os termos e gerar a APIKey. O que é isso? Conclua a verificação e, em seguida eles enviarão a chave de ativação da API em seu e-mail. Abra esse link e aqui temos a chave da API. Podemos ver que podemos enviar 1.500 solicitações de troca. Se você quiser receber mais solicitações, precisará pagar por isso. Como funcionam todas as APIs de taxa de câmbio. Por enquanto, não se preocupe com isso. Basta copiar essa chave e, em nosso arquivo ENV, adicionamos a API de pontuação da taxa de câmbio, chave de sublinhado é igual a colar sua chave de API Salve esse arquivo e volte para a página de taxas de câmbio. Aqui, temos que encontrar a API, acessar a visão geral do Doc. Aqui temos APIs, uma para obter todas as taxas de câmbio e outra para obter o par Vamos conversar em pares. Aqui, obtemos a API, então copie isso e, em nossa API, vamos criar uma função separada para obter a taxa de câmbio. Então, Const, a taxa de câmbio do relógio é igual à função de seta. Agora, nessa função, chamaremos essa API de taxa de câmbio. Portanto, a resposta const é igual a wedge, e aqui em segundo plano, simplesmente passamos o simplesmente passamos Agora temos que mudar algumas coisas. Aqui no local da sua APIE, temos que escrever colchetes de Cully em dólares, processar troca ponto a ponto, taxa de sublinhado, sublinhar a chave de sublinhado Certifique-se de escrever o nome correto da variável ENV. Agora, finalmente, temos duas moedas. primeira é a moeda base, que é a moeda na qual adicionamos o preço em nosso banco de dados, e a segunda é a moeda de destino na qual queremos converter. Portanto, nossa moeda base é USD porque, no banco de dados, adicionamos o preço dos produtos em USD e queremos converter essa moeda em INR. Portanto, nossa moeda alvo é o INR. Também no local de passar valor estático da moeda de destino, podemos torná-la variável. Então, no parâmetro, obtemos moeda alvo e passamos essa moeda alvo calibrada do dólar Agora, como sabemos, buscar a API é uma tarefa rudimentar assíncrona. Temos que esperar aqui pela resposta. E para usar await, temos que tornar essa função assíncrona. Lily Agora, essa resposta retornará dados como esses. Aqui precisamos dessa taxa de conversação. Depois de obter a resposta, precisamos converter esses dados em JSON Os dados de custo são iguais a await response dot JSON. Agora, a partir dessa função, podemos simplesmente retornar taxa de sublinhado da conversa por pontos de dados Bom. Agora, em nosso OrderyPi, simplesmente contamos aqui o valor, contamos a troca, taxa de sublinhado é igual ao peso, patch, taxa de câmbio, função e, como argumento, passamos nossa moeda alvo, que Agora, depois de obter a taxa de câmbio, criamos que o valor constante é igual ao ponto do cartão , o preço total do cartão na taxa de sublinhado do câmbio, e temos que arredondar esse Então, envolva essa expressão com parênteses e simplesmente adicione um ponto ao fixo e passe aqui dois Agora, no valor, passamos o valor para 100. Agora vamos verificar essa implementação. Salve esse arquivo novamente no navegador, atualize a página e clique em Taste o pagamento Veja, agora obtemos o valor na moeda indiana. Ótimo. Agora, vamos supor que queremos que nosso usuário possa transmitir o valor alvo. Então, obtemos o valor alvo do usuário no corpo do ponto da solicitação. O objeto Secst é igual ao corpo do ponto da solicitação e aqui obtemos a moeda E como valor padrão, passamos aqui a moeda do nosso banco de dados, que é USD. Agora, no lugar dessa moeda de destino codificada, passamos nossa variável monetária, que nosso usuário passa no corpo do ponto da solicitação Além disso, aqui está uma coisa. Se nossa moeda base e moeda de destino forem as mesmas, não precisaremos buscar a taxa de câmbio, certo? Então, vamos fazer modificações em nosso código. Antes dessa taxa de câmbio, aprovamos a condição I de que a moeda seja igual a USD, que é o valor do nosso preço no banco de dados. Se ambos forem iguais, então temos que fazer com que o valor seja igual ao preço total do cartão. Caso contrário, podemos calcular uma quantidade como essa. Então, movemos essas duas linhas aqui, removemos essa const e, na parte superior, definimos let amount igual a zero Portanto, substituímos esse valor acordo com nossa condição. E também nas opções de pedidos, temos que passar essa moeda, guardar as alterações e provar nossa implementação Consulte-nos a página, clique em provar o pagamento, veja, aqui recebemos INR porque, a partir do front-end, estamos enviando moeda como INR Se você quiser mudar isso, abra STMLFle vá até essas variáveis Aqui, na moeda do usuário, passamos CAD por dólar canadense. Salve esse arquivo, atualize a página e envie a solicitação. Veja aqui que obtemos valor em dólares canadenses. Além disso, se não passarmos seu campo de moeda na chamada do EPI, salve-o, atualize a página e envie a solicitação novamente Veja, por padrão, ele atinge o pico em USD. Ótimo. Além disso, se sua conta razor pay não tiver recurso de pagamento internacional, você não poderá fazer pagamentos internacionais É a política do usuário paga. Se você quiser verificar o recurso de pagamento internacional da sua conta, acesse suas contas e defina a opção de sua conta do ser Bay. Verifique se você está no modo ao vivo. Aqui, não consigo passar para o modo E porque essa conta não foi verificada. Se você puder entrar no modo ao vivo , acesse os pagamentos internacionais no blog de pagamentos. Que você pode ver que seu recurso de pagamento internacional está ativado ou não. Atualmente, estamos no modo de teste e também testaremos o campo em nosso pagamento internacional. Então, melhoramos nossa primeira API. Agora vamos passar para o segundo. Agora vamos melhorar nossa segunda API. Não se preocupe, pois não precisamos fazer muita coisa. Apenas criaremos novos dados do pedido no banco de dados e removeremos o cartão do usuário se o pagamento for bem-sucedido. Se o pagamento não for verificado, estamos executando esse bloco de código. Se o pagamento for bem-sucedido, poderemos escrever um código aqui antes de retornarmos a resposta bem-sucedida. Aqui criamos o custo, novo pedido é igual ao novo pedido. Certifique-se de inserir esse modelo de pedido. Portanto, no topo, a ordem de custo é igual à exigência de que tenhamos um modelo mais cheio e, nesses pedidos Bom. Agora, na parte inferior, temos que passar o novo objeto de pedido aqui. Em primeiro lugar, nesta ordem, adicionamos o usuário para solicitar o ID de sublinhado do ponto do usuário Depois disso, precisamos de produtos e, com isso, armazenaremos todos os produtos que pedimos Como podemos obter essas informações? Certo, podemos obtê-lo pelo back-end. Antes desse pedido, encontramos o custo, carrinho é igual a oito pontos do carrinho Fine Vn. Aqui no objeto, passamos a condição do usuário para solicitar o ID de sublinhado do ponto do usuário ponto Simplesmente nos produtos encomendados, passamos os produtos para os produtos CAT dot. Em seguida, totalize os produtos até a CRT Total Products. Em seguida, temos o preço total em relação ao preço total do CRT. Em seguida, temos o endereço de entrega, que precisamos obter do front-end. Por enquanto, deixe como está. Em seguida, adicionamos status de pagamento a pago, ID de pagamento ao pagamento de reserva, sublinhado, pagamento , ID de sublinhado E como informação extra, podemos armazenar ReserpeOder ID, reservar sublinhado, ID de sublinhado Mas temos que adicionar esse campo em nosso esquema de pedidos. Depois desse campo, adicionamos reserpeOder ID à string. E é isso. Nós passamos todas as informações que precisávamos. Agora podemos armazenar esse novo pedido, então aguarde o novo pedido Dot CV E depois de salvar o novo pedido, podemos remover nosso cartão do banco de dados. Então aguarde o cartão dot deleteB aqui já temos o cartão. É por isso que usamos diretamente o card dot delete one. Se não obtivermos o cartão aqui , teremos que usar o método CRT dot Fine one e delete como este, e pronto Agora só precisamos passar o endereço de entrega na propriedade do pedido. Então me diga de onde obtemos o endereço de entrega. Certo, nós entendemos isso do front-end. No corpo da solicitação de verificação de pagamento, podemos obter o endereço de entrega porque, no front-end, já passamos o endereço de entrega. Veja aqui eu passo o endereço de entrega. Agora, deixe-me te dar uma situação. Imagine que o usuário esqueceu de passar o endereço de entrega. Agora, como podemos entregar o produto a esse usuário? Temos que garantir que o usuário passe esse endereço de entrega. Portanto, aqui podemos escrever se o endereço de entrega não estiver disponível, retornaremos a resposta com o Código de Status 400 para solicitação de aposta e, no objeto JSON, passamos uma mensagem para fornecer seu endereço de entrega Agora, aqui está mais uma coisa. Sabemos que essa API de verificação de pagamento será executada após o pagamento ser feito. Não podemos dizer agora, usuário, eles não fornecem o endereço de entrega, então podemos fazer mais uma coisa Podemos simplesmente colocar essa condição no início da nossa primeira API. E aqui obtemos endereço postal do corpo do ponto da solicitação Portanto, nosso front-end precisa passar o endereço Zipping nessas duas APIs Além disso, em nossos dados de pedidos, definimos o endereço postal como endereço de entrega e pronto Aqui, nossa parte de implementação acabou. Vamos ver se estamos passando endereço postal nas duas APIs ou não Então, no arquivo de modelo do ser P, podemos ver aqui na segunda API, que estamos passando o endereço postal como endereço posta 150. Pagamento internacional usando PayPal: Vamos ver como podemos implementar gateway de pagamento internacional em nosso aplicativo de nós. Então, como sabemos, para pagamento global, temos duas opções muito populares. Temos listras e temos papel. Nesta lição, implementaremos um papel como esse. Vamos implementá-lo em nosso back-end, prová-lo com o front-end e também aqui podemos ver os pagamentos de degustação. Então vai ser divertido. Este vídeo é para pessoas de qualquer país. Vamos começar isso. Além disso, atualmente, o stripe é única opção de solicitação para o meu país, então eu posso mostrar a demonstração do Stripe Se, no futuro, eles permitirem , eu também criarei uma lição sobre isso. Agora vamos entender o fluxo de trabalho do gateway de pagamento Paper. Então, quando o usuário clicar no botão Checkout, criaremos uma API, digamos, criaremos um pedido API criará uma ordem para o pagamento em papel com alguns detalhes, como quanto queremos receber em qual moeda queremos que o usuário pague USD ou Euro. Lembre-se de que esse pedido é um pedido em papel, não nossa coleção de pedidos. Agora, essa API gerará o ID do pedido usando papel e simplesmente retornará esse ID do pedido para o front-end. Ao usar esse ID do pedido, papel abrirá uma página de pagamento na qual o usuário poderá inserir detalhes sobre o pagamento. Agora, depois que o usuário inserir os detalhes do pagamento, chamaremos outra API para capturar esse pagamento Basicamente, por meio dessa API, permitiremos o pagamento dos usuários, adicionaremos nossa conta comercial em papel e, em seguida, criaremos os dados do pedido e, após o pagamento bem-sucedido, criaremos os dados do pedido e confirmaremos o pedido do usuário. Portanto, para implementar o pagamento em papel, precisamos criar duas APIs em nosso backhand nodejs O primeiro para criar o pedido e o segundo é para capturar o pagamento em nossa conta Eu sei que você tem muitas perguntas, mas não se preocupe. Depois de concluir esta lição, você entenderá melhor todo o fluxo de trabalho. Então, vamos criar essas duas APIs. Além disso, se você implementar o gateway de pagamento SRP da lição anterior, precisará repetir pequenas coisas como remover a expiração do token, etc Tenho que repetir para que todos cheguemos em uma página. Desculpe por isso. Espero que você possa entender isso. Agora, na pasta de rotas, você precisa criar um novo arquivo chamado orders dot js. Eu criei esse arquivo com duas APIs porque, na lição anterior, mostro a integração com o SRP, mas essas duas APIs são separadas dessa integração de pagamento Você pode ignorar isso totalmente. Agora, para adicionar rapidamente a rota, basta copiar as duas primeiras linhas de código das rotas do cartão e colá-las no arquivo de rota de pedidos. No final, você precisa fazer com que o módulo dot Xbards seja igual ao roteador Além disso, você precisa adicionar esse roteador no arquivo index dot js, que as rotas Const Order sejam iguais a require Got routes folder e Orders Na parte inferior, depois das rotas do cartão, você pode adicionar app.us slash API slash Order e passar Order Agora você pode se concentrar na criação de APIs. Então, em nosso arquivo, o roteador pontuar e apontar a barra Pessoas e a barra Criar pedido Aqui também precisamos do middleware OS porque queremos que apenas usuários logados possam acessar essa API Além disso, certifique-se de inserir Osmddleware na parte superior e, depois disso, em retorno de chamada Agora, nesta função, sabemos que queremos criar um pedido em papel. Para isso, primeiro, temos que configurar P. Na pasta de configuração, temos que criar um novo arquivo chamado paper dot js. Primeiro de tudo, definiremos a variável para alguns detalhes. Portanto, o papel const é igual ao objeto. Primeiro, o ID do cliente, que é o ID do cliente do nosso aplicativo, depois o segredo do cliente, que é a chave secreta do nosso aplicativo em papel e, por fim, também precisamos do URL base. Esse é o URL base da API em papel. Todos esses detalhes serão armazenados no arquivo NNV por motivos de segurança Então, aqui passamos o processo ponto por ponto, sublinhado, ID sublinhado do cliente E na segunda propriedade, escrevemos papel process.nw dot, E, por fim, escrevemos o ponto E do processo e o URL em papel, sublinhado, base e sublinhado Agora, vamos definir essas três variáveis no arquivo ENV. Portanto, o sublinhado PPL, o ID do sublinhado do cliente é igual a deixá-lo em branco e, em seguida, o sublinhado do papel, segredo é O URL do sublinhado base do sublinhado do papel é igual a. Nós os adicionaremos quando registrarmos uma conta comercial em papel. Está bem? Por enquanto, deixe como está. Agora, no papel, quando queremos criar um pedido em papel ou capturar o pagamento no bootstep, precisamos criar um token exclusivo como o JWT Então, para gerar esse token, podemos criar uma função para isso. O token Const G Xs é igual à função de seta. Agora, para gerar o token, usaremos a API de pessoas oficiais. Portanto, para chamar a API , usaremos o Axos. Axios é o pacote para chamar a API em JavaScript. É muito mais fácil do que usar o método fetch. Terminal de caneta, NPM, instale o Axios. Bom. Agora, para usar esse pacote Axios na parte superior, o custo de importação do Axios é igual ao de exigir Agora, em nosso Gate aces to confunction, aguardamos axios dot aqui, temos que adicionar o método SDDP E nesse método, na primeira posição, adicione o endpoint da API em backticks, dolar Cali Brackets, dot BRL V one, O oth, two, slash token Agora, no segundo lugar, que é o corpo, temos que passar códigos duplos. Conceder, o tipo de sublinhado é igual às credenciais de sublinhado do cliente E em terceiro lugar, passamos Configure Object. Primeiro, Ah, para se opor, use um nome P dot client ID. E a seguir, temos a senha para o segredo do cliente ppt. Agora, depois do Oath, adicionamos cabeçalhos ao objeto no tipo de conteúdo de códigos duplos, dois em códigos duplos, aplicativos codificados em URL xWWWfm E isso é tudo para essa API. Essa API gerará um token em excesso para nós, então nós o armazenamos em resposta variável. E então simplesmente retornamos a resposta, dados de pontos, ponto Xs e como token de código. Agora, para usar await, tornamos essa função assíncrona e talvez esse código possa nos dar erro Portanto, é melhor agrupar esse código no bloco try and cache. Então, tente pegar bloquear e mover esse código no blog Try. E no cache, nós consolamos o log de pontos, erro na busca do token de acesso E escrevemos essa mensagem de ponto de erro. Simplesmente no final, fazemos exportações de pontos do módulo iguais ao objeto. E aqui adicionamos papel a papel, ou podemos escrever apenas papel e obter o token de acesso para obter o AcessKen Salve esse arquivo e volte para nossa rota de pedidos. Agora, para criar um novo pedido em papel, usaremos outra API P. Você pode obter todas essas APIs na documentação em papel. Não se preocupe com isso. Portanto, o custo de resposta é igual a aguardar a Axios para enviar solicitações e qual solicitação queremos enviar para publicação Então, poste no primeiro argumento, temos que passar e apontar Batis dollar Cali Brackets, paper dot Slash checkout slash Orders. Além disso, para usar essa variável de papel, que definimos no arquivo de configuração do papel, precisamos importá-la na parte superior Const ciBacketsPaper, e também precisamos que o token de acesso gat seja igual exigir que coloquemos uma pasta , configuremos Além disso, importamos const Axios é igual a require Axos. Agora, em nossa API no Axios, no segundo parâmetro, podemos passar o corpo da solicitação Aqui passamos um objeto com algumas propriedades. A primeira é a intenção. Isso define a intenção da ordem a ser capturada. Isso informa às pessoas que o pagamento será capturado imediatamente quando o usuário o aprovar. Por isso, capturaremos imediatamente o pagamento na segunda API. A próxima propriedade que adicionamos é comprar unidades de sublinhado. Para organizar. Isso representa os itens ou serviços que o usuário está comprando e quanto custam. Por enquanto, passamos apenas um objeto e, nesse caso, passamos a descrição para o pedido do carrinho de compras e outra propriedade para o valor do objeto. Dentro disso, temos que informar em qual moeda queremos aceitar o pagamento. Portanto, o código da moeda é USD e, em seguida, o valor é dez. Queremos do usuário um valor D tênue. Agora, após a compra de unidades, passamos pelos contextos de aplicação e sublinhamos Isso fornece instruções em papel sobre o que fazer depois que o usuário terminar de usar o formulário de pagamento em papel. Então, neste objeto, temos que passar duas propriedades. O primeiro é o URL de sublinhado escrito. Esse é o URL para o qual queremos redirecionar nosso usuário após o pagamento ser verificado com sucesso em papel E a segunda propriedade é cancelar o URL de sublinhado, esse é o URL para o qual queremos redirecionar o usuário após o pagamento ser rejeitado ou Por enquanto, deixe esse campo como está. Vamos preencher isso quando provarmos essa implementação. Agora, após o corpo da solicitação, podemos passar outras configurações como cabeçalho para objeto, tipo de conteúdo para aplicativo, tipo de conteúdo para aplicativo, ZSN e também precisamos passar o cabeçalho de autorização para a cerveja Batis, espaço, e aqui adicionaremos Você pode dizer como podemos gerar esse token? Podemos usar gxsstkenFunction. No topo, o token const é igual a um peso porque essa é uma função Obtenha o token em excesso no cabeçalho de autorização, passaremos o token Calibrakets em dólares e pronto para esta API Agora, essa API criará um novo pedido, como dados escritos, como ID do pedido e alguns links. Aqui só precisamos retornar o link, que é o link em papel. Se abrirmos esse link no navegador , receberemos a página de pagamento em papel. Então, simplesmente retornamos o ponto de resposta (URL de aprovação do objeto JSON), dois pontos de resposta (ponto teta). Os links Aqui temos a função de seta de link único, o ponto de link L é igual a códigos, aprovamos o ponto externo HRF e pronto Nossa primeira API está completa. Agora, vamos definir rapidamente nossa segunda API para capturar o pagamento e, em seguida, testaremos essa implementação Portanto, roteador, poste pontos e aponte para cortar a ordem de captura do papel Depois disso, é retornado a ligação com solicitação e resposta. Agora, capturar o pagamento é muito simples. Em primeiro lugar, obteremos o ID do pedido a partir do corpo do ponto da solicitação porque, no front-end, precisamos enviá-lo e precisamos desse ID do pedido para capturar o pagamento. Além disso, para verificação, podemos colocar a condição aqui Se o ID do pedido não estiver disponível, basta retornar o status do ponto de resposta, objeto Json de 400 pontos com a propriedade da mensagem Envie o ID do pedido ou forneça o ID do pedido Forneça sons bons. O que você diz? Sim. Agora, se tivermos o ID do pedido , precisaremos de um token para a API de captura PL. Portanto, o token Gs é igual a await, G excess token e, no final, simplesmente chamaremos uma API Aguardamos axios dot post para o endpoint, passamos impostos do BC, clacketSP dot BRL dois, slash checkouts Pedidos, colchetes em dólares de Cali, ID Como captura. Agora, no segundo parâmetro, precisamos passar o corpo. Para essa API, não precisamos passar nada, então passamos um objeto vazio. Agora, obtemos o status e alguns detalhes sobre a captura dessa API. Assim, podemos armazenar isso em resposta e, no final, simplesmente retornamos o simplesmente retornamos status do objeto Json do ponto de resposta para resposta, dados do ponto, status do ponto Esse status indicará que o pagamento foi capturado com sucesso ou não, e pronto. Você pode ver como é simples. Só precisamos chamar a API People. Agora você pode perguntar: por que não podemos chamar essas APIs do front-end Suponha que chamemos diretamente essa API de criação de pedidos a partir do front-end. Agora, como sabemos, o usuário tem excesso do front-end. Eles podem simplesmente modificar esse valor e torná-lo zero ou 0,5. Imagine quanto dinheiro a empresa perderá e algumas pessoas usarão indevidamente algumas informações É por isso que precisamos implementar esses recursos de pagamento em nosso back-end. Aqui, concluímos nossas duas APIs para p. Não se preocupe, essa é apenas uma implementação básica Melhoraremos essas APIs após teste porque na segunda API, após capturar o pagamento com sucesso, precisamos criar um novo pedido para esse usuário e remover os detalhes do cartão Por enquanto, não queremos essa complexidade, então faremos isso mais tarde nesta lição, certo? Antes de testar essas APIs, precisamos de uma chave de cliente em papel, People Secret e People base URL Lembre-se de que usamos variáveis vazias no arquivo ENV, precisamos primeiro adicionar esses três campos e, para isso, precisamos configurar a conta People Business Agora vamos configurar a conta do Paper Business. Vamos criar uma nova conta em papel e experimentar essa implementação. Nesse processo, você pode precisar de alguns documentos legais e seus dados bancários. Então, acesse a página do desenvolvedor em papel, que é developer.paper.com Se você já tem uma conta comercial impressa , é bom, mas a maioria dos estudantes não tem uma conta comercial impressa. Aqui estou falando sobre conta comercial, não pessoal. Você também pode converter sua conta pessoal em conta comercial a partir dessa configuração. Aqui, clicamos em C para se inscrever para criar uma nova conta. Certifique-se de selecionar aqui a conta comercial e começar. Digite seu e-mail aqui e envie-o. Agora, aqui, crie sua senha. Certifique-se de seguir essas instruções e enviá-las. Agora, descreva seu tipo de negócio, eu seleciono seu indivíduo, e aqui também temos que fornecer essas informações. Produto ou serviço, digamos, mercados. Estou escrevendo detalhes aleatórios, mas no mundo real, você tem que escrever seus detalhes originais. Código de propósito, deixe-me ver o que eles têm. Selecione seus serviços de entretenimento. Depois disso, tenho que escrever o número da minha carteira de identidade. Para o seu país, pode ser outra coisa, então você precisa escrever os detalhes corretos. Nome da declaração para, digamos, que Deus o abençoe e envie o formulário Agora, aqui, temos que preencher as informações pessoais e comerciais, então eu preencho rapidamente esses detalhes. Portanto, essas plataformas de pagamento mudam sua interface com muita frequência. Portanto, se no futuro você não tiver a mesma interface que eu , não se confunda. Basta fornecer os detalhes que eles estão solicitando e criar uma conta comercial em papel. Depois de criar uma conta, podemos criar o ID do cliente e o segredo do cliente. Além disso, aqui eu seleciono a moeda principal para o dólar americano. Você pode escolher o que quiser, concordar e continuar. Aqui, eles estão solicitando a verificação de sua identidade. Se você planeja fazer seus pagamentos no modo ao vivo, conclua esse processo o mais rápido possível. Por enquanto, eu só quero testar, selecionar, fazer isso mais tarde. Isso nos moverá para a página de papelão. Agora, na parte superior, clique em desenvolvedores e, como você pode ver, agora estamos no modo Sandbox, o que significa modo de teste Agora, para criar o ID do cliente e o segredo do cliente, acessamos aplicativos e credenciais. Clique em Criar aplicativo. Escreva o nome do seu aplicativo, qualquer coisa. Digamos que Cardwish node. Estamos criando uma conta para o comerciante e simplesmente criando um aplicativo Está carregando e veja, aqui temos o ID e o segredo do cliente. Então, primeiro, copie o ID do cliente e cole-o em nosso ID do cliente do arquivo ENV Agora, copie a chave secreta e cole-a também no valor secreto. Para URL em papel, passamos TDPs, pontos e barra dupla para api.sandbox.people.com. Bom. Salve esse arquivo. Agora, para testar com pagamento, também precisamos de uma conta de teste em sandbox para enviar o pagamento Então, vamos às ferramentas de teste e vemos , como as contas de sandbox, aqui temos duas contas de teste, uma para negócios e outra para uso pessoal No momento, não precisamos criar uma nova conta. Se precisarmos, criaremos. Agora, como sabemos, precisamos de um front-end para testar essa API porque, no front-end, abriremos a página de pagamento em papel Agora, como sabemos, precisamos de um front-end para testar essas APIs porque, no front-end, abriremos uma página de pagamento em papel Então, aqui eu criei uma página SDML simples chamada p tasting dot Você verá esta página abaixo desta lição, e ela também está disponível no projeto de recursos para pasta. Faça o download e simplesmente adicione-o ao seu projeto atual. Agora, vamos executar esse arquivo SDML no Browser. Então vá para SDMLFle no Explorer de arquivos ou Finder e simplesmente abra-o no Chrome Aqui temos o título e um botão simples. Se você quiser ver o que aconteceu quando clicamos nesse botão , você pode assistir ao arquivo SDML É muito simples. Veja, atualmente ele está sendo executado a partir de arquivos locais da nossa máquina. Agora, aqui está uma coisa. Lembre-se de que, na API do pedido, precisamos passar os contatos do aplicativo. Veja, aqui. Basicamente, temos que passar pela página de sucesso e cancelar a página. Na API do pedido, não podemos passar o caminho da pasta local, precisamos passar o URL. Então, qual é a solução aqui? Podemos hospedar nosso arquivo SDML no servidor local e, em seguida, passaremos esse caminho aqui Deixe-me mostrar que é muito simples. Então, na guia de extensão, pesquise Live Server. E instale essa extensão. Ao usar essa extensão, podemos executar nosso aplicativo no servidor local. Volte aos arquivos e coloque o link direito no papel de degustação do SDMLFle e selecione abrir com E veja que está aberto no navegador, mas agora está sendo executado nessa porta. Basta copiar esse URL, voltar ao código Vas e simplesmente colá-lo no URL escrito e também no URL de cancelamento, cole o mesmo URL. Mas para verificar se isso está funcionando ou não, passamos aqui para cancelar. No mundo real, perguntar ao desenvolvedor de front-end qual página ele deseja mostrar sobre o sucesso e cancelar e mudar o caminho de acordo com isso. Eu passo por esse caminho apenas para testar. Salve esse arquivo e verifique se o servidor está em execução. Aqui, recebo um erro, parâmetros duplicados. Oh, aqui eu passo a resposta no local da solicitação. E também, deixe-me verificar outra API. Sim, aqui também solicite. Salve esse arquivo e certifique-se de que nosso servidor esteja funcionando. Bom. Está funcionando. Agora volte para a sala e simplesmente clique em pagar com papal. Nada acontece. Isso não é justo. Vamos verificar o que acontece. Então, inspecione manualmente usando FL, vá para o console e aqui podemos ver que recebemos um erro O acesso à API de busca ou criação de pedidos a partir da origem Null foi bloqueado pela política do curso Esse é um erro muito popular para desenvolvedores full stack. Isso acontece porque, por padrão, nosso aplicativo Express não aceita chamadas de API de nenhuma origem. Temos que habilitar o curso em nosso aplicativo Express. Então, volte ao terminal e escreva NPM install CRE. E aperte Enter. Agora, no arquivo js do índice na parte superior, importamos o custo. O curso é igual ao curso obrigatório. Então, na parte inferior, antes desse express DJs and middleware, adicionamos o curso app dot g, e pronto Veja as mudanças. Certifique-se de que nosso servidor esteja funcionando. Bom. Agora, basta clicar no botão pagar com papel. Aqui eu recebo um erro na criação do pedido, o que significa que estamos recebendo um erro na API 1. Vamos verificar o que está acontecendo aqui. Então, abra o Console. Aqui eu recebo 400 pedidos incorretos. Então, voltando ao código VS no terminal, C, obtemos o token como portador Insira seu token JWT, o que significa que passamos o token errado do front-end Então, abra o ponto de teste de papel SDMLFle aqui, temos que inserir nosso token Abra o Postman, abra a API de login, gere um novo token Bom, copie esse token e, em nosso arquivo STML, passe esse token Salve esse arquivo, menos isso. Clique em pagar com papel. Vai levar algum tempo para ver, aqui temos a página de login em papel, que significa que nossa primeira API de criação de pedidos está funcionando bem. Agora, antes do login, vamos cancelar o pagamento. Veja, nós redirecionamos para cancelar o URL. Agora, volte duas vezes para nossos caminhos de front-end e clique em pagar com o Paper. Recebemos a página de login do Paper. Aqui no mundo real, nosso cliente fará login com seu ID e senha impressos. Mas aqui para degustação, usaremos a conta Sandbox Pense em papel. A conta Sandbox é como a conta Dummi para degustação Então, vamos ao nosso Paper Dashboard. Aqui temos uma conta pessoal. Clique nisso. Aqui, veja, obtemos informações de login, copiamos o e-mail e, em nosso front-end, adicionamos esse e-mail. Agora, volte ao Painel, copie a senha , cole-a na senha e clique em Login. Aqui, recebemos um erro gravado para o comerciante. Não podemos processar seu pagamento usando sua conta impressa no momento. Volte para o vendedor e tente usar um método de pagamento diferente Então, deixe-me tentar novamente. Veja, ainda assim, estamos recebendo o mesmo erro. Agora deixe-me tentar outra coisa. Atualmente, minha inscrição é baseada em uma conta indiana, e aqui estou tentando pagar da Índia para a Índia. O Paper não permite pagamentos domésticos na Índia por meio de carteiras de papel Mesmo na conta sandbox, tentamos fazer uma transação entre duas contas indianas e, em seguida, também haverá um erro se o pagamento da Índia para a Índia tiver outro gateway de pagamento, como o raiser pay Vamos criar uma conta de teste para outro país. Tipo de conta para pessoal e aqui, selecione qualquer país, mas não selecione o mesmo país conta comercial. Crie uma conta. Agora vamos tentar fazer login com essa nova conta. De volta ao nosso front-end. Aqui, estou recebendo o mesmo erro porque minha conta está conectada Então, vamos abrir esse front-end na guia anônima e pagar com papel Aqui, eu recebo a página de login. Certifique-se de fazer login com conta de outro país, adicionar o e-mail e também adicionar aqui a senha e fazer login com esta conta Veja, aqui temos a página de pagamento em papel. No topo, obtemos a conta do usuário e aqui temos o preço a pagar. Além disso, aqui na parte inferior, obtemos vários métodos de pagamento, como saldo em papel, cooperativa de crédito usando cartão, crédito em papel e você também pode adicionar seu próprio cartão. Essa é uma conta de teste, e é por isso que não fazemos nada. Além disso, aqui temos o endereço dessa conta. Esses são os detalhes da conta de degustação. Agora vamos clicar em Continuar para revisar o pedido. Então, aqui temos uma falha no pagamento. Deixe-me verificar o que está errado. Abra bem o console usando F e veja, aqui temos um erro na API de ordem de captura. Então, em nosso código VS no terminal, aqui eu recebo esse erro longo, então role rapidamente até o topo. Aqui obtemos um erro, não é possível ler as propriedades do status de leitura indefinido Portanto, em nossa segunda API, não estamos obtendo status. Deixe-me verificar o que está errado. Oh, desculpe. Aqui, eu esqueci de escrever. Salve esse arquivo e volte para o nosso front-end. Deixe-me tentar remover esse token e o ID de par da URL e executar esse arquivo SGML simples Agora clique em pagar com papel. Veja se recebemos o pagamento papal, basta clicar em Continuar para revisar o pedido Aqui eu novamente recebo o preenchimento do pagamento. Lembre-se de que sempre que aplicarmos novos recursos, certamente ocorrerão erros. Não fique frustrado, concentre-se nas soluções, não nos problemas Veja, aqui eu recebo um erro interno do servidor. Deixe-me verificar a solicitação do terminal preenchida com Código de Status 400 em nossa API de pedido de captura, o que significa que não estamos recebendo o ID do pedido. Oh, aqui eu só escrevo o corpo do ponto de solicitação. preciso adicionar um ID de pedido por pontos, salvar as alterações e, em nosso front-end, pagar com papel. Continue revisando o pedido. Veja, vamos para nossa página de sucesso e aqui também obtemos o pagamento bem-sucedido, que significa que nossa segunda API captura de pagamentos também está funcionando Veja, em nossa URL, também obtemos o Token, que é o ID do pedido, e buscaremos esse parâmetro em nosso front-end e, em seguida, chamamos a segunda API de pagamento de captura e passamos esse ID do pedido no corpo E com isso, capturamos o pagamento em conta de papel. Vamos verificar nossa conta comercial, receber o pagamento de $10 ou não Para isso, precisamos acessar o painel do Pap. Nas ferramentas de teste, acesse as notificações do sandbox Agora, nesse menu suspenso, selecionamos nossa conta comercial e clicamos em pesquisar. E na parte inferior, recebemos o pagamento. Se você não receber o pagamento aqui, espere de dois a 3 minutos, pois às vezes leva tempo para mostrar o pagamento aqui. Agora, se abrirmos isso , podemos ver o pagamento recebido de $10 de John, que está testando o nome da conta Aqui podemos ver a data da transação. Esse é o formato PST, que é um horário padrão específico Não se confunda com isso. Agora você pode se perguntar por que recebemos pagamentos nessa conta comercial. O motivo pelo qual recebemos o pagamento nessa conta comercial é que, usando essa conta, criamos nosso aplicativo e seguida, obtemos o ID do cliente e o segredo em papel. É por isso que recebemos pagamentos nessa conta comercial. Agora, aqui vamos provar o pagamento para o usuário dos EUA. Veja, aqui temos o código do país. Agora, para provar o pagamento em outro país, podemos criar uma nova conta Selecione aqui pessoal, que é a conta do comprador, e aqui podemos selecionar o país. Digamos que eu selecione aqui o país, Canadá, você pode selecionar qualquer país e criar uma conta. Isso é muito divertido. Veja, na parte superior, temos a nova conta para usuário canadense. Abra esse usuário e simplesmente copie o ID do e-mail. Agora, de volta ao nosso front-end e aqui vamos para um URL simples de teste em papel. Certifique-se de remover esse token porque é a página posterior do pagamento bem-sucedido. Agora clique em pagar com papel. Aqui, obtemos novamente a conta anterior porque fizemos login com ela Então, para remover essa conta, clicamos aqui neste ícone do JD Veja na parte inferior, obtemos o Logout. Clique nisso. Agora, clique em alterar e-mail do usuário e cole aqui o e-mail da nova conta. Agora, de volta ao deskbard, copie a senha, cole-a aqui e faça login com Bom. Agora, veja aqui no topo, eu recebo o valor em ordem, mas aqui da minha conta, eu posso pagar em moeda canadense, que é CAD. Além disso, temos métodos de pagamento limitados e, veja aqui, obtemos a taxa de conversação das pessoas um CAD igual a 0,6 9549 Aqui, as pessoas pagam suas taxas de transação, mas podemos pagar na moeda do nosso país. Vamos continuar revisando o pedido. Veja, aqui recebemos pagamentos bem-sucedidos. E se verificarmos nossas notificações de sandbox, pesquise aqui a conta comercial Pode levar um pouco de tempo, e aqui recebemos outro pagamento de $10 Na parte inferior, como podemos ver, temos a localização do Canadá. Além disso, essa conta comercial recebe seu pagamento em dólares americanos, até mesmo o cliente paga em outra moeda. Esse cliente precisa pagar a taxa de transação papal. Então, como sabemos, nosso pagamento está funcionando. Agora podemos melhorar nossas APIs e torná-las realistas. É muito simples. Deixe-me te mostrar. Então, o que queremos mudar na API de pedidos, atualmente estamos passando quantidade estática aqui, mas isso não está certo. Temos que repassar o preço total do cartão do usuário. Então, vamos obter o preço total do cartão. Portanto, antes deste token de acesso, escrevemos o custo, carrinho é igual ao peso, carrinho Certifique-se de inserir o ponto Fine one do modelo do cartão. E aqui no objeto, passamos o usuário para solicitar o ID de sublinhado do ponto do usuário E também, para esse ID de usuário, precisamos adicionar o Osmidalware Certifique-se de inserir isso também. Isso retornará o objeto do cartão, mas teremos que aprovar a condição dela se o carrinho não estiver disponível ou o comprimento dos pontos dos produtos do cartão for igual a zero, retornaremos a resposta com código de status Objeto Json de 404 pontos, propriedade da mensagem ao carrinho não encontrado Agora, no local desse valor, temos que passar o preço total do cartão por ponto do cartão. E aqui não mudamos a moeda porque queremos receber o pagamento em dólares americanos. Se você quiser receber o pagamento em outra moeda, poderá passar esse código de moeda nesse código de moeda. Mas deve verificar se a moeda é aceita em papel ou não. Por enquanto, vamos provar isso. Salve as alterações e vá para Paper tasting dot SDMLFle deixe-me explicar esse código Então, aqui passamos o token JWT ao qual adicionamos o produto. Atualmente, em nosso aplicativo, definimos um prazo de validade de apenas 2 horas, o que é um pouco chato para degustação, porque aqui temos que criar o token JWT repetidamente Assim, podemos remover a expiração do login e simplesmente adicionar a expiração na fase final do projeto Portanto, nas rotas do usuário e na parte inferior, removemos esse objeto com a propriedade expirada Agora vamos gerar um novo token que nunca expira. Abra o Bostman e abra a API de login e simplesmente envie a solicitação Bom. Aqui copiamos esse token no arquivo SDML, simplesmente o colamos aqui Além disso, você pode passar aqui seu endereço de entrega. Agora, depois disso, adicionei aqui este evento ao clicar para este botão de pagamento. Em primeiro lugar, chamamos nossa API de pedidos usando o método fetch e com esse token E, como sabemos pela API de pedidos, obteremos o URL de aprovação. Então, temos isso aqui. Se esses dados não tiverem sucesso , mostraremos um alerta com erro na criação do pedido. E se obtivermos o URL de aprovação do back-end com sucesso? Em seguida, redirecionaremos o usuário para essa página. Agora o usuário insere as informações corretas e o pagamento é feito com sucesso. Agora, as pessoas passam o token nos parâmetros do URL, que é nosso ID do pedido. Então, após um pagamento bem-sucedido, obtemos o token nos parâmetros do URL. Depois disso, chamamos nossa segunda API para capturar o pagamento E se esse pagamento for capturado com sucesso, a partir do back-end, passaremos o status na resposta Aqui, verificamos se o status está concluído , mostramos um alerta de sucesso e, se ele falhar , mostramos um erro de falha, simples assim. Agora, vamos simplesmente experimentar nossa implementação. Estou muito empolgado com isso. Salve esse arquivo e agora atualize a página e, novamente, clique no botão de pagamento Ocorreremos um erro ao criar a ordem se verificarmos o console. Veja, aqui temos um erro. São 400 erros, o que significa que o carrinho não foi encontrado. Ou, lembre-se, na lição sobre como remover carrinho, removemos o cartão removendo os últimos produtos da matriz de produtos. Temos que adicionar um produto em nosso cartão, acessar a API do Postman open head to cart Aqui, temos que atualizar o token, copiá-lo da API de login e simplesmente colá-lo no cabeçalho de autorização. Bom. Agora vamos enviar a solicitação. C, produtos adicionados. É um iPhone, ótimo. Agora vamos atualizar a página e, novamente, provar o pagamento Veja, aqui temos o preço do nosso cartão. Adorável. Agora, aqui, simplesmente cancelamos o pagamento e passamos para o ponto de degustação de papel STMLpage Bom. Agora vamos melhorar nosso segundo EPI Não se preocupe, pois não precisamos fazer muitas coisas. Vamos apenas criar um novo dado de pedido no banco de dados. Remova o cartão atual do usuário se o pagamento for bem-sucedido. Então, aqui passamos condição I que o pagamento é capturado com sucesso, então o status do ponto de dados do ponto de resposta , que obtemos dessa API de captura Se o pagamento for igual a concluído, escrevemos o código aqui no bloco I. Então, aqui criamos custos. Novo pedido é igual a novo pedido. Certifique-se de inserir esse modelo de pedido. Bom. Agora temos que passar um novo objeto de pedido aqui. Então, primeiro de tudo, nesta ordem, adicionamos o usuário para solicitar o ID de sublinhado do ponto do usuário Mas aqui, para obter detalhes do usuário, precisamos adicionar nosso middleware Good Agora, depois disso, precisamos de produtos e, nesses casos, armazenaremos todos os produtos que pedimos. E como podemos obter essa informação? Certo, nós pegamos isso do back-end. Portanto, antes desse pedido, encontramos const, Card é igual a await cart dot find one E aqui no objeto, passamos a condição do usuário para solicitar o ID de sublinhado do ponto do usuário ponto Simplesmente nos produtos encomendados, passamos os produtos cart dot. Depois disso, o total de produtos no carrinho representa o total de produtos. Em seguida, temos o preço total, até o preço total do carrinho. Em seguida, temos o endereço de entrega, que precisamos obter do front-end. Por enquanto, deixe como está. Em seguida, adicionamos o status do pagamento a pago, ID de pagamento aos dados do ponto de resposta ID do ponto. E se você quiser salvar algumas informações extras , pode avaliar se elas realmente dependem de você. Além disso, se você quiser adicionar um novo campo, precisará adicionar esse campo em nosso esquema de pedidos Por enquanto, passamos todas as informações necessárias. Agora podemos salvar esse novo pedido, então aguarde o novo pedido dot save e depois de salvar o novo pedido, podemos remover nosso cartão do banco de Então aguarde o cartão dot DiLto Aqui já temos o cartão. É por isso que usamos diretamente o cartão dot Delete one. Se não obtivermos o cartão aqui , teremos que usar o método cart dot Fine one e delete como este. Na parte inferior, movemos essa resposta este blog e retornamos essa resposta. Isso é muito importante. Agora, para maior segurança, adicionamos uma condição e simplesmente retornamos aqui a resposta com o código de status, 400 SN Object, a propriedade de status como não concluída e a mensagem de pagamento não foi capturada com sucesso. Tente novamente mais tarde e pronto. Só precisamos passar o endereço postal neste objeto de pedido De onde obtemos o endereço postal. Nós o obtemos do front-end. No corpo da solicitação da API do pedido de captura, podemos obter o endereço postal, os segundos do endereço de envio são iguais ao corpo do ponto da solicitação, endereço de entrega do ponto Aqui estamos recebendo endereço postal porque , no front-end, já passamos o endereço postal no corpo da solicitação Veja, aqui eu passo o endereço postal. Agora, em nosso pedido, podemos definir o endereço de entrega como endereço postal Bom. Agora, deixe-me dar uma situação. Imagine que o usuário tenha esquecido de passar esse endereço de entrega. Como podemos entregar o produto a esse usuário? Portanto, temos que garantir que o usuário passe o endereço postal. Portanto, aqui podemos escrever a condição I, endereço de entrega não está disponível e, em seguida, retornamos a resposta com o código de status 400 para a solicitação de aposta e, no objeto JSON, passamos a propriedade Message para fornecer seu endereço de entrega Agora, aqui está uma coisa. Sabemos que essa API de captura de pagamento será executada após o usuário pagar com papel Não podemos dizer agora ao usuário que eles não fornecem endereço de entrega. Aqui podemos fazer uma coisa. Também podemos simplesmente colocar essa condição logo no início de nossa primeira API antes de sermos cortados. Aqui, temos que obter o endereço postal no corpo do ponto da solicitação Portanto, o endereço de entrega Const é igual ao corpo do ponto da solicitação, endereço de entrega do ponto Certifique-se de escrever a grafia correta do endereço de entrega 151. Obtendo o histórico de pedidos: Agora, vamos definir rapidamente outras APIs para os pedidos. Vamos encontrar todo o histórico de pedidos do usuário atual. Depois dessa API papal, adicionamos o ponto Get do roteador e apontamos para a barra frontal Além disso, para encontrar as informações do usuário, adicionamos o middleware Os e, em seguida, usamos a função de retorno de chamada com solicitação Agora, aqui obtemos diretamente que const orders é igual a um peso, order dot find, e aqui passamos o objeto de comparação, usuário para solicitar dot user dot dot underscore ID Além disso, precisamos encurtar esses dados por data. Método curto de pontos, e aqui no objeto, passamos criado em dois menos um para ordem decrescente Aqui, da coleção de pedidos, não queremos mostrar todos os preenchimentos. Selecione pontos, menos usuário, menos endereço postal, menos ID de pagamento e, no final, podemos enviar a resposta, pontuar JSN e passar ID de pagamento e, no final, podemos enviar a resposta, podemos enviar a resposta, pontuar JSN e Vamos testar essa API. Então, no Postman aqui no CardWzpject, criamos uma Na pasta Pedidos, adicionamos uma nova solicitação chamada Histórico de pedidos. Agora, aponte para SCTP, coluna dupla para nosso host local de barra, coluna 3.000 API slash Order e envie coluna dupla para nosso host local de barra, coluna 3.000 API slash Order Desculpe, esquecemos de passar o token JWT. Então vá para os cabeçalhos. Primeiro, passamos a autorização ao portador e aqui passamos o token Então, fazemos login novamente. Aqui obtemos o token, copiamos esse token e colamos nessa API e enviamos a solicitação. Veja, aqui temos os dados dos pedidos, adoráveis. Agora, na próxima lição, definiremos nossa última API para esse projeto. 152. Atualizando status pelo administrador: Vamos criar uma API para administrador. Por meio dessa API, ele ou ela pode alterar o status do pedido para processamento, C entregue ou o que quiser. Portanto, na página de pontos do roteador, porque queremos alterar apenas uma propriedade, não o documento inteiro, e apontar para o status da ordem de barra D aqui, também precisamos do ID do pedido, então passamos o ID da ordem da coluna Então, adicionamos o middleware Os para o token JWT. E aqui também precisamos verificar a regra do usuário. É administrador ou não? Então, adicionamos aqui a regra de Jack, middleware, a entrada automática C não funcionou E dentro disso, temos que passar a função, que é admin. Agora, no topo, vamos inserir esse middleware. Const, a função de verificação é igual a exigir que tenhamos uma pasta ativa, middleware e nessa Já usamos isso na rota de produtos. Se você esqueceu, pode observar o código da rota. Agora, simplesmente passamos a função de atuação com solicitação e resposta Ótimo. Agora, primeiro, recebemos o pedido da coleção de pedidos. O pedido sectuDado é igual a aguardar pedido dot find By ID. Além disso, em vez disso, podemos usar fine by ID e atualizar. Aqui, no primeiro argumento, temos que passar o ID do pedido, que é o ID do pedido de pontos dos parâmetros do ponto E no segundo argumento, passamos o objeto dos valores atualizados. Portanto, o status do pedido do objeto é qualquer valor na passagem média. E como podemos obter esse valor diretamente do corpo da solicitação? Aqui, antes do pedido atualizado, status do custo era igual ao corpo do ponto da solicitação, status do ponto. E aqui passamos o status do pedido para o status. E depois disso, no terceiro argumento, passamos objeto com novo para verdadeiro. Fará com que as mangas retornem novos dados atualizados nesse valor do pedido Já vimos isso na seção Mongo DB. Agora, talvez não tenhamos encontrado o pedido. Se o pedido atualizado não estiver disponível, retornaremos a resposta , o status do ponto, o objeto Json de 404 pontos propriedade da mensagem para o pedido Por fim, simplesmente passamos a resposta dot json, Object, propriedade de mensagem para o status do pedido atualizado com sucesso e, depois disso, do pedido atualizado para o pedido atualizado Ou também podemos remover isso e pronto. Se você quiser mudar alguma coisa, poderá fazer essas alterações de acordo com suas necessidades. Vamos testar essa API, abrir o Postman, adicionar uma nova solicitação na coleção de pedidos chamada atualizar status do pedido, selecionar solicitação para página, endpoint para cortar API Selecione também a página, o status do pedido e aqui adicionamos o ID do pedido. Da chamada de API anterior, eu simplesmente copio esse ID do pedido e o colo no endpoint Agora, em nossa API, passamos o cabeçalho para autorização e também copiamos o valor da API anterior e o colamos aqui. Envie a solicitação. Aqui, recebo um erro. Deixe-me verificar o terminal. Eu sei que há um erro na função de verificação. Então, no topo, eu tenho um erro de digitação, então eu altero isso para verificar a função As alterações e o envio da solicitação. Veja, aqui temos o erro 403 proibido, acesso negado somente para administradores Precisamos alterar a regra de usuário dessa conta. Vá para MongoivCompass, abra a coleção do usuário e encontre sua conta pela qual Sem isso, eu simplesmente altero a regra para que o administrador a atualize. Agora, precisamos gerar o token web JSN novamente. Acesse o login e envie a solicitação, copie esse token e substitua nosso token por esse novo token. Agora, no body raw, também precisamos passar o objeto JSON com status do campo para o IB e enviar a solicitação Veja, aqui recebemos uma mensagem de sucesso e também dados atualizados do pedido. Adorável. 153. Limpando o código para arquivo de índice: Então, atualmente, nosso aplicativo está limpo. Só se confunda com o arquivo JS de pontos de índice. Podemos ver que isso não parece limpo. No topo, muitos, muitos exigem funções para entrada. Depois disso, temos o código para criar registradores e manipuladores de erros globais Depois disso, temos conexão com o MongoDB, aplicamos alguns middlewares e algumas rotas e, finalmente, ouvimos nosso servidor Há muitas coisas acontecendo nesse arquivo de pontos de índice. Podemos torná-lo limpo e armazenar cada lógica em um arquivo separado. Não é obrigatório, mas muitos desenvolvedores fazem isso, mas isso pode confundir você Portanto, há outra maneira de, em vez de separar o código, podemos torná-lo limpo adicionando comandos e separando-os uns dos outros Pode escolher de qualquer maneira, depende totalmente de você. Deixe-me te mostrar meu caminho. No topo, temos algumas configurações, então adira, comande a configuração global Depois disso, temos esse Express, Mongoose, Winston e, Adicionamos módulos de comando e de terceiros. Que temos esse aplicativo. Não queremos tocá-lo agora. Na parte superior, adicionamos todas as nossas entradas. Todas essas importam rotas sobre este aplicativo e adicionaram comentários, módulos personalizados ou, você pode dizer, módulo de rotas Não há regras para o comentário. Você pode escrever o comentário, como quiser chamar. Lembre-se de que este comentário será visto por você no futuro. Então, nesse momento, você não se confunde. Agora, depois disso, podemos adicionar um comando para este aplicativo, inicializar o aplicativo expresso Agora, aqui temos esse registrador e também na parte inferior, temos essa porta, então podemos movê-la aqui e podemos chamá-la de constante Depois disso, para essa exceção não detectada, adicionamos erros síncronos catch, unhandle que não foram detectados nos blocos try Para rejeições não tratadas, adicionamos rejeições catch unhandlePmise Com esses comentários, podemos lembrar por que adicionamos o código mesmo depois de muito tempo Depois disso, aqui temos a conexão com o banco de dados. Então temos esses dois middlewares, então middleware, então, para arquivos estáticos, adicionamos arquivos estáticos de serviço. Em seguida, para rotas, adicionamos rotas de API. Depois disso, temos o middleware de erros, então adicionamos um manipulador de erros personalizado e, finalmente, iniciamos Agora, se verificarmos nosso arquivo js de pontos de índice, veja, agora ele parece um pouco mais limpo. Sim, a separação do código tornará isso mais limpo, mas também pode nos confundir Você também pode separar o código. Eu dependo totalmente de você. Então, aqui, nosso projeto de comércio eletrônico acabou. Agora, na próxima seção, abordaremos nosso projeto três, que é um aplicativo de mídia social. 154. Seção 13 — introdução do projeto 03: Bem-vindo à nova seção do curso definitivo de Node JS. A partir desta seção, vamos construir um projeto totalmente novo. Você consegue adivinhar? Sim, vamos criar back-end de aplicativos de mídia social usando o NodeJS Chamaremos esse projeto de nosso Linky Pi. Este projeto é um dos meus projetos favoritos. Deixe-me explicar para você o que abordaremos neste projeto. Neste projeto, criaremos uma API para os seguidores seguintes, incluindo o envio de solicitações para contas privadas envio de e-mails do nosso aplicativo. Além disso, criaremos APIs para postagens com curtidas e comentários Em seguida, criaremos uma API para bate-papo, bate-papo pessoal e bate-papo em grupo. Além disso, aplicaremos experiências de bate-papo em tempo real com soquete e muitas outras coisas Se você realmente entender e criar esse projeto , seu portfólio realmente melhorará. Isso vai ser divertido. Você está animado? Estou muito animada e espero que você também esteja. Então, vamos começar a construir esse projeto incrível. 155. Configurando o Projeto 03: Agora vamos configurar nosso novo projeto. Então, na pasta de projetos, eu crio uma nova pasta chamada nosso Arquivo Linky Agora, vamos abrir essa pasta no código VS. Bom. No terminal, escrevemos NPM em Y para inicialização e para criar o pacote Além disso, vamos criar o arquivo index dogs, que é nosso arquivo principal. Agora, como sabemos, vamos configurar nosso aplicativo nesse arquivo. E para isso, precisamos de alguns pacotes. Então, no terminal, escrevemos NPM, install, Express, Mongos para Mongo DB, cours para cours para Além disso, adicionamos Dt NV, precisamos disso e pressionamos Enter Isso levará algum tempo. Bom. Agora, vamos configurar rapidamente nosso aplicativo. Em primeiro lugar, o Const Express é igual a exigir do Express Depois disso, st app é igual a, aqui chamamos Express para ouvir este aplicativo, adicionamos aqui o ponto LISN. Aqui, na primeira discussão, temos que passar pela porta. Depois do aplicativo const, definimos outra porta const igual a processar uma nova porta de pontos para 3.000 ou 5.000, Na produção, nosso aplicativo usará a porta da variável de porta ENV No segundo argumento, temos que passar a função de retorno de chamada que simplesmente console o log de pontos Nesse caso, o servidor está sendo executado em uma porta, e aqui imprimimos nossa porta de calibradores em dólares. Além disso, temos que adicionar alguns produtos intermediários do aplicativo. No topo, o curso é igual ao curso obrigatório. E aqui adicionamos o app dot g, basta chamar aqui de curso. E depois disso, para passar dados em JSON, usamos app.us, express Sem esse middleware, não podemos obter dados na solicitação do corpo Agora vamos ver essa implementação. Veja as mudanças e, no terminal, nodemon index dot js C, o servidor está em execução. Ótimo. Agora vamos também conectar esse aplicativo ao banco de dados. Para isso, precisamos de mangas. Portanto, no topo, o custo das mangas é igual ao exigido do Agora, depois dessa variável, adicionamos o Mongoose dot connect Aqui, temos que passar a cadeia de conexão do nosso banco de dados. Anteriormente, passávamos diretamente a string aqui, mas isso é um pouco arriscado Vamos tornar isso seguro. Em nosso projeto, criamos um novo arquivo chamado dot ENV. Nesse arquivo, criamos uma nova variável chamada DVes equal do, Mongo DB, column, double for slash, local host, column 27017, column 27017, que é nossa string de conexão local Você pode obter isso no Mongo Divi Compass e, depois disso, e, depois disso, E aqui inserimos o nome do nosso projeto, nosso slinky Pi. Agora, para usar essa variável de ambiente, precisamos configurar D E e V. Portanto, no arquivo de índice Gs, na parte superior, exigimos dot Env dot config No método mangos dot Connect, o que vamos passar? Certo, passamos o processo ponto w ponto d. Podemos ver como isso se torna simples depois criar apenas um ou dois aplicativos de nós. Isso melhorará gradualmente e você ficará mais confortável com o Node. Agora, como sabemos, esse mangos dot connect retorna uma promessa, então temos que lidar com essa promessa Dot, depois método, função de retorno de chamada, e aqui simplesmente consultamos o log de pontos, Mango Div conectado Além disso, após o método then, adicionamos o método catch para lidar com a rejeição de promessas, e aqui obtemos o erro, função de erro e , no console, o log de pontos, conexão do Mongo Di falhou e simplesmente aderimos a esse erro Vamos também verificar essa implementação. Salve este arquivo e, no terminal, veja, aqui temos o Mongo Di B conectado com sucesso Por enquanto, está tudo bem. Adicionaremos Winston e Lager no final deste projeto, conforme precisarmos deles Agora, na próxima lição, criaremos nosso modelo de usuário. 156. Crie um modelo de usuário: Agora é hora do exercício. Portanto, esta é a pequena amostra do documento do usuário. Com base nisso, você precisa criar um esquema de usuário. Você também pode assistir ao código do projeto anterior. Não se preocupe com isso. Portanto, dedique algum tempo e conclua este exercício. E depois disso, observe a solução. Agora vamos ver a solução. Então, em nosso projeto, criamos uma nova pasta chamada models e, nela, criamos um novo arquivo chamado users dot js. Bom. Agora, em primeiro lugar, importamos o custo, mangas são iguais ao que exigimos das mangas E depois disso, definimos const, esquema do usuário é igual ao novo esquema de pontos de manga e aqui passamos o esquema no objeto Agora, em primeiro lugar, para nosso aplicativo de mídia social, precisamos do nome de usuário para objetar, digitar, para a string necessária, para verdadeira. Além disso, não queremos espaços em branco no nome de usuário. Então, para isso, passamos stream para true. Também significa comprimento até três e comprimento máximo, digamos 30 ou 40, o que você quiser pegar. Depois do nome de usuário, adicionamos e-mail ao objeto, digitamos à string, obrigatório para verdadeiro, exclusivo para verdadeiro, sonho para verdadeiro, porque também não precisamos de espaço no e-mail. E sempre convertemos nosso e-mail em minúsculas, então minúsculas em verdadeiras também Depois disso, precisamos da senha para o objeto, tipo para a string e do requerido para true. Também queremos armazenar alguns detalhes do perfil do usuário, e esses detalhes o usuário pode adicionar a partir de configurações como o Instagram. Não deveria ser obrigatório. Assim, podemos obter um nome de perfil simples, que é do tipo string, e não precisamos que seja exclusivo e também não precisamos que seja obrigatório, portanto, não adicionamos aqui nenhum Agora, bio para objeto, digite para string. E comprimento máximo de 150. Em seguida, adicionamos contas, status, tipo à string, hum, à matriz. Aqui, passamos valores, active, next, disable e bend. Definimos o valor padrão como ativo. Em seguida, o que podemos adicionar é verificado como objeto, digite como bullian e o valor padrão seja falso Além disso, depois disso, adicionamos is private, object, type a bullian e o padrão a false Em seguida, o usuário pode adicionar o tipo de gênero à string, um à matriz, e aqui passamos masculino, feminino, não binário, ou o usuário pode dizer que prefere não dizer. Em seguida, também levamos o número de telefone ao objeto, digitamos à string, pois o usuário pode adicionar o código do país a ele. E aqui também reduzimos para a verdade. Agora, o que podemos acrescentar, acho que isso é suficiente por enquanto. Se, no futuro, precisarmos de mais detalhes, poderemos adicionar mais campos no futuro. Aqui temos nosso esquema. Agora vamos criar um modelo de usuários. Portanto, o custo do usuário é igual ao modelo de pontos Mongos. Aqui, passamos um nome singular, que é usuário. E segundo, passamos o esquema, que é o esquema do usuário Agora, para interagir com esse modelo de usuário, precisamos exportá-lo. Portanto, as exportações do módulo são iguais ao usuário e concluídas. Agora, na próxima lição, criaremos API para registrar um novo usuário. 157. Registrando um novo usuário: Vamos criar nosso primeiro EPI para esse aplicativo. Aqui, criamos uma nova pasta chamada Routes e, dentro dessa pasta, criamos um novo arquivo chamado users dot js. Bom. Agora, primeiro de tudo, precisamos criar um roteador. Importamos Express é igual a require Express e, depois disso, o custo do roteador é igual ao express dot Router. No final, simplesmente modulamos as exportações de pontos iguais a Router. Agora vamos adicionar essa rota em nosso arquivo js de pontos de índice principal. Após essas entradas, inserimos custo das rotas do usuário igual ao necessário Aqui vamos para a pasta Routes slash users. Agora, depois dos middlewares, adicionamos o app dot U. Aqui, na primeira posição, adicionamos o prefixo Então, corte o usuário da API. E aqui simplesmente adicionamos rotas de usuários. Agora vamos criar a API de inscrição. Então, de volta ao arquivo de rota dos usuários. Aqui, adicionamos o ponto post do roteador e apontamos para a barra e, em seguida, a função de retorno de chamada assíncrona com solicitação e com Agora, primeiro de tudo, precisamos obter preenchimentos a partir da solicitação do corpo Mas a questão é: quais preenchimentos precisamos para registrar um novo usuário Portanto, para aplicativos de mídia social, as empresas geralmente usam dados mínimos para registrar um novo usuário Porque se considerarmos dez a 15 preenchimentos como primeira etapa do processo , poucas pessoas criarão uma conta em nosso aplicativo de mídia social Portanto, é melhor usarmos apenas os dados necessários para nosso esquema Além disso, o usuário pode preencher facilmente esses detalhes, e é por isso que, se você notar, quase todos os aplicativos de mídia social levam apenas nome, ID de e-mail do usuário e senha. Somente esses preenchimentos. Posteriormente, eles fazem outros preenchimentos nas configurações do usuário É por isso que abrir uma conta em aplicativos de mídia social é muito simples. Aqui, obteremos apenas três preenchimentos do usuário. O objeto de custo é igual ao corpo do ponto da solicitação, e aqui temos o nome de usuário, e-mail e senha. Agora, se não obtivermos esses preenchimentos, retornaremos o erro Portanto, se o nome de usuário não for válido ou o e-mail não estiver disponível ou a senha não estiver disponível, retornamos a resposta com o status 400 e passamos objeto Json com mensagem de erro sem os campos obrigatórios do formulário Depois disso, também passamos o sucesso para as quedas. Esse campo de sucesso ajudará o front-end a mostrar erros. Agora, também, aqui encontramos que o usuário já está disponível em nosso banco de dados ou não. O usuário Const é igual a um peso. Aqui adicionamos o modelo do usuário, C, entrada automática funciona dot Fine one Object. E aqui precisamos de dólar ou operador para fazer a matriz, e aqui passamos várias condições em objetos separados. Portanto, nossa primeira condição é nome de usuário para nome de usuário e, segundo, e-mail para e-mail. Se alguma dessas condições for verdadeira, obteremos esse usuário. Então, aqui passamos a condição. Se o usuário estiver disponível, retorne a resposta com mensagem de objeto Json de 400 pontos do código de status para aqui passamos a condição O nome de usuário do ponto de usuário é igual ao nosso nome de usuário. Se isso for verdade, ponto de interrogação, nome de usuário já está em uso, caso contrário, o e-mail já está registrado. E depois disso, passamos o sucesso para as quedas. Agora, se o usuário ainda não estiver registrado, basta criar um novo usuário. Portanto, o custo do novo usuário é igual ao do novo usuário. Aqui, passamos o objeto do usuário, o nome do usuário para o usuário, ou podemos simplesmente remover esse e-mail para e-mail e senha para senha. Agora, como sabemos, não passamos aqui a senha em texto normal, precisamos criptografá-la. E para isso, qual pacote usamos, tente se lembrar dele. Sim, é cripta. Então, instale o NPM, criptografe e pressione Enter. Bom, minimize o terminal e, em nosso arquivo de rotas na parte superior, const, crypt é igual a require Agora, em nossa API, criamos Cost het pass é igual a await, criamos pontos s. E aqui, no primeiro argumento, temos que passar nossa senha, e no segundo argumento, passamos o número de sal, que é dez Agora podemos simplesmente definir a senha para definir a senha. E depois disso, podemos simplesmente aguardar o ponto c. do novo usuário. O que queremos fazer depois de criar um novo usuário Certo, geramos o token JWT para esse usuário e, para isso, precisamos do pacote de token web JSN Então, o NPM instala o token web JSON, na taxa 9,0 0,2, e Bom. Agora minimize esse terminal e vamos inserir esse token web JSN na parte superior Sacst JWT é igual a exigir o botão JSN. Agora, como fizemos anteriormente, criamos uma função para gerar JSN WebTGon porque também precisamos que em nossa API de login SacstGenerate, token seja igual a aqui obtemos os E nisso, simplesmente retornamos o sinal de ponto JWT. Primeiro, passamos os dados e, depois disso, precisamos passar a chave secreta do JWT Portanto, processe a chave de sublinhado JWT ponto a ponto. Agora precisamos adicionar essa variável chave em nosso arquivo ENV. chave de sublinhado do JWT é igual a aqui, podemos passar qualquer chave que seja segura Por exemplo, chave de segurança JWT. Não use isso para produção. Eu passo aleatoriamente. Você precisa criar sua própria chave de segurança. Além disso, aqui eu não adiciono a expiração nosso token porque, para aplicativos de mídia social, expiração do token não é boa. Os usuários desejam acessar nosso site rapidamente. Além disso, imagine que você visita Instagram todos os dias e, todos os dias, precisa fazer login. Se você usar esse aplicativo por muito tempo, não. Então, como desenvolvedores, precisamos sempre pensar da perspectiva do usuário. Agora, em nosso retorno de chamada de rota de API, simplesmente const token é igual a gerar Aqui na parte inferior, eu removo o Typo do nome da minha função Agora, em nossa função de gerar token, precisamos passar os dados do usuário que queremos adicionar em nossa carga de pagamento de tokens. Então Objeto, ID de sublinhado para o novo ID de sublinhado de ponto usuário e nome de usuário para o nome de usuário de ponto mais recente E, no final, simplesmente retornamos status do ponto de resposta para 01 para o novo ponto GSN de criação de dados e passamos esse token diretamente Agora, vamos experimentar essa API. Então abra o Postman. Aqui criamos uma nova coleção, criamos uma coleção em branco para nosso novo projeto chamado Our Linky Fi E nessa pasta, adicionamos uma nova pasta chamada usuários e, nessa pasta, adicionamos uma nova solicitação, chamada register, um novo usuário. Bom. Agora, solicite o tipo de publicação e aponte para SDDP, host local de barra dupla da coluna, usuário da barra barra da coluna 3.000 E envie a solicitação. Veja, aqui temos um erro, 500 não pode desestruturar os preenchimentos ausentes Vamos passar todos os preenchimentos de formulários necessários. Selecione corpo, bruto e aqui passamos nosso objeto JSON. Nome de usuário para codificar, sublinhar, abençoar. A propósito, esse é o meu nome de usuário do Instagram. Próximo e-mail para codificar no gmail.com vermelho. E por último, enviamos a senha 212-34-5678 Veja, aqui obtemos um token como resposta. E se verificarmos nosso banco de dados, aqui obtemos nosso banco de dados vinculado e, na coleção do usuário, veja, aqui também obtemos novos dados do usuário Além disso, obtemos o status da conta ativa, verificada e privada, ambas falsas. Definimos todos esses valores como padrão no esquema de nossos usuários. Além disso, aqui eu esqueci de adicionar exclusivo a verdadeiro para esse nome de usuário, porque aqui queremos que esse nome de usuário seja exclusivo para todos os nossos usuários 158. Exercício: API de login do usuário: Agora vamos fazer outro exercício. Neste exercício, você precisa criar uma API de login, que verificará o nome de usuário e a senha do usuário. Já fizemos isso em nosso projeto anterior, mas quero que você faça isso sozinho. Você pode ver esse código de verificação de senha, mas o restante da API precisa ser criado por conta própria. Eu sei que você pode fazer isso, então complete este exercício e, em seguida, qual é a solução. 159. Solução: API de login do usuário: Espero que você conclua o exercício ou tente resolvê-lo. Agora vamos ver a solução. Então, roteador, poste pontos e aponte para cortar o login E aqui passamos função assíncrona com solicitação e resposta Agora, primeiro de tudo, nessa função de retorno de chamada, obtemos os dados do corpo da solicitação Portanto, o objeto de custo é igual ao corpo do ponto da solicitação. E aqui chegamos ao nome de usuário e senha. Agora podemos passar a condição se o nome de usuário não estiver disponível ou a senha não estiver disponível, retornaremos o erro. Então, retorne resposta, status, 400 Json. Aqui, passamos Object success para false e a mensagem para fornecer nome de usuário e senha. Agora, depois disso, encontraremos o usuário com esse nome de usuário. O custo do usuário é igual a aguardar o ponto do usuário Fine one. Aqui no objeto, passamos nome de usuário para nome de ou também podemos removê-lo. Agora, talvez não encontremos nenhum usuário com o nome de usuário fornecido. Se o usuário não estiver disponível, retornaremos o status de ponto de resposta, objeto Json de 400 pontos com sucesso para falso e a mensagem para credenciais inválidas Agora, se encontrarmos o usuário , precisaremos comparar a senha usando a Biblioteca BCRP. Segundo, a senha válida é igual a await, B crypt dot compare. Primeiro, passamos a senha de entrada, que é front-end no corpo da solicitação, e no segundo argumento, passamos a senha dot do usuário Simplesmente passamos aqui outra condição senha válida é falsa ou não está disponível , retornamos o código de status 401 do ponto de resposta, que significa token de autenticação inválido ou ausente Além disso, enviamos o objeto Json com sucesso para false e a mensagem para credenciais inválidas Aqui, se especificarmos a senha não correspondida , isso significa que encontramos usuário e apenas a senha não corresponde Além disso, aqui acho que temos que passar o mesmo código de status para o usuário não encontrado. Altere esse 400 401 e a mensagem também será uma credencial inválida Agora, se a senha for verificada, poderemos gerar um novo token e enviá-lo na resposta. Portanto, const token é igual a gerar token. Aqui, passamos o objeto de dados com ID de sublinhado para o ponto do usuário, ID de sublinhado e nome de usuário para o nome de usuário ponto do usuário No último ponto de resposta, o Json envia esse token. É isso mesmo. Agora vamos experimentar essa API. No carteiro, criamos uma nova solicitação chamada Login a user Aqui, selecionamos o método SDTP para postar o endpoint no SDTP, coluna dupla ou barra, host local, coluna 3.000, API de barra, login de barra do usuário coluna dupla ou barra, host local, coluna 3.000, API de barra, login de barra do usuário e envio da solicitação. Veja, aqui temos um erro, não é possível desestruturar o nome de usuário da propriedade Então, aqui temos que passar os dados no corpo. Selecione corpo, bruto, aqui passamos objeto com nome de usuário para código, bênção e senha para 12345678 Veja, aqui recebemos a mensagem, credenciais inválidas porque eu passei um nome de usuário errado Eu mudo meu nome de usuário para o código original underscore bless e envio a solicitação Veja, aqui temos o token, que significa que nossa API está funcionando bem. 160. Implemente o Access Token e o Refresh Token [ATUALIZAÇÃO]: Agora, como vimos em nosso projeto anterior sobre registro e login, retornamos aos tokens, 14 tokens de acesso, que é a folha de classificação ou expiração do SOT, e outro é o token de atualização, que é folha longa ou token de expiração longa Resumindo, quando o token de acesso expira, front-end envia uma solicitação para algum endpoint, como Na repressão, verificamos o token de atualização e, em seguida, retornamos um novo token de acesso Essa é a lógica. Agora vamos implementar isso rapidamente em nosso terceiro projeto. Então, na parte inferior, temos a função de gerar token. Podemos renomear isso para gerar tokens. Agora precisamos retornar aos tokens a partir daqui. Então, armazenamos esse primeiro token na variável chamada token em excesso e, em seguida, definimos que ele expira na propriedade em, digamos, 1 hora Na produção, podemos adicionar o excesso de validade do token a três ou 4 horas. Mas, para testar facilmente esse aplicativo, não estou definindo o tempo de expiração para o excesso de token Novamente, estou falando apenas para o teste, que não precisemos gerar outro token em excesso em nossas próximas APIs Agora duplique essa linha, altere a variável para atualizar o token, ou seja, alteramos para objeto, ID de sublinhado para ID de sublinhado de ponto de dados E aqui adicionamos o cenário de expiração a 30 dias porque, finalmente, este é um aplicativo de mídia social, simplesmente somos um objeto com acesso e token de atualização Além disso, definimos uma chave secreta diferente para o token de acesso e o token de atualização Não é necessário, mas é melhor fazermos isso. Arquivo Pt NV no local da chave JWT, adicionamos token de acesso, chave e depois definimos outra variável, reprimimos o token, a chave é igual à nossa chave Salve isso e volte para nosso arquivo de saída do usuário. Aqui, trocamos a chave secreta pela chave do token de acesso. E para atualizar o token, nós o alteramos para atualizar a chave do token Agora, na API de login, altere o nome dessa função para gerar tokens. No local de obtenção do token, obtemos o objeto e desestruturamos excesso e o token de atualização a partir dessa função Bom. Agora, aqui estamos um símbolo em excesso na resposta. Além disso, você pode me dizer o que devemos fazer antes de enviar o token excedente na resposta? Certo. Precisamos armazenar o token de atualização na coleção do usuário e depois vender o token de atualização no cookie somente do SDTP Então, aqui aguardamos os pontos Bcrt. Aqui, passamos o token de atualização, coma, passamos aqui Essa expressão retorna o token. Então, nós o armazenamos em uma variável chamada Nu, o token de repetição. Depois disso, o token de repressão de pontos do usuário é igual a Novo tem o token de repressão Em seguida, temos que aguardar o ponto C. Agora, basta definir o token de atualização no cookie para lembrar como usamos o cookie de ponto de resposta Aqui, passamos o nome do cookie, que é token de atualização Aqui, adicionamos o token de atualização e, no terceiro parâmetro, precisamos passar o objeto de configuração Aqui, a primeira propriedade é somente SDDP, que definimos como verdadeira, segura ou falsa, mas garantimos que, para a produção, você a torne Mesmo site de streaming para o mesmo domínio, mas atualmente, nós o configuramos como nenhum e, finalmente, podemos passar a mensagem para 30 dias em 24 horas em 60 minutos em 60 segundos em 1.000 milissegundos e Agora precisamos simplesmente copiar essa lógica da geração do token até o envio resposta e colá-la aqui nesta API. E aqui, temos que alterar apenas o ID de sublinhado do ponto do usuário para o novo ID de sublinhado do ponto do usuário, novo nome de usuário do ponto do usuário, novo usuário, token de atualização do ponto e também do Nwuser dot Por fim, na resposta, também adicionamos status a 201. 161. Rota de atualização e logout [ATUALIZAÇÃO]: Agora, vamos criar uma rota para atualização, então Route dot post slash refresh e aqui adicionamos função de retorno de chamada ASN com solicitação e resposta Agora, primeiro de tudo, precisamos obter o token de atualização do Cookie Portanto, o token de atualização do usuário const é igual ao token request dot Cookie, dot refresh Aqui não recebemos esse cookie porque em nosso middleware Express, não criamos o middleware do analisador de cookies e, para isso, precisamos do pacote do analisador de cookies, abrimos o terminal e aqui escrevemos NPM install Cookies parser e pressionamos Enter esse cookie porque em nosso middleware Express, não criamos o middleware do analisador de cookies e, para isso, precisamos do pacote do analisador de cookies, abrimos o terminal e aqui escrevemos NPM install Cookies parser e pressionamos Enter. Bom. Agora abra o arquivo index dot gs. Na parte superior, inserimos const Cookie parser é igual a require Cookie Na parte inferior, adicionamos app dot g, Cookie parser. Certifique-se de chamar essa função aqui. Salve esse arquivo e volte para nossa rota. Aqui, passamos pela condição. Se o token de atualização do usuário não estiver disponível, retornaremos o status de ponto de resposta 401 dot Json e aqui passaremos Não, token de atualização fornecido. Depois disso, precisamos do ID do usuário que envia a solicitação de token de acesso e, como obteremos isso do token de atualização, precisamos decodificar esse token de atualização O custo do usuário decodificado é igual ao JWT dot. Verifique aqui passamos o token de atualização do usuário e, depois disso, passamos o processo da chave secreta de atualização dot ENV dot refresh ENV dot Agora, essa expressão pode retornar um erro, então adicionamos aqui, try e gatchblog simplesmente mova essa linha no blog seco E no blog de cache, retornamos o status de ponto de resposta 403, 44 PDN dot JSON e passamos sua mensagem para um token de atualização inválido Além disso, como sabemos, quando definimos variável usando custo, ela estará acessível somente neste blog seco. Então, temos que defini-lo antes do blog seco. E remova o custo daqui. Agora, depois disso, o custo do usuário é igual a um peso, usuário finaliza o BYD. E aqui passamos o ID decodificado do ponto de sublinhado do usuário. E então, se o usuário não estiver disponível, retornaremos o status de ponto de resposta 404 pontos Json E aqui adicionamos a propriedade da mensagem ao usuário não encontrado. Agora, se encontrarmos o usuário, teremos que comparar os tokens e, para isso, simplesmente usamos o pacote BCRP. Então espere, BCRP dot compare. Passamos o token de atualização do usuário, que obtemos do cookie e o comparamos com o token de atualização do ponto do usuário Essa expressão retorna o resultado da comparação. O segundo é válido. E também aqui passamos outra condição I é válido é falsa, então retornamos novamente o status de ponto de resposta 403 pontos Json com mensagem para atualizar o token não é Agora, se o token for válido, o que faremos? Criaremos novos tokens, armazenaremos o token de atualização na coleção do usuário, definiremos o token de atualização no cookie SDDPoly e, em seguida, retornaremos o token e, em seguida Essas etapas já foram executadas na API de registro e login. Copie o, basta colá-lo para atualizar a API e pronto. Agora, vamos definir rapidamente a API para o logout também. Em seguida, experimentaremos essas duas APIs juntas. Rota, lançamento de dardo, apontar para cortar Logout. Lembre-se de que, para este projeto no front-end, precisamos usar API para API de barra, usuário de barra, atualização de barra ou ponto de saída porque os adicionamos à Aqui, adicionamos o retorno de chamada ASN com solicitação e resposta. Agora, você pode me dizer o que devemos fazer no bloqueio? Certo, é muito simples. Precisamos remover o token de atualização do cookie e, em seguida, simplesmente remover o token da coleção do usuário Além disso, ao conversar com você sobre a coleção do usuário, lembro que não adicionamos token de atualização preenchido na coleção do usuário Então, vamos fazer isso primeiro e depois concluiremos essa rota de bloqueio Então, o modelo de um usuário e, na parte inferior, adicionamos astken preenchido ao objeto, tipo e string Não cumprimos o obrigatório porque, quando nosso usuário bloqueia , precisamos remover o astken Se adicionarmos obrigatório , isso não nos permitirá fazer isso. Simples assim. Agora, na API de logout, a tarefa inicial é muito semelhante à API de atualização. Por exemplo, também precisamos obter o token do cookie, encontrar o token de atualização do usuário e torná-lo nulo Então, vamos copiar o código da API de atualização e colá-lo aqui Bom. Agora vamos verificar esse código desde o início. Isso é bom. Isso também é bom até conseguirmos o usuário. Aqui, não precisamos criar tokens, então podemos remover isso. Além disso, não precisamos usá-lo como token, então podemos remover essa linha e, em seguida, aqui armazenamos null no token de repressão Agora, no local da resposta, dart Cookie, usamos response, dot clear Cookie Primeiro, passamos o nome do cookie, o que está bem. Depois disso, aqui não precisamos passar essa variável do token de atualização, mas precisamos desse objeto de configuração e, por fim, simplesmente retornamos a mensagem no local do token de acesso, bloqueada com sucesso e concluída Agora, vamos testar rapidamente essas APIs. Então, com um carteiro na pasta do usuário, criamos uma nova solicitação chamada repress access token Precisamos de uma solicitação de postagem. Aponte para SDD P, coluna, barra dupla, host local Coluna 3.000, corte o usuário das APIs, reprima com barra Veja, aqui recebemos um erro porque não temos Cookie, vá para Login Route, envie a solicitação com detalhes de gravação. Veja aqui que obtemos o token e também o token de repressão está definido como Cookie Agora, de volta à API de repressão, envie a solicitação novamente. Veja, aqui temos o novo token. Ótimo. Agora vamos experimentar a API Logout. Basta duplicar essa solicitação e alteramos o nome da solicitação para , digamos, desconectar um usuário, e também alteramos o endpoint da API para cortar usuário, cortar Logout Veja, recebemos uma mensagem de sucesso e, se verificarmos o cookie, veja, aqui não recebemos um token de atualização, as duas APIs estão funcionando Além disso, quero dizer que esta lição atual e a anterior são lições atualizadas. Se, no futuro, você não vir esse código na minha gravação de tela , não se preocupe, você pode absolutamente seguir essas lições. Eu só quero deixar os cursos o mais atualizados possível. Você também aprenderá as melhores práticas atuais para o Node jazz. 162. Detalhes atuais do usuário logado: Vamos criar outra API para enviar os detalhes dos usuários conectados Então, aqui adicionamos outro ponto Get point do roteador à barra frontal e simplesmente passamos aqui função de retorno de chamada ASN com solicitação Bom. Agora, nesta função, custo do usuário é igual a await user dot find By ID E aqui simplesmente passamos o ID do usuário. Mas como podemos obter essa identificação? Sim, precisamos extrair esse ID do token JWT. E para isso, precisamos criar o Osmddalware. Por enquanto, concluímos essa API e, em seguida, adicionaremos o Othmidalware Aqui, passamos o ID de sublinhado do ponto do usuário do ponto da solicitação. Agora, não queremos enviar uma senha com esses dados. Adicionamos aqui o método de seleção de pontos e, na string, adicionamos a senha negativa Depois disso, se não obtivermos o usuário, passamos a condição I, usuário não está disponível retornamos o status 404 do ponto de resposta Também passe o objeto GSN de ponto com sucesso para as quedas e a mensagem para o usuário, não encontrada Se encontrarmos o usuário , simplesmente o retornaremos em resposta ao usuário Json Agora, muitos estudantes podem perguntar: podemos ver o código do projeto anterior ao aplicá-lo em nosso novo projeto? Sim, claro, você pode ver esse código. Pense, há algo que você pode melhorar nesse código? Se sim, melhore-o e, se não, continue com esse código. Não há nada de errado nisso. Vamos criar o middleware OS. Então, em nosso projeto, criamos uma nova pasta chamada middleware E nessa pasta, criamos um novo arquivo de middleware chamado oth dot js Agora, primeiro de tudo, aqui criamos uma função chamada OT e sabemos que essa é uma função de middleware Então, obteremos aqui três parâmetros, solicitação, resposta e a seguir. Agora, nessa função, primeiro obtemos um token do cabeçalho da solicitação. Você se lembra em qual cabeçalho nosso front-end passará o token? Escreva no cabeçalho de autorização, o cabeçalho secondSto é igual a solicitar cabeçalhos de pontos autorização de pontos Depois disso, verificamos a condição. Se o cabeçalho de autenticação não estiver disponível, ou se ambos os pontos do cabeçalho começarem aqui nos códigos, passaremos o espaço de Barr. Se isso não for verdade, retornaremos o erro. Portanto, retorne a resposta, o status de ponto 401 para objeto Json não autorizado, sucesso para forçar e mensagem para autorização, Agora, se obtivermos os dois cabeçalhos , precisaremos extrair nosso token desse cabeçalho. Portanto, o token de custo é igual ao método de divisão de pontos do cabeçalho Em códigos, passamos o espaço e aqui precisamos do segundo item, então colchetes, índice um Já vimos isso no projeto anterior. Certo. Então, agora temos um token. A única coisa é que precisamos verificar o token e definir os dados de nossos usuários na solicitação dot user. O usuário decodificado pela seção é igual ao JWT dot Verify. Aqui, primeiro, passamos nosso token, que obtemos do cabeçalho. E então, no segundo argumento, passamos a chave de sublinhado JWT dot EV dot do processo Podemos simplesmente definir essa variável como usuário do ponto de solicitação. O usuário do ponto de solicitação é igual ao usuário decodificado e, em seguida, chamamos a próxima função Isso é a coisa mais importante. Agora, e se não conseguirmos esse usuário decodificado? Se não lidarmos com isso , receberemos um erro. Então, lidamos com isso com o bloco try and catch. Aqui, tentamos o bloco de cache e simplesmente movemos essas três linhas no bloco try. No bloco de cache, simplesmente retornamos response, dot status, 401, dot Json, Object, success para false e message para token inválido. E pronto. Agora vamos exportar essa função. Portanto, as exportações de pontos do módulo são iguais a OT. Agora, de volta à rota de nossos usuários. Aqui em nosso GIPI, adicionamos ambos os middlewares, veja Agradável. Agora vamos provar isso. Então, quando Postman, aqui adicionamos uma nova solicitação chamada current locked in user point para SJDP, Column double four slash Local host, Column 3.000 API slash Veja, aqui temos um erro, o token de autorização é necessário. Então, da chamada de API anterior, copiamos esse token JWT e, em nossa API atual, vamos para os cabeçalhos Aqui, adicionamos o cabeçalho de autorização. Valorize o espaço de Barr , cole nosso token e envie a solicitação Veja, aqui eu recebo um token inválido, mas por que eu passo o token válido Vamos verificar o terminal. Veja, o servidor também está em execução. Acho que um erro está acontecendo no bloco seco e de cache. É por isso que meu servidor ainda está funcionando. Então, aqui no bloco de cache, adicionamos esse erro ao log de pontos do console. Defina as alterações e envie a solicitação novamente. Agora, de volta ao código VS, de volta ao terminal, e aqui temos um erro, JWT não está definido Ah, esqueci de importar o JWT do pacote de tokens JSON Web Portanto, no topo da const, JWT é igual ao token web JSN necessário Você pode ver que é assim que podemos resolver o erro. Não entre em pânico se ocorrerem erros em seu código. Tente resolver isso passo a passo. Se ocorrerem muitos erros, podemos aprender mais sobre nossos erros e, com isso, melhorar nosso código. Portanto, não se preocupe com erros. Veja as mudanças e dê uma olhada. Veja, aqui temos os detalhes de uso sem senha. 163. Redefinindo a senha do usuário: Agora vamos implementar o recurso de redefinição de senha em nosso aplicativo. Primeiro, vamos entender a visão geral desse recurso. Portanto, quando o usuário inserir seu e-mail e clicar no botão de redefinição de senha, chamaremos nossa primeira solicitação de API de redefinição de senha Agora, essa API gerará um novo token e enviará uma URL com esse token em seu e-mail. Quando os usuários clicarem no link desse site, obteremos uma nova senha do usuário e, quando os usuários clicarem em enviar, chamaremos nossa segunda API de redefinição de senha Nessa API, verificaremos esse token e atualizaremos a nova senha no documento do usuário. Se tudo funcionar bem, retornaremos a mensagem, a senha, redefinida com sucesso. Aqui, precisamos criar duas APIs, solicitar a redefinição da senha e redefinir a senha Então, vamos começar criando a primeira API, então o Router dot post endpoint para solicitar a senha Ds, D reset, e também adicionamos função de retorno de chamada ASN com solicitação Portanto, aqui não estamos adicionando utensílios ortomidais porque queremos que qualquer pessoa possa redefinir sua senha Eles estão redefinindo a senha porque, em 99% dos casos, eles esqueceram a senha, então não conseguem fazer login, e é por isso que não adicionamos aqui o orthomidalware Agora, primeiro, recebemos um e-mail do usuário do corpo da solicitação. O segundo objeto é igual ao corpo do ponto solicitado. E aqui recebemos o e-mail. Agora, usando esse e-mail, vamos primeiro verificar se o usuário está disponível ou não. Portanto, const user é igual a await user dot Fine one. E aqui passamos o objeto de comparação com e-mail para e-mail. Em seguida, passamos a condição. Se o usuário não estiver disponível, retornamos a resposta cujo código de status 404 pontos Objeto Json com sucesso cai e a mensagem dois, este e-mail não está registrado ou também podemos passar o usuário não encontrado Depende totalmente de você. Agora, se o usuário estiver disponível, o que faremos? Certo, vamos gerar o token. Portanto, o custo, o token de redefinição é igual ao ponto seno do JWT. Primeiro, passamos nossos dados, então objeto, sublinhado para ID de sublinhado de ponto do usuário E no segundo parâmetro, passamos a chave JWT, então processamos a chave de sublinhado dot Env dot JWT E também no terceiro argumento, passamos o objeto com expirações na propriedade para 1 hora porque aqui queremos adicionar essas expirações na propriedade, e é por isso que não usamos here generate para Nós redefinimos o token. Agora, queremos apenas enviá-lo para o e-mail do nosso usuário. Enviar um e-mail é uma lógica separada, então, atualmente, não a implementamos. Primeiro, criamos nossas duas APIs de redefinição para que não confundam você Então, aqui estamos escrevendo um comentário para enviar e-mail e, em seguida, simplesmente retornar a resposta Json Aqui passamos Objeto com propriedade de mensagem, redefinição de senha, link, envio para e-mail. E depois disso, também passamos o token de redefinição para o token de redefinição. Enviando esse token de redefinição em resposta porque ainda não enviamos e-mails. É só para testar. Depois de enviar o e-mail, não precisamos passar o token de redefinição na resposta. Agora, vamos definir nossa segunda API na qual verificaremos esse token de redefinição e salvaremos a nova senha. Então, o roteador pontue e aponte para uma barra e redefina a senha. E aqui adicionamos função de retorno de chamada ASN com solicitação e resposta Em primeiro lugar, recebemos preenchimentos do corpo da solicitação. Portanto, o objeto Const é igual ao corpo do ponto de solicitação, e aqui desestruturamos o token de redefinição e também obtemos a nova senha que o usuário deseja atualizar Aqui, precisamos executar duas etapas. Etapa 1, verifique o token, e etapa 2, se o token for verificado, atualize a senha. Simples assim. Portanto, para verificar o token, podemos usar o JWT dot Verify Primeiro, passamos nosso token de redefinição. No segundo argumento, precisamos adicionar nossa chave JWT, ponto de processo, ponto ENV, ponto, chave de sublinhado JWT Agora, essa expressão nos dará aos usuários dados que passamos quando geramos esse token. Veja aqui na parte superior, passamos o ID de sublinhado para o ID de sublinhado de ponto do usuário Armazenamos isso em uma variável chamada usuário decodificado. Agora encontramos o usuário usando esse ID de sublinhado e depois atualizamos a senha Permitir que o usuário seja igual a esperar que o usuário encontre por ID. E aqui passamos o ID decodificado do ponto de sublinhado do usuário. Agora, depois disso, passamos a condição. Se o usuário não estiver disponível, retornaremos a resposta com código de status do objeto Json de 400 pontos com sucesso para false e a mensagem para o token inválido ou expirado Agora, se obtivermos o usuário , simplesmente atualizaremos a senha. Aqui, para a senha, precisamos primeiro ter essa senha. Não podemos armazená-lo como está. Aguarde, crypt dot tem aqui, primeiro, passamos uma nova senha, e no segundo argumento, passamos o Salt, que é dez Isso gerará uma senha, para que possamos armazená-la diretamente na senha do ponto do usuário e, abaixo disso, simplesmente aguardamos o currículo do ponto do usuário E, por fim, simplesmente retornamos objeto Json de ponto de resposta com a propriedade message, senha foi redefinida com sucesso e pronto Na primeira API, geramos o token de redefinição e o enviamos por e-mail, e na segunda API, o usuário enviará esse token de redefinição volta para nós e nós o verificaremos. Se for verificado, somente então atualizaremos essa senha. Aqui na verificação do token, temos poucos problemas de segurança. Aqui estamos apenas verificando o token usando o JWTKey, mas isso não é Deixe-me explicar com um exemplo simples. Suponha que os usuários enviem solicitações de redefinição de senha. No back-end, geramos um token de redefinição e o enviamos ao usuário. Agora, isso pode acontecer, usuário pode enviar novamente a solicitação de redefinição de senha e enviaremos novamente o novo token de redefinição para o usuário. Agora, esses são dois tokens que são válidos para redefinir a senha Suponha que o usuário passe o segundo token e altere a senha. Agora, e se esse primeiro token antigo que os hackers obtiverem e alterarem a senha usando esse antigo token de redefinição. Essa implementação é pouco arriscada. Agora, qual é a solução aqui? É muito simples. Quando geramos um token de redefinição em nossa primeira API no momento anterior ao envio do e-mail, armazenamos o token de redefinição na coleção do nosso usuário. Além disso, armazenamos a expiração e o prazo de validade do token. Agora, quando verificarmos o token, compararemos o token de redefinição armazenado com o token de redefinição do usuário. Se ambos corresponderem e o token não tiver expirado , atualizaremos a senha Somente com essa abordagem, o token de redefinição mais recente é válido e somente para os prazos e prazos Essa abordagem é mais segura que a anterior. Então, vamos implementar isso. Aqui, antes de enviarmos o e-mail, escrevemos que o token dot Reset do usuário é igual ao token de redefinição e o token do usuário dot reset expira é igual à data dot now, além disso, queremos adicionar 1 hora de expiração Então, 60 minutos em 60 segundos em 1.000. Convertendo segundos em milissegundos. E depois disso, podemos aguardar o ponto c. Também na parte superior, convertemos esse usuário const em at user Além disso, precisamos adicionar esses dois preenchimentos no modelo do nosso usuário Então, quando o usuário Schema, aqui, no final, adicionamos o token de redefinição ao objeto, o tipo à string e, depois disso, o token de redefinição expira para o objeto e o tipo para a data, salvamos as alterações e retornamos à nossa API de redefinição Na parte de verificação, adicionamos condição se o usuário não estiver disponível, ou se o token de redefinição de ponto do usuário for igual ao token de redefinição ou se o token de redefinição do ponto do usuário expirar for menor ou igual Se alguma dessas condições for verdadeira, retornaremos o token expirado e o token não foi verificado Além disso, depois de atualizar a senha, precisamos tornar esses dois preenchimentos nulos Antes do ponto c do usuário, definimos a redefinição do ponto do usuário, token é igual a nulo e o token de redefinição do ponto do usuário expira Isso é mais seguro. Se o usuário redefinir a senha com sucesso, não haverá tokens válidos para redefinir a senha. Agora vamos testar essa implementação. No Postman, criamos uma nova solicitação chamada solicitação , redefinição de senha, método, para postar ponto no SDDP, coluna com barra dupla, host local, coluna 3.000, API de barra, usuário de barra, solicitação de barra, usuário de barra, solicitação de barra E no corpo, vá para raw e aqui passamos o objeto JN com e-mail. Certifique-se de passar um e-mail válido e também de que o e-mail deve estar no e-mail do usuário. Caso contrário, faremos com que o usuário não seja encontrado. Se você não passar um e-mail válido nos dados do usuário, a partir do passe Mongo Di become, você pode alterar isso Agora envie o pedido aqui, eu recebo que Ken não seja encontrado. Deixe-me verificar o endpoint. Oh, aqui está o pedido, há a senha, vamos redefinir. E no meu endpoint, escrevo uma solicitação, vamos redefinir a senha Então eu mudo esse endpoint e envio essa solicitação. Veja, aqui obtemos um token de redefinição, copiamos esse token e precisamos criar uma nova solicitação chamada método de redefinição de senha para publicar e enviar o endpoint para o SDDP, coluna com barra dupla host local, coluna 3.000, usuário da API de barra, Além disso, aqui precisamos passar o corpo, o objeto bruto com o token de redefinição e colar esse token. E então passamos a nova senha. 123-45-6789. Agora envie a solicitação. Veja, obtivemos a redefinição de senha com sucesso. Portanto, ambas as APIs estão funcionando. Agora, a única coisa que queremos fazer é enviar esse token ou redefinir o link da página no e-mail do usuário, e veremos isso na próxima lição. 164. Maneiras de enviar e-mails no Node JS: Agora, existem várias maneiras de enviar e-mails a partir do aplicativo Node. A primeira é usando SMTP, que é um protocolo simples de transferência de e-mail A segunda maneira é usando a API SendGrid e a terceira é pelo Amazon SS, que é um serviço de e-mail simples Agora vamos ver os prós e os contras de cada forma, o que nos ajudará a decidir qual serviço de e-mail podemos usar para nosso aplicativo. Portanto, o SMTP funciona melhor para aplicativos pequenos porque é simples de configurar, precisamos passar apenas o e-mail e a senha da nossa conta e, em seguida, o SMTP enviará esse e-mail da nossa Mas o SMTP é um pouco lento em comparação com outros serviços de e-mail Além disso, com o SMTP, só podemos enviar uma quantidade limitada de e-mails Por exemplo, se usarmos o Gmail , só poderemos enviar 500 e-mails por dia Se usarmos o Yahoo, poderemos enviar apenas 100 e-mails por dia. O SMTP não é escalável para grandes empresas. É adequado para aplicações pequenas. Agora vamos passar para o snGrid. No SendGrid, não precisamos passar o e-mail e a senha da nossa conta Em vez disso, precisamos gerar APIKey e enviaremos e-mails usando a API SendGrids Portanto, isso é rápido e confiável. Também é fácil de configurar. Muitas empresas usam o SendGrid para enviar e-mails em massa, como Uber, AirBnB, aplicativo etc Mas para enviar e-mails ilimitados, precisamos comprar seu plano pago. Agora, vamos migrar para o Amazon SES. Este é o serviço de e-mail mais confiável e seguro usado por grandes empresas como Netflix, LinkedIn, etc Também é muito rápido. Podemos enviar milhões de e-mails por dia, e o plano pago deles é mais barato do que os planos Sandgrad, mas a única desvantagem é que é um pouco difícil de configurar Nós podemos gerenciar isso. Então, aqui, podemos ver claramente que, se precisarmos de velocidade, segurança e baixo custo , podemos usar o Amazon SES. Então, na próxima lição, implementaremos o Amazon SES em nosso aplicativo. 165. Configure o Amazon SES para enviar e-mails: Vamos implementar a pesquisa por e-mail Amazon Simple em nosso aplicativo de nós. É muito simples. Eu divido isso em três etapas. Etapa 1, configure o SS no aplicativo do nó. Etapa 2: criar uma conta Amazon SS e verificar o e-mail para teste. Etapa três, enviaremos um e-mail de teste da nossa API. Aqui, quero esclarecer uma coisa para configurar a conta Amazon SS precisamos dos detalhes do cartão de pagamento e da identidade. Não precisamos pagar nada, precisamos dos detalhes do cartão. Aqui, usaremos a versão anterior do Amazon SES. Portanto, se você não tiver esses detalhes, poderá pular esta lição e aplicar remetente de e-mail gratuito usando SMTP na próxima Para implementar o Amazon SES, precisamos instalar o pacote da AWS. Então, instale o NPM no cliente SDK da AWS Ss na taxa 3.738 0.0 Bom. Minimize o terminal. Agora, em nosso projeto, criamos uma nova pasta chamada Config e, nessa pasta, criamos um novo arquivo chamado Amazons dot js Primeiro de tudo, precisamos configurar o cliente SS e, para isso, precisamos do método do cliente SS. Então, colchetes Const CL. Aqui obtemos que o cliente SS é igual a exigir na taxa do cliente AWS SDK Ss Depois disso, const, pois cliente é igual a novo como cliente e dentro dele, temos que passar o objeto de inicialização Agora, a primeira propriedade do objeto é a região. Aqui, temos que passar pela nossa região. Armazenaremos a região no arquivo ENV, então adicionamos aqui a região do ponto de processo ENV Aws Score Depois disso, precisamos passar a propriedade das credenciais. Agora, isso é muito importante. Sem isso, não podemos enviar e-mails. Aqui, passamos um objeto com excesso de ID de chave e também precisamos passar uma chave secreta em excesso. Essas duas propriedades obteremos quando criarmos uma conta na Amazon AWS. Não se preocupe. Primeiro, configuramos tudo isso em nosso aplicativo de nós e, em seguida, criaremos uma nova conta no Amazon Aws. Então, aqui também passamos o ponto do processo An dot Aws, sublinhado Xs, chave de sublinhado Por segredo, passamos o processo ponto n ponto a ponto Aws, sublinhado, chave secreta de sublinhado e pronto Agora só precisamos criar a função Enviar e-mail e adicionar alguns preenchimentos de e-mail Portanto, Const send email é igual à função de seta. Aqui, antes de esquecermos de adicionar bloco try and cache, nós os adicionamos e, no cache, simplesmente consolamos dot log, Amazon, erro SCS. Aqui, adicionamos esse erro. Agora, vamos escrever nosso código no blog try. Se algo der errado , nosso bloco de cache consolará esse erro. Agora, para enviar o e-mail, precisamos fornecer algumas informações do e-mail, queremos enviar e-mail para qual e-mail queremos enviar, qual é o assunto, qual é o corpo, etc Portanto, os parâmetros de custo são iguais ao objeto. Aqui, primeiro somos uma fonte, aqui, temos que passar nosso endereço de e-mail verificado, que será verificado no site do Amazon SS. Não se preocupe, não escreva nada por enquanto. Deixe o plano. Certifique-se de escrever o nome dessa propriedade na capital, da mesma forma que eu escrevo. Caso contrário, você receberá um erro. Agora, após a origem, adicionamos o destino, adicionamos o objeto com a propriedade ao endereço e aqui temos que passar uma série de e-mails para quem queremos enviar e-mails Também podemos enviar e-mails para vários usuários. Agora, como podemos obter esse endereço de e-mail nessa função? Certo, a partir dos parâmetros. Então, aqui adicionamos dois, que é o endereço de e-mail. Além disso, precisamos do assunto do e-mail e também do texto do e-mail. Agora, aqui nos dois endereços, adicionamos dois parâmetros. Aqui, se tivermos vários , também podemos adicionar esses IDs de e-mail com vírgula Agora, após o destino, adicionamos a propriedade da mensagem ao objeto. Primeiro, adicionamos assunto ao objeto com propriedade de dados aqui, temos que passar o assunto que obtemos do parâmetro. Agora, depois do assunto, adicionamos corpo ao objeto, texto ao objeto e, dentro desses dados, ao texto, que obtemos novamente do parâmetro. Eu sei que essa é uma sintaxe um pouco estranha, mas é o que é Precisamos seguir isso. Agora temos nossas permanentes prontas Agora podemos criar um comando para esses perams. Const, o comando é igual ao comando New send email,. Então, a entrada automática funciona, e aqui simplesmente passamos os perams Agora precisamos enviar esse comando para enviar o e-mail. Então, o cliente Ss dot SN, e aqui passamos o comando. Agora, como sabemos, o envio do e-mail levará algum tempo, portanto, será uma tarefa assíncrona E para isso, aderimos e aguardamos. E por causa do await, precisamos tornar essa função assíncrona Agora vamos fazer a resposta na variável de resposta e, no final, simplesmente adicionamos o log de pontos do console, coluna ID da mensagem do e-mail enviado com sucesso e aqui retornamos a ID da mensagem do ponto de resposta. No final desse arquivo, simplesmente modulamos as exportações de pontos como o envio de e-mail. Certifique-se de não chamar essa função aqui. Só precisamos passar a referência. Além disso, aqui nas fontes, passamos o processo dot En dot Aws underscore, e-mail, que será nosso e-mail do qual queremos enviar o e-mail Então, aqui, nossa etapa número um está concluída. Só precisamos adicionar essas três variáveis no arquivo ENV e também precisamos passar esse e-mail de origem Acesse o navegador e acesse aws.amazon.com. E aqui precisamos criar uma nova conta da AWS. Aqui, escrevemos nosso endereço de e-mail e aqui precisamos passar o nome da nossa conta da AWS. Por enquanto, passe qualquer coisa, podemos alterá-la posteriormente nas configurações. Clique em Verificar endereço de e-mail. Depois disso, ele solicitará uma senha, basta criar uma senha e continuar aqui, vemos como um plano pessoal, e também precisamos passar nossos dados. Eu rapidamente escrevo meus detalhes, concordo e continuo. Agora, aqui, temos que passar os detalhes do cartão. Se você não tiver os detalhes do cartão ou não quiser fornecer suas informações, poderá implementar o SMTP porque a maioria dos alunos não tem cartão, então você pode implementar o SMTP, que usa apenas seu e-mail Eu vou te mostrar isso na próxima lição. Por enquanto, eu passo os detalhes do seu cartão , depois verifico e continuo. Isso processará pequenos pagamentos, como $1 ou até menos, para a verificação do seu cartão. Então, aqui eu insiro que meu pagamento OTP está sendo processado e aqui está feito o pagamento Agora temos que fornecer identidade. Selecione seu uso pessoal. Se você quiser usar para negócios , você também pode selecionar isso. Em seguida, selecionamos um indivíduo e, aqui, precisamos fornecer um documento de identidade. Então, eu preencho rapidamente este formulário e também carrego meu documento e clico em Continuar. Aqui estão mais alguns detalhes para verificação. Escrevo aqui meu número de telefone e envio SMS. Se você for de um país diferente, talvez consiga outro preenchimento. Aqui, verifico meu número com o OTP e continuo. Agora, aqui, acabamos de definir esse plano básico gratuito e, finalmente, concluir a inscrição e acessar o AWS Management Console Veja, aqui estamos no console. Em primeiro lugar, verificaremos o e-mail do remetente. Então, na parte superior, insira SEs e abra esta página do Amazon SS. Clique nessas três linhas e acesse identidades para verificar o e-mail ou o domínio Aqui, temos que criar identidades. Agora, se você quiser usar para produção, precisará verificar seu domínio aqui. Mas agora, para testar, podemos usar seu e-mail. Aqui, escrevemos nosso endereço de e-mail a partir do qual queremos enviar e-mails aos usuários e clicamos em Criar identidade. Veja aqui que temos a verificação pendente. A Amazon faz com que S envie um e-mail para esse e-mail e precisamos verificar isso. Então aqui eu abro esse e-mail. Clique neste link, veja a verificação concluída e, se atualizarmos essa página, veja aqui, também seremos verificados Portanto, temos que copiar esse e-mail e em nosso aplicativo de nó nas fontes, adicionamos o e-mail de sublinhado da AWS Vamos adicionar essa variável no arquivo ENV. e-mail de sublinhado da AWS é igual a aqui em que eu passo meu e-mail verificado Agora temos que criar a chave de acesso e a chave secreta para nosso aplicativo. Pesquise aqui IAM, que é gerenciamento de identidade e acesso. Aqui vamos até os usuários e criamos um novo usuário. Escrevemos o nome de usuário, digamos, nosso Linky Pi e clicamos em Avançar Aqui temos que anexar políticas, pesquisar aqui, AS full Xs e selecionar a política de processo completo do Amazon SS, clicar em Avançar e criar usuário. Agora, para gerar a chave de acesso, abra esse usuário e acesse as credenciais de segurança Aqui temos zero chaves de acesso, então criamos a chave, selecionamos outra opção e clicamos em Avançar. Aqui está pedindo uma descrição, mas é opcional, basta criar a chave de acesso. Veja, aqui temos a chave de acesso e também a chave de acesso secreta. Temos que adicioná-los em nosso arquivo ENV. Certifique-se de baixar esse arquivo CNV de pontos. Em nosso arquivo ENV, primeiro, eu adiciono aqui o nome da variável, AWS, sublinhado Xs, chave de sublinhado é igual a copiar a chave aces do navegador e colá-la em nosso Além disso, adicionamos outra variável chamada AWS, segredo de sublinhado, chave de sublinhado é igual a copiar a chave secreta do navegador e também colar aqui Agora precisamos de uma região. No arquivo ENV, adicionamos a região de sublinhado da AWS. Agora, esquecendo a região aqui no lado esquerdo do nosso perfil, obtemos uma lista de regiões Eu sou da Índia. É por isso que escolhi Mumbai Minha região será AP South One. Aqui, você tem que selecionar o seu. Se você não tiver uma ideia, basta pesquisar sua região no Google e selecionar a localização de Neal Eu adiciono esse valor de região no arquivo NV. Agora, aqui, nossa segunda etapa está concluída. Portanto, esse arquivo, a menos que a função de envio de e-mail esteja funcionando ou não, que é nossa etapa três. Em nossa solicitação, des resets password API, chamaremos a função Send Email no primeiro argumento para passar o e-mail do usuário O usuário pontuou a vírgula de e-mail aqui, escrevemos o assunto do nosso e-mail Vamos definir uma nova variável para o assunto igual à redefinição de senha, solicitação para sua conta Linkifi Além disso, definimos o texto que queremos enviar nos marcadores traseiros, clique neste link Redefina sua senha, SDDP cool e double forward slash, nossa senha de redefinição de barra do linkify.com No parâmetro de consulta, ponto de interrogação, reset tocan é igual a aqui adicionamos pacotes Dollar Curly, Esse URL é para acesso direto ou um front-end. Então, o sentido do Instagram, certo. Além disso, você pode modificar esse texto de acordo com suas necessidades ou também pode passar o código STML como corpo do e-mail Apenas nos parâmetros de e-mail no local deste texto, temos que passar STML Agora, na função Enviar e-mail, passamos o assunto e também o texto. Salve as alterações, a menos que essa função de envio de e-mail esteja funcionando ou não. Então, um carteiro, e aqui está uma API de solicitação de redefinição de senha, que é nossa primeira API para redefinição Agora, antes de ligar para isso, deixe-me passar aqui um e-mail válido para que eu receba o token de redefinição nesse e-mail. Aqui, eu mudo meu e-mail para um dos meus e-mails fictícios, atualizo e, também no corpo do ponto da solicitação, passo o mesmo e-mail Bom. Agora, vamos enviar a solicitação. Veja aqui que não foi possível enviar a solicitação. Oh, desculpe, eu esqueci de iniciar o servidor. Então, nodemon index dots Nice. Agora, vamos enviar a solicitação. Aqui eu recebo que o e-mail de envio não está definido. Eu esqueci de inserir isso. Portanto, no topo, o custo envio de e-mail é igual ao necessário. Aqui vamos abrir uma pasta, Config Amazon SCS. Salve isso e envie a solicitação novamente. Novamente, recebo um erro. Não entre em pânico. Vamos verificar. É um erro de validação. Então, como sabemos, acabamos de verificar e-mail do remetente no Amazon SES, mas também precisamos verificar o e-mail do destinatário para testar o recurso de e-mail É a condição do Amazon SES para testar a conta sandbox Se passarmos para o plano de produção e pago , enviaremos um e-mail para qualquer pessoa sem verificar o e-mail Para o ambiente de teste, precisamos verificar o e-mail do destinatário. Então, deixe-me verificar qual e-mail eu uso para a conta de usuário no Mongo DB Compass Veja, isso é e-mail. Então, aqui, eu tenho que adicioná-lo em nossa identidade de usuário. Então pesquise Ss assim. Vá para identidades. Crie uma identidade, selecione e-mail e enviaremos seu e-mail, que está disponível em seu banco de dados. Crie identidade. Eles enviam novamente o e-mail de verificação neste e-mail. Então eu abro esse e-mail aqui e abro esse link. Veja, recebemos parabéns. Bom. Deixe-me atualizar esta página. Veja, está verificado. Então, vamos morrer novamente. Ainda assim, envie a solicitação, recebo que Sandymil não está definido Deixe-me verificar o arquivo Amazon SS. Oh, na parte inferior, esqueci de remover esse parêntese Eu adicionei para mostrar um erro e esqueci de removê-lo Salve isso e vamos enviar a solicitação novamente. Veja, aqui temos o token de reinicialização. Mas se verificarmos nosso terminal, veja, aqui ainda recebemos um erro de validação, erro do Amazon SS, e-mail. Vamos verificar a função SandyML. OK. Aqui no destino, temos que mudar esses dois endereços para dois endereços no plural Agora vamos tentar novamente. Aqui obtemos nosso token de redefinição. Agora vamos verificar nosso terminal. Aqui temos um novo erro. O e-mail não foi verificado nesta região. Mas por que, como sabemos, já verificamos nosso e-mail. Ainda assim, estamos recebendo esse erro. Deixa eu te explicar. Aqui, verifiquei nossos dois e-mails na região errada. Deixe-me também verificar no site da Amazon. Veja, aqui eu tenho a região da Europa selecionada e, na minha variável NV, passo pela região de Mumbai, e é por isso que recebo esse erro Eu seleciono aqui esta região umbi. Agora eu tenho que verificar novamente os dois e-mails nesta região. Vá para identidades, crie identidade, selecione aqui e-mail, escreva o e-mail e crie identidade Agora vamos verificar isso a partir de um e-mail válido. Agora tenho que fazer o mesmo com outro e-mail. Se eu comer e terminar aqui, Se eu comer e terminar os dois e-mails serão verificados para minha região. Então, agora vamos testar novamente nossa implementação. Envie a primeira chamada de API. Veja, recebemos o token de reinicialização. Além disso, se verificarmos nosso terminal , veja aqui que recebemos e-mails enviados com sucesso e também recebemos o ID da mensagem. E se eu verificar minha caixa de entrada de e-mail, aqui eu recebo o e-mail no spam porque aqui estamos no modo de degustação e também não verificamos Na produção, você precisa fazer pequenas alterações na configuração e seu e-mail não entrará na pasta de spam. Esse é o poder do Amazon SES. Eu sei que configurar essa conta SES é uma parte um pouco difícil e chata Mas para uma experiência melhor e suave como essa, precisamos nos livrar dessa tinta doce. Agora, o usuário pode abrir esse link de front-end e , em seguida, o front-end chamará nossa segunda API. Esse é o trabalho do front-end. Também desenvolva front-end se você é um link. Não se preocupe com isso. Agora, também, se precisarmos usar o Amazon SES para produção , precisaremos solicitar acesso à produção. Se verificarmos nosso status atual na página GetSet, veja atualmente, nosso status é sandbox, o que significa Aqui, podemos ler a menção nos cartões abaixo, verificar um endereço de e-mail e um domínio de envio para solicitar ces de produção, o que permite enviar e-mails em um nível de produção e aproveitar todos os recursos do SCS. Para produção, você precisa verificar o domínio de envio a partir daqui. E se você fornecer informações escritas e enviar uma solicitação , a AWS geralmente as aprova dentro de 24 a 48 horas Depois de obter a aprovação, podemos enviar um e-mail para o endereço de e-mail. Além disso, darei mais informações no artigo abaixo desta lição. Então, para produção, você pode ler isso. Está bem? Então é assim que enviamos e-mails da forma mais segura, super rápida e barata do Amazon SS. 166. Como enviar e-mails GRATUITAMENTE: Vamos ver como podemos enviar e-mails usando a forma SMTP, que é gratuita, mas tem limite diário Podemos enviar apenas 500 e-mails do GML SMTP e, se você usa o YahooSMTP, só podemos enviar 100 Mas para sua inscrição local ou projeto universitário, tudo bem. Além disso, se você implementar Amazon SS e ele estiver funcionando para você, poderá pular esta lição porque adicionaremos somente recursos de envio de e-mail nesta lição, mesma forma que fizemos na lição anterior Agora vamos ver a implementação do SMTB. Eu divido essa implementação em três etapas simples. Primeiro passo, implementaremos configuração SMTV no aplicativo do nó Em seguida, na segunda etapa, geraremos uma senha para o SMTB, na última etapa três, testaremos essa implementação Vamos começar com a etapa número um. Para implementar o SMTP, precisamos de um pacote chamado node mailer NPM instale o Node mailer, no d 6.10 0.0 e Bom. Agora, aqui em nosso projeto, crie uma nova pasta chamada config e, nessa pasta, criaremos um novo arquivo chamado SMTP dot js Bom. Agora, para iniciar a configuração, precisamos de um método node mailer do pacote O Sconst node mailer é igual a require node Mailer. E depois disso, precisamos criar um transporte para configuração. Então, nodemler dot Create Transport. E dentro disso, temos que passar o objeto de configuração. Aqui, adicionaremos propriedades e passaremos a maioria de seus valores no arquivo ENV Então, host para processar ponto a ponto: host SMTP Underscore. Em segundo lugar, precisamos de uma porta para processar ponto a ponto: SMTP Underscore POD ponto a ponto: SMTP Underscore Depois disso, volte à verdade. Esse valor é verdadeiro apenas para colocar 465. Para outros potes, precisamos usar um valor falso. Depois disso, passamos para o objeto. E aqui precisamos passar o usuário para processar ponto a ponto SMTP, sublinhado E depois disso, passe para o processo SMTP ponto a ponto, passe o sublinhado Não se preocupe, passaremos esses valores em apenas um minuto. Agora, para enviar o e-mail, criamos uma nova função chamada Enviar SMTP, e-mail é igual à função de erro Agora, nesta função, antes de escrever o código, é melhor adicionar o bloco try and cache. E no bloco de cache, passaremos o log de pontos do console. Erro ao enviar e-mail e simplesmente adicionar o e-mail. Agora, no blog do dri, adicionamos custos. As opções de e-mail são iguais ao objeto. Aqui passamos algumas opções. De dois processos dot nvt SMTP underscore user , temos Aqui, temos que passar o e-mail dos destinatários. Mas aqui está uma pergunta. Como podemos receber o e-mail do destinatário nessa função Certo, vamos obtê-lo a partir do parâmetro. Então, nós adicionamos também. Além disso, aqui precisamos de um assunto. Este é o assunto do nosso e-mail e também passamos o texto, que é o corpo do e-mail. Agora, nas opções, adicionamos dois a dois, sujeito ao assunto e texto ao texto. Portanto, temos opções prontas. Agora só precisamos enviar o e-mail. Aguarde, e aqui precisamos do transportador, que obtemos desse nodo do método Miller Então, vamos armazená-lo invariavelmente chamado transportador, e na função de envio de e-mail, usamos transportador dot send mail, aqui temos Essa expressão escreverá a resposta, então vamos armazená-la em uma variável chamada resposta. Por fim, simplesmente consolamos o registro de pontos, e-mail foi enviado com sucesso e também adicionamos o ID da mensagem e aderimos ao ID da mensagem com pontos de resposta. Para enviar o e-mail, basta chamar essa função e passar esses argumentos. Exportamos essa função usando o módulo que exporta é igual ao envio de e-mail SMTP Salve este arquivo e, agora, em nossa API de redefinição de solicitação, simplesmente ligaremos para aqui, enviaremos a função de e-mail SMTP e veremos o funcionamento do atoiput Aqui na lição anterior, eu criei essas duas variáveis, assunto e texto. Você pode copiar isso e, simplesmente nesta função, passar o e-mail com pontos do usuário, que é o e-mail do destinatário, assunto da vírgula e o texto Agora, deixe-me comentar essa função anterior Amazon SES. Aqui, nossa primeira etapa está concluída. Agora vamos para a etapa dois, que é definir variáveis de ambiente. Então, nos arquivos ENV da lição anterior, adicionei essas quatro variáveis para o Amazon SES. Se você não aplicar isso, não se preocupe. Agora, aqui passamos quatro variáveis para SMTP. Se você não se lembra dos nomes deles, basta copiá-los do código. Não há nada de errado nisso. Então, primeiro, SMTP e ace host são iguais a aqui em que estou usando o GMLHst, então escrevo smtp.gmail.com Depois disso, a porta de sublinhado SMTP é igual a 465. Aqui, se você estiver usando o Yahoo ou o Outlook, poderá usar os valores de postagem e porta Mas o Gmail é bom para SMTP. Agora precisamos do usuário de sublinhado SMTP, e aqui passamos o e-mail do qual queremos enviar o Esse é o ID de e-mail da empresa. Então, aqui eu adiciono meu ID de e-mail. Eu uso este e-mail apenas para demonstração, no futuro, não vou usá-lo. Agora só precisamos passar a senha de sublinhado SMTP igual a aqui, podemos passar nossa senha do Gmail, mas depois de 2024, o Gmail não permite esse Então, em vez de passar uma senha real, podemos passar uma senha. Vamos ver como podemos gerar uma senha. Então, abra google.com e vá para gerenciar minha conta do Google. Aqui vamos para a segurança. Agora, para gerar a senha do aplicativo, há uma condição. Em nossa conta do Google, verificação em duas etapas não deve ser possível. Se estiver desativado para sua conta, você deverá ativá-lo. Caso contrário, você receberá um erro SMTP. Agora, depois de não conseguir realizar a verificação na parte superior, pesquise uma senha e abra a senha em segurança. Ele verificará você primeiro, ótimo. Agora é o nome do aplicativo. Aqui podemos escrever node, Miller, SMTV ou qualquer outro nome, não importa única coisa é que, no futuro, se você quiser remover essa senha do aplicativo, poderá se lembrar do nome do aplicativo. Agora clique em Criar. Veja, aqui temos uma senha de 16 dígitos, basta copiá-la e você também pode fazer captura de tela ou clicar em Foto no seu telefone porque, uma vez que a fechamos , não podemos ver a Copie isso e cole em nosso arquivo ENV. Certifique-se de deixar o espaço como está. Não mude nada nisso. E é isso. Aqui, nossa segunda etapa está concluída. Agora vamos para a etapa três, que é o teste. Portanto, antes de testar, certifique-se passar o e-mail válido nos dados do seu usuário. Se você não passar seu e-mail, poderá modificá-lo no Mongo DB Compass Ok. Agora abra o Postman, e aqui enviamos a primeira solicitação, a API de redefinição de senha Veja, aqui vamos redefinir o token e, se verificarmos nosso terminal, obteremos um erro. Conecte, coloque um ícone, recuse. Talvez seja um erro para uma senha de uso único. Então, deixe-me tentar novamente. Ainda assim, estou recebendo o erro. Então, deixe-me criar outra senha de aplicativo para nodemiler, SMTP, criar e copiar isso e certifique-se de clicar Agora, em nosso arquivo ENV, substitua a senha e salve esse arquivo Agora vamos tentar novamente. Envie a primeira solicitação. Aqui obtemos o token e no terminal, veja, recebemos o e-mail enviado com sucesso e também recebemos o ID da mensagem. E se eu abrir minha caixa de entrada, veja, aqui eu recebo o novo e-mail É muito simples enviar e-mails a partir do aplicativo Node. Resumindo, você pode usar Amazon SES para aplicativos do tipo corporativo e, se o seu aplicativo for pequeno, você pode usar o método SMTP, mas ele nos fornecerá apenas 500 e-mails em um dia, depende totalmente de você qual deles escolher 167. Seguidores e lógica de seguir: Atualmente, em qualquer aplicativo de mídia social, existem seguidores e o recurso de seguir é obrigatório Então, vamos também implementar isso em nosso aplicativo. Você pode ficar um pouco assustado com esse recurso se estiver implementando-o pela primeira vez. Mas confie em mim, é muito simples. Então, vamos primeiro entender a lógica de seguir e seguir Então aqui está, qual é o usuário de login em nosso aplicativo. E aqui está outro usuário, digamos que Harley e seu status de perfil sejam públicos Agora, você quer seguir a Harley, então aperte o botão Seguir Agora, o que aconteceu no back-end? Em primeiro lugar, para cada usuário, adicionaremos três novos campos no esquema do usuário, seguidores, que é a matriz de usuários que seguem esse usuário Aqui, adicionamos IDs de usuário como referência. Em seguida, adicionamos o campo a seguir, que é a matriz do usuário que é seguida por esse usuário. Por fim, adicionamos a solicitação de acompanhamento, que também é uma matriz, mas nela, adicionaremos o ID de todos os usuários que enviam solicitações para seguir o usuário. Adicionaremos o ID do usuário nesta solicitação de acompanhamento somente se a conta do usuário for privada. Agora, voltando ao nosso exemplo, suponha que você queira seguir Hurley e a conta de Hurley é pública Em primeiro lugar, seu ID de usuário será adicionado à lista de seguidores da Hurley Em seguida, o ID de usuário do Halley será adicionado à sua lista a seguir. Muito simples. Agora, aqui, conta de Halley é pública E se definirmos a conta dele como privada? Nesse caso, não podemos adicionar seu ID de usuário na lista de seguidores do Halley Nesse caso, adicionaremos seu ID de usuário na matriz de solicitações de acompanhamento do Hal. Agora Hali tem duas opções. Ele pode aceitar a solicitação ou rejeitá-la. Se Ali rejeitar, simplesmente removeremos seu ID de usuário da solicitação do AlisFollow Agora, e se Hali aceitar o pedido? Então, primeiro, removemos seu ID de usuário da lista de solicitações e o adicionamos à lista de seguidores Além disso, adicionamos o ID de usuário Hale à sua lista a seguir. Então, é assim que esse seguidor é simples e os seguintes recursos Agora, na próxima lição, definiremos a AEI para esses recursos 168. Siga o usuário: Agora vamos definir a API para adicionar seguidores. Como sabemos, a lógica é muito simples. Então, vamos implementá-lo rapidamente. Aqui na parte inferior, adicionamos o ponto final do roteador na barra frontal Aqui, adicionamos o ID do usuário, então a barra ID do usuário da coluna segue Esse é o ID do usuário que queremos seguir. Além disso, precisamos de um ID de usuário conectado, então adicionamos aqui um middleware e uma função de atendimento com solicitação e resposta Agora, dentro dessa função, primeiro lugar, obtemos esse ID de usuário, então o ID de usuário Const é igual ao ID de usuário request dot Perms dot Além disso, precisamos de const, ID do usuário atual é igual ao ID do ponto do usuário solicitado Em primeiro lugar, verificaremos uma condição. Se o ID do usuário for igual ao ID do usuário atual, retornaremos a resposta com o código de status 400 para solicitação inválida ponto, objeto Json, Você não pode seguir a si mesmo. A primeira lógica da API de acompanhamento é verificar se a outra conta de usuário é privada ou pública. Para isso, obtemos as informações do usuário. Portanto, o contras que o usuário deve seguir é igual a aguardar o ID de compra do usuário dot fine E aqui passamos o ID do usuário. Em seguida, aprovamos sua condição. Se o usuário a seguir não estiver disponível, retorne a resposta com o código de status 404 e Json para Objeto com a propriedade de mensagem, Usuário não encontrado Além disso, precisamos encontrar as informações atuais do usuário. Portanto, const current user é igual a await user dot Fine BD e passar aqui o ID do usuário atual E também passe aqui, a mesma condição, então duplique essa condição então duplique essa condição Alt mais sift mais seta para baixo ou Option plus sift mais seta para baixo e mova essa linha abaixo da opção de retenção na fonte ou altere as teclas de seta de retenção na fonte ou E aqui nós apenas mudamos esse usuário para o usuário atual. Agora, depois de obtermos os dois usuários, podemos transmitir sua condição se o usuário a seguir for privado. Se isso for verdade, isso significa que a conta é privada. Se a conta for privada, precisamos adicionar o ID de usuário atual na solicitação de acompanhamento do outro usuário. Mas, para isso, precisamos adicionar três campos no esquema de nossos usuários Então, no esquema do usuário, finalmente, adicionamos seguidores preenchidos à matriz e, dentro disso, adicionamos o tipo de objeto ao esquema de pontos do Mongoose, tipos de pontos, ID do objeto de ponto e Além disso, precisamos seguir e seguir a solicitação, que tem o mesmo tipo de esquema e referência de usuário Só aqui, alteramos o seguimento e seguimos a solicitação. Salve esse arquivo e volte para nossa rota. Aqui, escrevemos “usuário para seguir”, dot follow request”, “dot push”. E aqui adicionamos o ID de usuário atual e, em seguida, podemos esperar que o usuário siga dot save E aqui retornamos a resposta com mensagem JSON. Para seguir, solicitação enviada. Bom. Mas aqui está uma coisa. É possível que o usuário já esteja disponível na matriz de solicitações a seguir. Antes desse método push, adicionamos a condição I que o usuário siga o ponto siga a solicitação dot includes aqui, passamos o ID do usuário atual. Se o ID do usuário atual estiver disponível na matriz, retornaremos o status de ponto de resposta, objeto Json de 400 pontos com msATpperty para E depois disso, adicionamos s e podemos mover essa parte no bloco s. Então, aqui escrevemos a lógica de adicionar solicitação de acompanhamento se a conta for privada, mas nossa outra conta de usuário puder ser pública. Depois disso, se adicionarmos Ls, se você estiver ficando confuso, poderá escrever comandos para isso. Eu escrevo um comentário aqui, lógica para conta pública. Bom. Agora, o que queremos fazer se a conta for pública? Certo, adicionaremos diretamente ID do usuário atual na lista de seguidores e, na lista de seguidores do usuário atual, adicionaremos o usuário ao ID a seguir O usuário deve seguir dot followers dot push. Aqui, adicionamos o ID do usuário atual e, depois disso, o usuário atual, dot following, dot push. E aqui adicionamos o ID do usuário. E depois disso, salvamos esses dois documentos. Portanto, espere que o usuário siga dot save e aguarde o usuário atual dot Depois disso, retornamos a resposta com objeto JSON com a propriedade de mensagem, seguida pelo usuário com sucesso Agora, como fizemos anteriormente, talvez nosso ID de usuário atual já esteja disponível na lista de seguidores Nós superamos sua condição antes dessa lógica. Se o usuário seguir seguidores de pontos, ponto inclui aqui que passamos o ID de usuário atual. Se estiver disponível, retornaremos a resposta com o código de status, 400 para solicitação de morcego e, no objeto Jason com propriedade de mensagem, para quem já está seguindo o usuário Depois disso, adicionamos s e moveremos esse código no bloco se. É isso mesmo. É muito simples. Agora vamos testar essa implementação. Portanto, para testar a API a seguir, precisamos de outra conta de usuário. Vamos criar essa primeira API de usuário aberta, alterar o nome de usuário, digamos, Hurley 001 e enviar um e-mail para Hali no gmail.com vermelho Além disso, continuarei com a mesma senha. Caso contrário, esquecerei a senha e enviarei a solicitação. Veja, aqui temos o novo token de usuário. Aqui precisamos desse ID de usuário da Hurley. Então, de acordo com Mongoi, vamos até os usuários e copiamos esse novo De volta ao Postman para seguir, criamos uma nova solicitação Siga a API, método SDB, para publicar, URL para SDDP, coluna dupla, barra, host local, coluna 3.000, barra da API, barra do usuário, aqui paginamos o novo ID do usuário , clique em seguir API, barra do usuário, aqui paginamos o novo ID do usuário aqui paginamos Precisamos do token de usuário atual, então acessamos a API de login, alteramos a senha porque a alteramos em nossa lição anterior e enviamos a solicitação. Copie esse token e, em nossa API de acompanhamento, acessamos os cabeçalhos, aderimos à autorização e, no portador do valor, espaçamos o token E envie a solicitação. Veja, aqui o usuário é seguido com sucesso. Seguimos diretamente o usuário porque essa nova conta de usuário é pública. Agora, vamos provar também tornando essa conta privada. Então vamos ao Mongo Di BecompasrFresh the data. Primeiro, removemos o ID da lista a seguir. Além disso, removemos o ID da lista de seguidores e também tornamos essa nova conta de usuário privada para verdadeira e a atualizamos Agora, vamos voltar a seguir a API e enviar a solicitação. Veja aqui que a solicitação de acompanhamento foi enviada, adoravelmente. Agora, na próxima lição, criaremos uma API para aceitar a solicitação de acompanhamento e rejeitar a solicitação de acompanhamento 169. Aceite a solicitação de acompanhamento: Vamos definir a API para aceitar e rejeitar a solicitação de acompanhamento Primeiro, implementaremos a rejeição da solicitação porque será fácil de testar, então o roteador dot post and point to slash rejeita a solicitação Ds, slash e aqui precisamos do ID do usuário solicitante ID do solicitante da chamada. Depois disso, também precisamos da louça ortodôntica Adicionamos uma função de válvula de uso com solicitação e resposta. Agora, em primeiro lugar, nesta função, obteremos Cost, obteremos Cost, ID do solicitante é igual ao solicitação Perms dot ID do solicitante Além disso, precisamos de const, ID do usuário atual é igual ao ID de sublinhado do ponto do usuário solicitado, que obteremos deste Omdalware Antes de tudo, verificaremos se os dois usuários estão disponíveis em nossa coleção ou não. Lembre-se de que fizemos o mesmo na API anterior. Aqui está, copie esse código. Além disso, copie essa primeira condição para o mesmo ID e, na parte inferior, cole-a em nossa API de rejeição. Aqui precisamos fazer pequenas mudanças. Portanto, no local da ID do usuário, temos que adicionar a ID do solicitante e, aqui, também a ID do solicitante Além disso, precisamos alterar o nome dessa variável, então selecione o usuário a seguir, pressione F dois e altere isso para o usuário solicitante Nos dará mais clareza. Agora, para rejeitar a solicitação, basta remover o ID do solicitante da matriz de solicitações a seguir Mas antes disso, podemos verificar se solicitamos o ID na matriz de solicitações a seguir ou não. Portanto, se o ponto da solicitação dot follow do usuário atual incluir o ID do solicitante, se essa condição não for verdadeira, passaremos aqui o ponto de exclamação e retornaremos a resposta com o código de status 400 e o objeto JSON dot com a propriedade de mensagem dois, nenhuma E eu sigo que a solicitação foi encontrada, então aqui podemos usar o método de filtro para remover o ID do solicitante da matriz Portanto, Const, a solicitação atualizada é igual ao filtro dot follow request dot do usuário atual Aqui, adicionamos ID, que é o item individual dessa função de seta de matriz, e aqui retornamos a condição dt duas strings não iguais à ID do solicitante Isso removerá o ID do solicitante da matriz de solicitações a seguir Podemos simplesmente definir solicitação atual de pontos de acompanhamento do usuário é igual à solicitação atualizada. E então aguardamos o ponto c do usuário atual. E, por fim, simplesmente retornamos a resposta com objeto JSON com a propriedade de mensagem para seguir, solicitar, rejeitar e pronto Agora vamos testar essa API. Então, abra o Postman e aqui adicionamos uma nova solicitação chamada rejeitar a solicitação de acompanhamento Agora, neste caso, definimos o método da API para publicar e apontar para SDDP, coluna dupla para barra, host local, coluna 3.000, barra do usuário da API rejeitar a solicitação, barra aqui precisamos passar o ID do solicitante, que é o ID do usuário que enviou a Aqui abrimos o Mongo Db Compass, e você pode me dizer qual usuário enviou uma solicitação Certo, é nosso primeiro usuário, cujo ID é adicionado na matriz de solicitações de acompanhamento de outro usuário. Então, copie esse ID e cole no URL e enviaremos a solicitação. Oh, precisamos passar o JWT Token. Agora, aqui precisamos do token do usuário que está recebendo a solicitação, que é nosso novo usuário. Então, na API de login, eu altero o nome de usuário para Hurley 001 e também altero a senha e envio a solicitação Copie esse token. E na API de rejeição, acessamos os cabeçalhos, aderimos à autorização e valorizamos o espaço do portador, acompanhamos o token Agora enviamos a solicitação. Veja, aqui temos a solicitação de acompanhamento rejeitada. Como se verificássemos nosso banco de dados, atualize a coleção. Veja, para o segundo usuário, não recebemos nenhum ID na solicitação a seguir. Aqui, nossa API rejeitada está funcionando bem. Agora podemos definir a API para aceitar a solicitação do usuário. Essa API é muito semelhante à API de solicitação rejeitada, então copiamos a API inteira e a colamos abaixo. Bom. Agora, primeiro alteramos o endpoint para aceitar como solicitações o ID do solicitante Depois disso, se aceitarmos a solicitação, também precisaremos remover o ID do solicitante da matriz de solicitações a seguir Portanto, mantemos nosso código como está. Mas depois de remover o ID do solicitante, precisamos adicionar o ID do solicitante à lista de seguidores Isso significa que estamos aceitando a solicitação de acompanhamento. Portanto, antes do método de salvamento, adicione o usuário atual dot followers dot push. Aqui, enviamos o ID do solicitante e também precisamos adicionar o ID do usuário atual na a seguir dos usuários solicitantes Então, usuário solicitante, ponto após ponto, push. Aqui, enviamos o ID do usuário atual. Agora, também vamos aguardar o salvamento do ponto do usuário solicitante. Por fim, alteramos a mensagem para seguir a solicitação, aceita e pronto. Agora vamos também experimentar essa API. Então, voltando ao Postman aqui precisamos da mesma solicitação, como rejeitar Assim, podemos duplicar a API de sabor a partir daqui, alterar o nome para aceitar a solicitação de acompanhamento Também é um endpoint para aceitar como ID do solicitante da solicitação. E se verificarmos os cabeçalhos, veja, aqui também obtemos esse token, e é por isso que duplicamos esse Agora, vamos enviar essa solicitação de API. Veja, aqui não encontramos nenhuma solicitação de acompanhamento porque acabamos de rejeitar a solicitação de acompanhamento. Aqui, precisamos enviar a solicitação de acompanhamento novamente. Para isso, vamos seguir a API e enviamos a solicitação de acompanhamento. Pedido enviado, bom. Agora, volte para aceitar a API de solicitação e enviar a solicitação. Veja, recebemos a solicitação de acompanhamento aceita e, se verificarmos nosso banco de dados, atualizamos a coleção Veja, aqui também obtemos o ID do usuário na lista de seguidores e solicitamos nosso ID seja removido da solicitação de acompanhamento E aqui temos o ID na lista a seguir. 170. Exercício — obtendo a lista de seguidores e seguidores: Agora é hora de fazer um pouco de exercício. Neste exercício, quero que você crie duas APIs. Uma API para obter a lista do usuário de outro usuário e uma segunda API para obter a seguinte lista de outro usuário. Se você for o usuário um, poderá enviar uma solicitação para obter a lista do usuário dois, seguidores e seguidores. Aqui, nossa API tem esta aparência. Corte o ID de usuário da API, corte os seguidores. Corte o seguinte para seguir a API. Pense primeiro na lógica e depois implemente-a. É muito simples. Eu sei que você pode completar este exercício. Tente resolver isso e então qual é a solução. Espero que você conclua este exercício ou tente resolvê-lo. Aprecie a si mesmo por isso. Agora vamos ver a solução. Então, aqui adicionamos o ponto Get do roteador e apontamos para cortar o ID de usuário Colin e cortar seguidores Esse é o ID do usuário cuja lista de seguidores o usuário deseja ver. Portanto, precisamos de um middleware e, em seguida, função de retorno de chamada com solicitação Agora, dentro dessa função, primeiro, obtemos o custo do ID do usuário igual ao ID do usuário do ponto Perms da solicitação Além disso, precisamos que o custo, usuário atual, seja igual ao ID de sublinhado do ponto do usuário solicitado Agora vamos entender a lógica dessa API. Devemos mostrar a lista de seguidores de qualquer usuário não. Você pode ver somente a lista de seguidores dos usuários, quem você segue ou cuja conta é pública. Aqui, precisamos da lista atual de seguidores de usuários e outros usuários são propriedade privada Novamente, copiamos o código de ambos os usuários da API anterior e o colamos nessa API. Agora, aqui, alteramos o nome da variável para usuário e alteramos esse ID do solicitante para ID do usuário Bom. Agora, depois disso, podemos passar a condição se o ponto do usuário, os seguidores do ponto incluírem, aqui passamos o ID do usuário atual. Ou o ponto do usuário é privado é falso, o que significa que a conta do usuário é pública. Se alguma dessas condições for verdadeira, mostraremos a lista de seguidores dos usuários. Retorne o ponto de resposta Json, e aqui passamos os seguidores de pontos do usuário Adicionamos, e nisso retornaremos ponto de resposta Status 400 dot Jon, passaremos seu objeto com a propriedade de mensagem, Gant, Obtenha lista de seguidores, a conta é privada Agora vamos fazer essa implementação, salvar as alterações e abrir o carteiro Aqui, criamos uma nova solicitação chamada Obter lista de seguidores de usuários. Aqui adicionamos URL, SDP, barra dupla de quatro colunas, host local, coluna 3.000, API de barra, ID de usuário e, por fim, adicionamos seguidores de barra e, por fim, adicionamos seguidores de Agora, de volta ao banco de dados do Mongo DB, copie esse segundo ID de usuário, que tem seguidor, e cole esse ID na URL Agora, nesta API, precisamos passar o token. Então vá para os cabeçalhos. Aqui, adicione autorização e valor ao espaço do portador. E aqui, temos que passar outro token de usuário que está seguindo esse ID de usuário. Então, de volta à API de login, e aqui simplesmente fazemos login com a conta antiga, alteramos a senha e enviamos essa solicitação. Veja, aqui obtemos o token, copie e cole no cabeçalho da nossa API. Bom. Agora envie a solicitação. Veja, aqui temos a matriz com o ID do seguidor. Mas, como sabemos, no mundo real, precisamos mostrar o nome do usuário, então precisamos preenchê-lo Para isso, em nossa boa consulta, primeiro tínhamos o método populatet, passamos o nome de preenchimento que queremos preencher, que é seguidores, e depois passamos o nome de preenchimento, que queremos obter da referência, que é ID de sublinhado Agora, aqui está uma coisa. Aqui, preenchemos a lista de seguidores Então, agora não é o mesmo de antes. Será uma matriz de objetos com campos de ID de sublinhado e nome de usuário em cada objeto Então, não podemos passar aqui, isso inclui o método. Podemos usar o método Fine index que usamos nos projetos anteriores, e também escrever aqui condições diferentes, usuário atual, inclusões de ponto a ponto, e aqui passamos o ID do usuário. Portanto, se o usuário atual estiver seguindo o outro usuário , também podemos obter essa lista de seguidores. Salve as alterações e dê uma olhada. Envie a solicitação. Veja aqui a seguinte lista com ID e nome de usuário. Agora, vamos criar outra API e você adivinhou corretamente, duplicaremos essa API e, na parte inferior, a adicionaremos Agora, aqui precisamos mudar apenas pequenas coisas. Então, primeiro de tudo, alteramos o endpoint para cortar o ID do usuário e Então, aqui na consulta do usuário, precisamos preencher o campo a seguir, então essa condição será a mesma e alteraremos a mensagem para a lista a seguir, conta é privada e pronto Agora, na próxima lição, definiremos a API para deixar de seguir o usuário 171. Exercício — Dessiga o usuário: Deixe-me te dar outro exercício. Neste exercício, você precisa criar uma API para deixar de seguir o usuário Portanto, nosso endpoint de API ficará assim. Corte o usuário da API, corte o ID do usuário, corte e deixe de seguir. É muito simples, passe algum tempo e resolva esse exercício. E depois disso, volte e veja a solução. Agora vamos ver rapidamente a solução. Então, aqui escrevemos router dot Post e 0.2 slash Column, ID do usuário, slash Além disso, precisamos da função de retorno de chamada Omidleware ACN com solicitação com Agora, aqui precisamos encontrar os dois usuários. Portanto, copie esse código inicial com essas duas condições e, em nossa API, passe esse código. Agora, aqui não precisamos desse método de preenchimento, então o removemos e também alteramos esse nome de usuário para usuário a ser deixado de seguir Bom. Agora, depois de obter os dois usuários, passamos sua condição I para deixar de seguir seguidores de pontos, ponto inclui o ID do usuário atual, se não for verdade, e aqui adicionamos pontos de exclamação, e aqui retornamos a resposta com o código de status 400 e em Jason, 400 e em Jason, passamos a mensagem de objeto para usuário que não está disponível E depois disso, podemos remover ID de usuário atual da lista de seguidores do usuário para deixar de seguir Portanto, o usuário que deixa de seguir os seguidores do Dart é igual ao usuário deixar de seguir o método de filtro de pontos dos seguidores do Dart Aqui obtemos cada ID e aqui retornamos o ID da condição, string de dois pontos não é igual ao ID do usuário atual. Além disso, usuário atual, ponto seguinte é igual ao usuário atual, ponto seguinte, filtro de pontos. Aqui obtemos a função de seta ID, e a string ID two não é igual à ID do usuário. Agora podemos salvar os dois documentos, esperar que o usuário deixe de seguir ponto c e aguardar o usuário atual ponto C. E aqui retornamos o objeto Json do ponto E aqui retornamos de resposta com a propriedade de mensagem, o usuário deixou de seguir com propriedade de mensagem, E pronto. Agora podemos experimentar essa implementação. Então, um carteiro e aqui duplicamos essa API de acompanhamento. Altere o nome para deixar de seguir a API. Agora, vamos alterar o endpoint para cortar usuário, ID de barra, deixar de seguir e enviar a solicitação. Veja, aqui recebemos a mensagem de sucesso do usuário, deixou ser seguido com sucesso Então foi assim que implementamos seguidores, seguindo a API de solicitações e rejeições. Você pode ver que é muito simples. Precisamos entender a lógica antes de implementarmos novos recursos. 172. Seção 14 — introdução: Bem-vindo à 14ª seção do curso definitivo sem JS. Nesta seção, implementaremos recursos relacionados à postagem, como publicar uma nova imagem ou vídeo, exibir a postagem e excluir a postagem inteira. Além disso, adicionaremos o recurso de curtir e não gostar , escrever um novo comentário na postagem, responder aos comentários e muito mais. Essa é uma seção importante, então vamos começar esta seção. 173. Crie um modelo de postagem: Primeiro, vamos criar um esquema de postagem antes de criar APIs para Na pasta models, criamos um novo arquivo chamado post dot js. Agora vá para o arquivo do módulo do usuário, copie todo o código daqui e cole-o no arquivo de modelo de postagem. Agora, primeiro de tudo, vamos remover esse objeto de esquema e, como precisamos mudar algum nome aqui Curta esse esquema de usuário e renomeie-o por F para postar um esquema e Agora selecione o usuário e, para selecionar várias vezes, pressione Control plus D ou Command plus D e altere isso para postagem. Agora, precisamos adicionar apenas o objeto Schema. No documento postal, precisamos de algumas coisas. Em primeiro lugar, precisamos do usuário, que é o ID do usuário que postou a imagem ou o vídeo. Portanto, digite em Mongos dot schema dot Types dot Object ID, ref to user e required to true Em seguida, precisamos de mídia. Pode ser imagem ou vídeo. Além disso, pode ser um ou mais de um. Então, adicionamos aqui uma matriz e, nela, adicionamos objeto, nome da primeira propriedade ao objeto, tipo à string e exigimos que você seja verdadeiro. E outra propriedade, mídia, tipo para objeto, tipo para string. Num para a matriz, aqui adicionamos imagem, ou pode ser vídeo. Como exigimos que você desenhe. Por meio desse esquema, obtemos um entendimento adequado sobre mídia. Em seguida, os usuários podem adicionar uma legenda à postagem, digitar em string e dream to true para remover o espaço em branco, ou também podemos remover essa propriedade do stream Os usuários podem adicionar qualquer tipo de legenda. Além disso, não estamos tornando isso obrigatório porque o usuário pode não gostar de adicionar nenhuma legenda. Depois disso, adicionamos s, que é array, e também aqui está a referência do usuário. Então, copiamos esse tipo e a propriedade ref do campo do usuário e colamos aqui. Bom. Agora vamos adicionar alguns campos adicionais, como textos, que também são matriz, digite para string. Em seguida, também adicionamos localização, tipo à string e pronto. Atualmente, precisamos desses preenchimentos. Se, no futuro, precisarmos de outros preenchimentos , os adicionaremos nas próximas aulas Além disso, adicionaremos o preenchimento de comentários posteriormente nesta seção. Então não se preocupe com isso. Agora, deixe-me mostrar uma coisa no objeto do esquema. Anteriormente, lembre-se de que criamos para preencher nosso projeto. Mas no esquema Mongo, podemos adicionar isso automaticamente Logo após esse objeto de esquema, tivemos um segundo argumento no método de esquema, object, e aqui adicionamos a propriedade timestamp e a configuramos como draw Por essa propriedade, obteremos duas propriedades relacionadas ao horário, criadas e atualizadas. Esta é a hora atual em que o documento foi criado e, no ED atualizado, obteremos a data e a hora da última atualização. Não se preocupe, veremos isso quando criarmos uma nova postagem e faremos isso na próxima lição. 174. Crie um novo post: Vamos criar uma API para criar uma nova postagem. Na pasta routes, criamos um novo arquivo chamado post dot js. Aqui, precisamos de Router, Cost Express é igual a require Express. E depois disso, o custo do roteador é igual ao roteador de pontos expressos. No final, simplesmente modulamos as exportações de pontos iguais a Router. Agora vamos configurar esse roteador em nosso arquivo principal. Portanto, no arquivo index dot js, adicionamos cost post route igual a require. Aqui vamos para a pasta de rotas e nesse post. Agora, na parte inferior, app dot g, prefixo para slash API slash post e, no segundo argumento, adicione Salve esse arquivo e agora podemos adicionar rotas de postagem. Então, no arquivo post, adicionamos o Roteador, método que usaremos, certo. Usaremos o roteador dot post. Aqui, adicionamos menos para criar uma nova postagem. Além disso, aqui precisamos de utensílios ortomidais porque queremos que apenas os usuários façam login e criem uma nova postagem E depois disso, adicionamos função de retorno de chamada AC com solicitação e resposta Agora, o que queremos fazer nesta API é simplesmente criar um novo documento de postagem e armazenar essas imagens e vídeos em nosso servidor local. Então, para isso, precisamos configurar o Multer da mesma forma que fizemos anteriormente Então, abra o terminal, escreva e instale o Multer no vermelho de 1,4 0,5 traços LTso Oito, Enter. Bom, minimize esse terminal e vamos implementar o Multer. Então, no projeto anterior, adicionamos a configuração do Multer no mesmo arquivo de rota, mas isso parece pouco profissional Portanto, neste projeto, podemos configurar o Multer em um local diferente e depois importá-lo neste arquivo Está bem? Então, na pasta config, criamos um novo arquivo chamado MulteruLoad Sabemos que implementar o Multer é muito simples. Só precisamos definir o nome do arquivo e podemos definir o filtro do arquivo para evitar o upload desnecessário de arquivos. O custo, o pós-upload é igual ao Multer e dentro disso, precisamos passar o objeto de configuração Primeiro, passamos pelo armazenamento, que cuidará do caminho e do nome do arquivo. Então, na parte superior, criamos um const variável separado igual ao armazenamento em disco Mltert. E nisso, também passamos objetos com propriedades. Além disso, precisamos inserir Multer na parte superior. Portanto, Const Multer é igual a exigir de Multer. Bom. Agora, neste objeto, adicionamos a primeira propriedade, destino. E aqui temos solicitação, arquivo e CB tem parâmetros, função de erro e, dentro disso, simplesmente chamamos a função CB E na primeira posição, temos que passar o erro, que é nulo E no segundo argumento, passamos pelo caminho, destino dos nossos arquivos de postagem. Digamos que carrega uma postagem. Em seguida, temos o nome do arquivo, novamente, a função de seta com solicitação, arquivo e CB e, dentro disso, definiremos um nome de arquivo específico e exclusivo, mesmo que fizemos anteriormente Você também pode ver o código desse projeto. Está totalmente bem. Portanto, o timestamp Const é igual ao ponto da data agora Com isso, obtemos a hora atual. Depois disso, removemos alguns caracteres e espaços do nome do arquivo. Portanto, o custo do nome original é igual ao nome original do ponto do arquivo. Com isso, obteremos o nome original do arquivo enviado. Agora, no nome do arquivo, pode haver algum espaço, então é melhor substituirmos esse espaço pelo traço Isso tornará o URL do nome do arquivo amigável. Adicionamos o método de substituição de pontos. Aqui, primeiro adicionamos expressão regular a uma sintaxe de expressão regular, que é uma barra dupla entre elas, escrevemos a barra invertida a para espaço e mais para um ou mais No final da expressão regular, um G para sinalizador global, que garante que todas as correspondências na string sejam substituídas, não apenas a primeira. Agora, aqui passamos o traço em códigos únicos. Isso significa que todo o espaço será substituído por um traço. Agora, e se no nome do arquivo também obtivermos os caracteres especiais Precisamos removê-los também. Adicionamos outro método de substituição. Primeiro, o que vamos passar? Escreva uma expressão regular por dobro para nossa barra entre elas, escrevemos uma expressão regular para obter os caracteres espaciais Aqui adicionamos A a Z. Também de A a Z de zero a nove traços Agora queremos obter outros personagens que não façam parte desses personagens. Serão nossos personagens especiais. Então, para inverter isso, nós o colocamos entre colchetes e, após o primeiro colchete, adicionaremos Garret para inverso e, no final, também adicionaremos Agora, queremos substituir esses caracteres especiais por nada. Só queremos removê-los. Portanto, aderimos apenas códigos sem nada. Agora, no final, vamos misturar esse carimbo de data/hora e o nome do arquivo original CB primeiro, passamos null por erro e, segundo, escrevemos impostos Aqui, adicionamos colchetes de Cali, carimbo de data/hora, colchetes em dólares de Cali, nome original e pronto. Definimos o destino e também o nome do arquivo enviado. Agora podemos simplesmente passar essa variável de armazenamento aqui na função múltipla Agora, após o armazenamento, passamos o filtro no qual filtraremos os arquivos por suas extensões. Portanto, o filtro de arquivo de custo é igual à função de erro com três parâmetros, solicitação, arquivo e CB. Aqui, verificaremos se é válido ou não. Portanto, os tipos permitidos de Const são iguais a array, e aqui adicionamos os tipos de arquivo Agora, em nosso aplicativo de mídia social, usuário também pode fazer upload de imagens e vídeos. Adicionamos aqui a barra de imagem JPEG, outra imagem, PNG. Em seguida, imagem GIF e para vídeo, adicionamos vídeos MP quatro E também vídeo slash MOV. Você também pode adicionar outros tipos, se quiser. Agora podemos simplesmente colocar aqui a condição I do arquivo Mme. O tipo Mme é desses tipos, só então permitiremos, caso contrário, o rejeitaremos Se os tipos permitidos dot incluem arquivo dot Mme type, é verdade, então chamamos essa função CB e primeiro, passamos null para erro e depois passamos para aceitar Agora, se o tipo MM é outra coisa, então esses tipos, então aderimos à condição e chamamos aqui a função CB No erro, passamos um novo erro, e aqui passamos a mensagem de erro, tipo de arquivo inválido, somente JPEG, PNG, GIF, MP quatro e MOV podem rejeitar esse arquivo, aderimos à Agora podemos simplesmente passar esse filtro de arquivo no objeto Multi config Além disso, no multer, podemos especificar o tamanho do arquivo usando a propriedade Limits Para mídias sociais, podemos definir um limite de 15 MB. Se o usuário quiser enviar alguns vídeos , ele também pode fazer isso. Tamanho do arquivo do objeto de 15 a 1024 a 1024. Com isso, obtemos o valor dos bytes. Esse é o limite para cada arquivo. Se o usarmos para fazer upload de várias postagens , cada arquivo terá um limite máximo de 15 MB, não para o limite combinado, e pronto Aqui, nosso método de upload de postagem está pronto, para que possamos exportá-lo daqui. As exportações de pontos do módulo são iguais ao upload posterior. Salve esse arquivo e, em nosso arquivo de rotas, aqui após esse middleware, adicionamos post, upload, see auto input works dot porque queremos fazer upload de várias imagens na Agora, com a primeira posição, escrevemos o nome do preenchimento de entrada. Vamos passar aqui a mídia. No front-end, precisamos inserir o arquivo na entrada com a mídia de nome de preenchimento como esta. Depois disso, passaremos o número máximo de arquivos, digamos dez, e pronto. Agora podemos escrever a lógica da API. Em primeiro lugar, aqui verificamos ou não o arquivo enviado pelo usuário, porque se não houver mídia, não queremos salvar a postagem em nosso banco de dados. Solicito ou os arquivos não estão disponíveis, ou solicito que o tamanho dos pontos dos arquivos de pontos seja igual a zero. Se alguma dessas condições for verdadeira, retornaremos error, response, dot status, 400 para uma solicitação melhor. E no JSON, adicionamos objetos com propriedades confusas. É necessário pelo menos um arquivo de mídia. Agora, se a mídia estiver disponível, armazenaremos essa postagem em nossa coleção de postagens. Então, custo, nova postagem é igual a nova postagem. Ótima entrada automática funciona, e aqui precisamos passar pelos preenchimentos O primeiro é o usuário solicitar o ID de sublinhado do ponto do usuário. Em seguida, temos a legenda, que obteremos do corpo da solicitação Acima disso, desestruturamos o corpo da solicitação e aqui temos a legenda Além disso, o usuário pode adicionar texto e localização. Agora, em nossa postagem, adicionamos legenda à legenda, ou também podemos remover esse texto em texto e local em local Precisamos apenas de um campo que é mídia, que é matriz de objetos, e esse objeto tem duas propriedades, nome, que é o nome do arquivo e tipo de mídia, que é imagem ou vídeo. Com isso, quando exibimos essa mídia no front-end , podemos facilmente decidir qual tag devemos usar. Então, aqui precisamos criar essa matriz de objetos. É muito simples: a mídia Cast é igual a solicitar um mapa de pontos de arquivos de pontos. Aqui, obtemos o arquivo único no parâmetro, função de erro, e aqui queremos simplesmente reter um objeto Aqui nos colchetes Gully, escrevemos objeto, nome do arquivo, nome do arquivo com pontos e, para o tipo de mídia, aqui precisamos passar a condição Tipo de arquivo: ponto mímico, ponto começa com códigos duplos, imagem Se for verdade, definimos o tipo como imagem, coluna, caso contrário, configuramos como vídeo. Neste método, obteremos a matriz de mídia do objeto aqui em nosso novo post, configuramos a mídia como mídia. Depois disso, podemos simplesmente aguardar o novo ponto C. Em seguida, retornamos o status do ponto de resposta para 01 para criar novos dados Objeto Dot Json com propriedade de mensagem, postagem enviada com sucesso À medida que retornamos uma postagem para uma nova postagem, pronto. Vamos testar essa implementação. Salve esse arquivo e abra o carteiro. Aqui, criamos uma nova pasta chamada post e, dentro dela, adicionamos uma nova solicitação, carregamos uma nova postagem, alteramos o método SDDP para post e a URL para Coluna dupla para barra Hospedeiro local, coluna 3.000 barra API, corte Publicar e enviar Veja, aqui obtemos o token necessário, acessamos a API de login e simplesmente geramos um novo token. Copie isso em nossa nova API, vamos para o cabeçalho e adicionamos aqui um novo cabeçalho, autorização para beer space e aqui colamos nosso token. Agora envie a solicitação. Veja, aqui temos pelo menos um arquivo de mídia necessário. Agora, também vamos adicionar um arquivo de mídia com essa solicitação. Lembre-se de qual seção podemos enviar o arquivo, podemos enviar o arquivo a partir do corpo e dos dados do formulário. Aqui na chave, passamos mídia porque em nossa API, definimos mídia aqui no método multer Agora, aqui, selecionamos o arquivo. Adicione um novo arquivo da máquina local. Vamos enviar duas ou três imagens daqui e enviar a solicitação. Veja, aqui temos um erro, esse arquivo ou diretório AploadsPost não existe Basicamente, eles estão nos dizendo que precisamos criar o caminho da pasta. Em nosso servidor, criamos uma nova pasta chamada uploads. Certifique-se de usar somente letras minúsculas, pois elas diferenciam maiúsculas de minúsculas. Agora, nesta pasta de uploads, criamos outra pasta chamada Post Bom. Agora envie a solicitação. C, postagem enviada com sucesso. Aqui, obtemos um novo objeto de postagem com o usuário mídia também fica ótima com nome e tipo de mídia, curtidas e tags em uma matriz vazia e também recebemos carimbos de data/hora criados e enviados em Nós entendemos isso porque, em nosso esquema, adicionamos carimbos de data/hora É assim que criamos uma nova postagem. Agora, na próxima lição, receberemos uma postagem da coleção de postagens. 175. Obtendo postagens atuais do usuário: Agora é hora de fazer um pouco de exercício. Aqui, você precisa criar uma nova API para obter todas as postagens do usuário atualmente conectado Além disso, você precisa implementar o recurso de paginação, mesma forma que fizemos no projeto anterior, a API de produtos Certifique-se de exibir primeiro as cartas postadas e depois as mais antigas. Eu sei que você pode fazer isso, experimente e depois disso, qual é a solução. Agora vamos ver rapidamente a solução. Então, aqui em nossa rota de postagem, adicionamos outro ponto do roteador GDNDPoEndpoint, digamos, cortamos Aqui, também adicionamos função de retorno de chamada Osmidalware e ASN com solicitação e resposta a função de retorno de chamada Osmidalware e ASN com solicitação e resposta. Aqui, precisamos obter os parâmetros quadrados, o que nos dará página e limite O segundo objeto é igual à consulta de pontos de solicitação. E aqui temos a página e o limite. Além disso, podemos definir o valor padrão desta página e o limite. Então, página para um e limite para, digamos, dez. Se, no parâmetro de consulta, passarmos outra coisa , ela substituirá esses valores. Além disso, como sabemos, quando obtemos valores do parâmetro de consulta, esses valores são strings, então precisamos convertê-los em números inteiros Então, aqui no local do custo, escrevemos let, e depois disso, página é igual a analisar inteiro, página, e depois disso, limite é igual a analisar inteiro Agora podemos adicionar uma consulta para postagem. Então const, post é igual a await, post dot find. Aqui, passamos o usuário do objeto para solicitar o ID de sublinhado do ponto do usuário ponto E aqui adicionamos o método Skip. Essa página menos um no limite, e também somos o método limite, e passamos aqui esse limite e também criaremos essa linha E então, no final, simplesmente retornamos o ponto de resposta Json e passamos aqui esta postagem Agora vamos testar essa implementação. Salve esse arquivo e abra o carteiro. Aqui, duplicamos essa solicitação, alteramos seu nome para ser logado na postagem do usuário Altere também o método para obter um URL para a API post slash MI Post e enviar a solicitação Veja, aqui está a postagem. Atualmente, temos apenas uma postagem, e é por isso que chegamos aqui uma única postagem, então está funcionando. Além disso, para melhorar essa consulta, podemos fazer uma coisa. Passe a variável, que informa ao nosso front-end se a próxima página está disponível ou não. É muito simples. Então, aqui, depois de obtermos nossa postagem, criamos uma nova variável chamada próxima página igual a aqui, passamos a condição se o comprimento do ponto da postagem for igual ao limite atual, então é possível que haja uma próxima página para postagem, então passamos aqui verdadeiro se o tamanho da postagem atual for menor que o limite, caso contrário, passamos É uma lógica muito simples. Agora, na resposta Json, temos que passar objeto, post para post Página a página, limite, limite e como próxima página a ter a próxima página Salve as alterações e dê uma olhada. Envie a solicitação novamente. Veja, aqui temos uma postagem e, se rolarmos para baixo, a próxima página cai porque o limite atual de páginas não está cheio. Agora, na próxima lição, veremos como publicar em nossa página inicial de mídia social 176. Como obter o feed: Vamos criar uma API para obter postagens, que podemos exibir na tela inicial quando o usuário abre nosso aplicativo. Aqui, adicionamos outro ponto do roteador GAD e apontamos para a barra de seguidores porque, na página inicial, usuário verá a postagem que seguiu por ela ou Aqui também precisamos Osmidleware porque precisamos que os usuários atuais sigam a lista e também executem a função de retorno de chamada com solicitação Em primeiro lugar, nesta API, precisamos encontrar a seguinte lista de usuários atuais. Seconds user é igual a await user, dot fine by ID, e aqui passamos a requisição dot user dot underscore Aqui, queremos apenas o seguinte preenchimento, então selecione o ponto e passamos aqui os seguintes códigos. Aqui temos três linhas, o que significa que a entrada automática não funcionou. Deixe-me inserir esse modelo de usuário na parte superior. O custo do usuário é igual ao exigido. Aqui vamos para uma pasta b models e vamos para os usuários. Bom. Agora, para a consulta de postagem, podemos definir uma variável separada. Deixe que a consulta seja igual ao objeto. Dentro disso, passamos o usuário e aqui adicionamos novamente colchetes Agora podemos usar o operador Mongo Deb chamado $1 in, que é usado para verificar o valor do item na matriz Aqui, passamos ao usuário dot following, que é array. Basicamente, isso significa a publicação de usuários que estão disponíveis na matriz de pontos a seguir do usuário. Agora, a partir disso, podemos simplesmente obter post, então Const, post é igual a await, post, dot find, e aqui adicionamos nossa consulta Além disso, com isso, precisamos preencher o usuário que enviou essas postagens Então preencha o ponto e aqui passamos o usuário preenchido no segundo parâmetro, passamos quais campos queremos Portanto, ID da pontuação, nome de usuário e nome do perfil. Se tivermos uma foto de perfil , também podemos preenchê-la aqui Em seguida, adicionaremos um resumo. Aqui, passamos o objeto com a propriedade criada em e os filmamos em ordem decrescente, então passamos menos Com eles, recebemos uma nova postagem primeiro. Atualmente, não implementamos recurso de paginação nessa consulta, mas no mundo real, precisamos do recurso de paginação porque, no mundo real, pode haver centenas ou milhares de postagens Nesse momento, não podemos enviar todas as postagens em uma única solicitação. Isso tornará nosso servidor lento. Então, aqui precisamos do recurso de consulta infinita na parte superior, adicionar o objeto let é igual à consulta de ponto da solicitação, e aqui desestruturamos a página igual a um e o limite é igual a dez Esses são valores padrão. Além disso, precisamos convertê-los em números inteiros. Página é igual a analisar inteiro para página e limite é igual a analisar inteiro Agora, em nossa consulta, adicionamos o método Skip e passamos aqui a página menos o osso para E também adicionamos o método limit, e passamos aqui o limite, e também no final, adicionamos o método len. Agora, tudo está ótimo, mas há um pequeno problema nessa API. Deixe-me explicar isso com o exemplo. Suponha que aqui temos 20 postagens e nosso usuário envie uma solicitação de API para postagem. Nossa API envia essas dez primeiras postagens. Agora, quando o usuário está assistindo esta postagem, é possível que qualquer usuário seguinte possa adicionar uma nova postagem no banco de dados. Suponha que cinco usuários seguintes façam o upload de cinco novas postagens. Agora, quando o usuário atual quiser ver mais solicitações de postagem com o parâmetro de consulta da página dois. Nesse momento, nossa consulta pulará os primeiros dez dados do banco de dados porque a segunda página exibirá esta postagem Aqui podemos ver a duplicação de postagens porque essas cinco postagens foram adicionadas recentemente, e esse é o problema Agora, qual é a solução aqui? Podemos usar aqui a paginação baseada em cursor. Deixe-me explicar em palavras simples. paginação baseada no cursor significa que buscaremos a postagem com base na hora Por exemplo, aqui está o usuário h he está na página inicial e envia solicitações para as dez primeiras postagens Agora, a partir do back-end, enviaremos dez postagens e também enviaremos a última postagem criada no momento. Agora, quando Harley quiser mais dez postagens , ele enviará a última postagem criada no momento, que chamamos de cursor Agora você pode perguntar por que precisamos desse cursor. Usaremos esse cursor em nossa consulta. Encontre outras dez postagens cujo tempo de criação seja menor que o tempo do cursor. Com isso, não recebemos postagens duplicadas e nossa paginação funcionará Essa técnica é chamada de paginação baseada em cursor. Essa técnica é usada com muita frequência quando os dados que queremos são adicionados muito rapidamente, como as mídias sociais. Agora, vamos implementar isso em nossa consulta. Em primeiro lugar, retornaremos o cursor na resposta para que você a entenda corretamente. Aqui, após nossa consulta, adicionamos o custo que o próximo cursor é igual a. Aqui passamos a condição : o comprimento do ponto do poste é maior que zero. Se for verdade, retornamos a última postagem criada na Tate. Portanto, poste, colchete, comprimento do ponto do poste menos Com isso, obtemos a última postagem, ponto criado em, retornamos null Agora, no final, adicionamos ponto de resposta Json, aqui adicionamos objeto, post a post e próximo cursor ao próximo cursor Bom. Agora, vamos adicionar esse cursor em nossa consulta porque esse é o motivo pelo qual estamos enviando esse cursor. Então, quando enviarmos o próximo cursor para o front-end, nosso front-end enviará o próximo cursor na próxima solicitação de postagem. Portanto, no corpo ou no parâmetro de consulta, obtemos o cursor que envia o front-end. E agora simplesmente adicionamos esse cursor em nossa consulta. Aqui, a consulta criada em é igual aos colchetes Coli. Aqui passamos o dólar do operador LT, que é o menor que, e passamos aqui uma nova data. E aqui passamos o cursor. Agora, aqui precisamos lidar com a situação de queimadura. Primeira solicitação de postagem, não haverá cursor. Então, passamos aqui a condição se o cursor estiver disponível, só então adicionamos isso criado na consulta. Então, sem o cursor, nossa consulta ficará assim. E com o cursor, nossa consulta ficará assim, simples assim. Também podemos passar aqui a propriedade da próxima página. Portanto, copie essa linha da API anterior e cole-a em nossa API. E no final do objeto de resposta, adicionamos a página hasNext à página hass next Agora, vamos para essa implementação. Abra o Postman, duplique esta última consulta. Mude seu nome para receber seguidores, postar. Além disso, alteramos o URL para a barra de postagem da API após e enviamos a solicitação Veja, aqui não recebemos uma postagem porque nosso usuário atual fez o upload da postagem, não nenhum de seus seguidores. Então, aqui precisamos adicionar outro token de usuário. Acesse a API de login, faça login com outra conta de usuário. Qual é o nome de usuário e a senha de outro usuário? Deixe-me lembrar que sim, é h001 e a senha está definida como 128 Sim, pegue esse token, copie isso e, em nossa API atual no cabeçalho, substituímos esse token e enviamos a solicitação. Ainda assim, não recebemos correio. Deixe-me verificar quem segue quem. Oh, aqui, ninguém segue ninguém. Então, para fazer esse disco, copio esse ID de usuário atual, qual fizemos login, e o ID de edição nos seguidores do usuário anterior E também copie esse ID de usuário e faça isso na lista de seguidores do usuário atual e atualize-o. Agora, vamos enviar essa solicitação novamente. Veja aqui que obtemos a postagem, e também o próximo cursor, que é criado na data da última postagem e tem a próxima página a cair, isso significa que está funcionando corretamente. 177. Excluindo a postagem: Vamos criar uma API para excluir a postagem, então Router, dot delete, e aqui adicionamos barra, coluna, ID da postagem, que é o parâmetro de consulta Além disso, precisamos de middleware porque somente usuários autorizados podem excluir suas postagens E por último, adicionamos função de retorno de chamada ASN com solicitação e resposta Bom. Agora, em primeiro lugar, nesta função, obtemos const post ID igual a request dot PRMs, dot post Além disso, obtemos o custo do ID de usuário igual ao ID de sublinhado do ponto do usuário da solicitação Agora, aqui nesta API excluída, avisamos que somente o usuário que criou a postagem pode excluir a postagem. Então, para isso, precisamos encontrar o usuário desta postagem. O custo da postagem é igual ao ponto de espera da postagem Fine By ID. E aqui passamos o ID postal. Passamos que a condição I post não está disponível, depois retornamos a resposta com o código de status 404 e, em Jason, Object, propriedade da mensagem dois, postagem não encontrada Agora, e se encontrássemos uma postagem? Então, temos que verificar se o usuário de login atual é o autor desta postagem ou não? Portanto, se post dot user, que é o ID do objeto para sring, não for igual ao ID do usuário, retornaremos novamente a resposta com código de status 403 em caso de erro não autorizado no Jason, adicionaremos objeto com propriedade de mensagem não autorizada para adicionaremos objeto com propriedade de mensagem Agora, e se o usuário e o autor também forem iguais? Nesse caso, primeiro precisamos remover as imagens ou vídeos dessa postagem e, em seguida, podemos excluir o documento da postagem, certo? Então, aqui precisamos executar cada loop porque nossa mídia é uma matriz, suposto ponto de mídia de pontos para cada um. Aqui obtemos um único objeto de arquivo, função de seta, e aqui executamos nossa lógica para cada arquivo. Em primeiro lugar, precisamos do caminho do arquivo da imagem ou do vídeo, pois somente com isso podemos remover esse arquivo. É muito simples. Para path, precisamos do módulo path. Portanto, Const path é igual a require path, que é o módulo embutido do node Agora, na parte inferior, o caminho do arquivo de custo é igual à junção de pontos do caminho. Primeiro, adicionamos sublinhado Dname e também vírgula adicionamos o nome do ponto do arquivo, que é uma propriedade do nome Não tenho certeza sobre esse caminho. Então, vamos consultar o dot log desse caminho de arquivo. E na parte inferior, simplesmente retornamos o ponto de resposta json, objeto com propriedade medida, post, excluído com sucesso apenas para verificar esse caminho Salve esse arquivo e abra o carteiro. Aqui, duplicamos essa postagem de usuários logados porque, nessa API, temos o token do usuário que criou essa Aqui, alteramos o nome da API para excluir, a postagem, alterar o método para excluir e, no endpoint da API, alteramos isso para ID da postagem da API Vamos também copiar o ID da postagem da API anterior, enviar a solicitação e, aqui na parte inferior, obtemos o ID, copiamos e colamos em nosso endpoint da API E envie a solicitação. Veja, aqui temos a postagem excluída com sucesso. E se verificarmos nosso terminal, veja, aqui temos o caminho do arquivo. Ignore o primeiro caminho porque é sublinhado, Só para ver aqui, obtemos o nome do arquivo de barra das rotas de barra, que é o caminho da nossa pasta atual, mas não queremos adicionar Então, aqui entre o nome da data e o nome do arquivo, adicionamos códigos duplos, ponto, ponto final. Salve esse arquivo e vamos enviar a solicitação. No terminal de código VS, C, a rota é removida. Agora, só precisamos adicionar uma postagem com barra de uploads porque esse é o caminho da nossa Antes desse nome de arquivo, adicionamos uma barra de uploads, salvamos as alterações e enviamos a solicitação novamente Se verificarmos nosso terminal, veja aqui o caminho do arquivo. Então é assim que você pode experimentar o código usando o Console. Eu sempre faço isso quando estou confuso. Eu apenas comento a lógica do banco de dados e depois experimento a API. Dessa forma, não precisamos criar e remover dados do banco de dados. Então, temos aqui o caminho do arquivo. Agora só precisamos remover esse arquivo usando o módulo de arquivo. Já fizemos isso em nosso projeto anterior. Então, aqui, remova o console e adicione aqui, tente pegar o blog. E no cache, adicionamos o erro de ponto do console no Batis, passamos o erro ao excluir o arquivo, colchetes de dólar Coli, caminho do arquivo e também registramos esse Agora, no drilog, simplesmente aguardamos fs dot unlink e aqui passamos Para usar await, precisamos tornar essa função de retorno de chamada assíncrona e também importar Fs do módulo Portanto, Const Fs é igual a exigir promessas de Fs porque excluir o arquivo é uma operação assíncrona E depois de remover o arquivo do servidor, podemos remover o documento postal. Então aguarde o ponto de postagem Exclua um porque já buscamos a postagem na parte superior. E pronto. Salve os genes e envie a solicitação de exclusão novamente. Veja aqui que podemos postar, excluí-lo com sucesso. E se verificarmos nossos arquivos do Bend na pasta de postagem, as imagens também serão excluídas. 178. Curta e diferencia do post: Vamos criar uma API para e diferente da postagem. É muito simples. Se na matriz, a ID do usuário não estiver disponível, adicionaremos a ID do usuário, que significa que gostamos da postagem, e se a ID do usuário já estiver na matriz L, então, ao contrário da postagem, precisamos apenas remover a ID do usuário dessa matriz. Vamos adicionar a página de pontos do roteador. Aqui, adicionamos endpoint à coluna de barra, ID da postagem, barra L. Essa é a mesma API que usaremos e diferente Função de callback Comma ORT es com solicitação e resposta. Agora, primeiro, obtemos o ID da postagem igual ao ponto PRMs da solicitação, o ID do post do ponto e também obtemos o custo do ID do usuário igual ao ID de sublinhado do ponto do usuário da solicitação Agora, primeiro, encontramos a postagem, então Const, post é igual a await post dot Fine By ID e passar o ID da postagem Depois disso, verificamos a condição. Se a postagem não estiver disponível, retornamos a resposta com o código de status 404 e, no Jason, passamos o objeto com a propriedade de mensagem para postagem não encontrada Agora, se a postagem estiver disponível, verificamos que o usuário já gostou da postagem ou não. Portanto, Const já curtido é igual a postar curtidas de pontos, incluir pontos e aqui passamos o ID do usuário Agora, com base nisso, podemos passar condição, custo, atualização, postagem igual a oito, postar ponto fino por ID e atualizar. Primeiro, passamos o ID da postagem, e você pode me dizer o que passaremos no segundo argumento? Certo, passamos as atualizações. Então aqui passamos a condição. Eu já gostei é verdade, então temos que remover o like. Então, para isso, no objeto, usamos o operador Mongo Di Be, que é a atração do dólar para o objeto E aqui adicionamos curtidas ao ID do usuário. E se já curtido é falso, passamos aqui a e aqui no objeto, adicionamos outro método Mongoib, dollar at para definir como objeto, é para ID do usuário O motivo pelo qual adicionamos here at to set que ele só adicionará o ID do usuário se não estiver disponível, não duplicará o ID do usuário em s. Agora, no terceiro argumento, passamos o objeto com novo para verdadeiro Isso nos fornecerá dados atualizados. No final, simplesmente retornamos objeto Json do ponto de resposta com a propriedade message Aqui, verificamos as condições. Eu já gostei é verdade, então passamos por aqui, postamos diferente de qualquer outra coisa passamos postagem curtida e também podemos retornar curtidas para postagens atualizadas. Tamanho do ponto. Você pode retornar qualquer valor que quiser retornar da API. Agora vamos ajustar semanalmente essa API. Um carteiro, primeiro, precisamos criar uma nova postagem porque, na lição anterior, excluímos nossa única postagem Acesse a API de criação de postagem e envie a solicitação. Veja aqui que recebemos um erro de postagem, então temos que selecionar as imagens novamente. E envie a solicitação. Veja, aqui temos uma nova postagem, copie seu ID. Nós precisamos disso. Agora, em nossa pasta de postagem, criamos uma nova solicitação chamada L e diferente da postagem. Altere o método para página e o endpoint para SDDP, coluna dupla para nosso host local de barra, postagem de barra API de barra da coluna 3.000 e aqui colamos nosso ID de postagem e Também no cabeçalho, adicione a chave de autorização e o valor ao espaço do portador, copie o token da API de login e simplesmente cole-o em nossa API e envie a solicitação Veja, recebemos curtidas nas postagens e as curtidas contam até uma. Agora, envie a solicitação novamente. Veja, recebemos curtidas e curtidas contam até zero, então está funcionando. 179. Implementando o recurso de comentários: Atualmente, em quase todos os aplicativos de mídia social, há recursos para adicionar comentários na postagem. É a maneira de engajar as pessoas nessa postagem. Vamos também implementar recursos de comando para nossa postagem. Em primeiro lugar, a questão é: onde estamos no comando? Precisamos adicionar um comando no esquema. Então, no arquivo de pós-modelo, e aqui na parte inferior, adicione comandos, que é a matriz do objeto. Agora, em vez de escrever o esquema inteiro aqui, podemos criar um esquema separado para comandos e, em seguida, adicionar aqui uma referência Com isso, não nos confundimos. Portanto, antes desse esquema, adicionamos o esquema de comentário const igual ao novo esquema de pontos do Mongoose e, aqui no objeto, passamos o esquema e, aqui no objeto, passamos o passamos Em primeiro lugar, precisamos aqui de usuário para objeto, digitar no esquema de pontos do Mongos, tipo ponto, ID do objeto, e fazer referência ao usuário e também obrigatoriamente para Em seguida, precisamos de texto para objeto, tipo para string e também tornamos necessário True. Depois disso, precisamos criar em, que é o momento que esse comando específico foi criado. Então, digite até a data e use como padrão o ponto de data agora. Agora, como sabemos, nas mídias sociais, usuário pode responder ao comando de outros usuários. Devemos adicionar esses recursos de resposta em nosso Linky fi ou não? Vamos fazer isso também. Para respostas, adicionamos outras respostas preenchidas, que é matriz, e dentro dessa matriz, precisamos definir o esquema para Não se preocupe, é o mesmo que esse comando. Basta copiar essas três propriedades e, dentro dessa matriz, adicionar objetos e colá-los aqui. Certifique-se de adicioná-lo ao objeto, caso contrário, isso nos dará erro. Agora temos o esquema de comando. Podemos simplesmente adicioná-lo na parte inferior do esquema, veja, agora podemos ver facilmente o esquema da postagem sem nos confundir Agora vamos criar uma API para adicionar o novo comando à postagem. É muito simples. Então, aqui adicionamos os comandos dot post do roteador e apontamos para a coluna de barra, ID da postagem e barra Aqui, também precisamos do orthomiddal ware e da função de retorno de chamada ASN com solicitação e resposta Em primeiro lugar, obtemos o custo do ID do post igual ao ponto da solicitação PRMs do ponto ID do post Além disso, obtemos o custo do ID do usuário igual ao ID de sublinhado do ponto do usuário do ponto da solicitação Então, também obtemos que o texto Const é igual ao texto do ponto do corpo do ponto da solicitação Antes de fazer qualquer coisa, primeiro verificamos se o texto não está disponível, depois simplesmente retornamos a resposta com o status 400 e, em Jason, passamos o objeto com a propriedade da mensagem para comentar, o texto é obrigatório Agora, se tivermos texto de comando , precisamos simplesmente criar um novo comando. Portanto, o custo, o novo comentário é igual ao objeto e, por dentro, temos que passar o usuário para o ID do usuário e o texto para o texto. Portanto, não precisamos passar a data de criação porque já passamos a data atual como valor padrão em nosso esquema Agora, aqui precisamos colocar esse novo objeto de comentário na matriz de comentários do post. Você pode me dizer qual método usaremos? Sim, podemos usar aqui, tudo bem por ID e atualização. O custo da postagem é igual a aguardar, publicar, pontuar, multar por ID e atualizar Na primeira posição, adicionamos o ID da postagem. Na segunda posição, precisamos passar o que queremos atualizar. Agora, para pressionar o novo comando, usamos o método dollar push Aqui, adicionamos colchetes de Cully e nesses comandos, o que queremos inserir neste novo E no terceiro argumento, passamos objeto com novo para verdadeiro. Agora, você pode me dizer por que não usamos aqui para definir o método? Certo, porque at to set não permite valores duplicados. Mas aqui, o comando pode ser duplicado. Um usuário pode atribuir comandos. Não podemos negar isso, e é isso. No final, retornamos a resposta com o código de status 201. Novos dados e retornamos objeto JSN com a propriedade de mensagem para comentário adicionado com sucesso E como podemos enviar comentários para postar comandos de pontos em um pacote quadrado, publique comandos de ponto com comprimento de ponto menos um, que é o comando mais recente que adicionamos e executamos Agora, vamos fazer essa implementação. Abra o Postman e duplique essa API, altere o nome. Para criar um novo comando. Altere o método para postar e também aponte para os comandos post ID e envie a solicitação. Veja aqui que recebemos um erro porque não passamos texto. No corpo, vamos para raw e aqui adicionamos objeto com propriedade de texto. O que devo comentar? Sim, este é um ótimo produto. Aqui você pode adicionar qualquer comando. Agora envie a solicitação. Veja aqui obtemos o comando, editamos com sucesso e aqui também obtemos o comando de letras. Agora, na próxima lição, criaremos uma API para adicionar resposta a esse comando. 180. Adicionando resposta aos comentários: Agora vamos criar uma API para adicionar resposta a um comando específico. É uma API muito semelhante à anterior, então roteador dot post, barra frontal, ID da postagem da coluna, comandos de barra, barra aqui também precisamos do ID do comentário porque em qual comando o usuário deseja adicionar a resposta, precisamos descobrir isso E depois disso, o slash responde. Role para cima e copie toda essa API com OT e cole-a em nossa API. Bom. Agora precisamos mudar pequenas coisas aqui. Em primeiro lugar, nos parâmetros, também estamos recebendo o ID do comentário Vamos desestruturar os parâmetros de ponto da solicitação e aqui obtemos o ID do comando Agora, no local do novo comentário, chamamos isso de nova resposta e, na parte inferior, alteraremos o método para corrigir uma e atualizar. À medida que usamos fine one e update, precisamos passar o objeto de condição dela no primeiro argumento. Dentro disso, passamos o ID do sublinhado para o ID do post. E também passamos sua condição, códigos duplos, pontos de comentários, ID de sublinhado para ID de comentário Certifique-se de escrever o nome correto da propriedade, pois faz distinção entre maiúsculas e minúsculas. Além disso, você pode perguntar se nossos comentários são uma matriz, e aqui estamos escrevendo ID de sublinhado dos comentários. Isso funcionará A resposta é sim, funcionará porque no Mongo Di B, usamos essa notação de ponto, que nos permite pesquisar na matriz de comentários e encontrar o primeiro objeto em que o ID do sublinhado corresponde ao ID Agora, no método push, no local do comando, adicionamos comentários, pontos, respostas Aqui podemos usar comentários dot dollar dot rep. Agora você pode perguntar: qual é a diferença entre comentários com pontos de resposta e comentários em pontos por dólar por RPS Portanto, o operador commens dollar é otimizado para direcionar um elemento específico dentro de uma matriz outro lado, comentários, pontos e respostas são para o campo geral Deixe-me explicar com um exemplo. Suponha que essa postagem tenha dez comentários e queiramos adicionar uma resposta a esse segundo comentário. Agora, se usarmos as respostas de pontos de comentários aqui, ele adicionará uma resposta a todos os comandos Não queremos que, por outro lado, se você usar aqui comments dot dollar dot replies, ele adicione resposta apenas ao segundo comando, e é isso que queremos Lembre-se sempre de que, se você quiser atualizar um item específico de matrizes aninhadas, precisará adicionar o operador dólar entre elas Curtir comentários, pontos em dólares, respostas. Esse dólar é chamado de operador posicional. Resumindo, no Mongo DB, notação de pontos funciona para pesquisar e excluir elementos, e o operador posicional é necessário para Agora, aqui em nosso método de atualização, alteramos esse novo comentário para uma nova resposta. E também no final, alteramos a mensagem para responder, editá-la com sucesso e simplesmente enviamos essa nova resposta em nossa resposta. Então, acima deles, adicionamos o comentário de custo igual aos comandos post dot, que é a matriz. Agora, para obter o comando específico, precisamos encontrar seu índice. Então, em vez disso, no Mongoose, temos outro método chamado dot ID Isso nos ajudará a encontrar um subdocumento pelo campo de ID de sublinhado Só precisamos passar aqui o ID do comentário, mas certifique-se de adicionar o ID do ponto do comentário, que é o método das mangas Caso contrário, no futuro, você ficará confuso ao procurar esse código. Na resposta no local do comando, adicionamos resposta e aqui passamos comando, respostas por pontos, colchetes, comando, respostas por pontos, comprimento do ponto comprimento do ponto Com isso, obtemos a resposta mais recente que acabamos de adicionar. Salve as alterações e vamos testar essa API de volta ao Postman, e aqui duplicamos essa API de comentários , alterando seu nome para adicionar uma nova resposta Agora, no endpoint, após os comandos, precisamos adicionar o ID do comentário. Vamos copiar o ID do comentário da API anterior e colá-lo em nossa API. Após o ID do comentário, adicionamos respostas em barra. Agora, vamos também alterar o texto da resposta para muito obrigado e enviar a solicitação. Veja aqui que recebemos a mensagem de sucesso e também a última resposta. Então você pode ver como é simples. 181. Exercício - Removendo comentário específico: Agora é hora de fazer um pouco de exercício. Neste exercício, você precisa criar uma nova API para excluir o comando específico da postagem Portanto, nosso URL da API terá a seguinte aparência : barra, API , ID da postagem, comandos de barra, ID do comando de barra, e você precisará remover esse comando com esse ID e você precisará remover esse comando com esse Além disso, certifique-se de que somente o usuário que fez o upload dessa postagem ou o usuário que adicionou esse comando possa remover esse comando. Nem todos os usuários podem remover comandos. É muito simples. Eu sei que você pode fazer isso, experimente e depois veja a solução. Espero que você resolva esse exercício e, mesmo que esteja preso em algum lugar, não se preocupe, pelo menos tente. Isso é o que mais importa. Agora vamos ver rapidamente a solução para esse exercício. Aqui, simplesmente duplicamos essa última API porque ela é muito semelhante Em primeiro lugar, alteramos o método para excluir. Além disso, do endpoint, removemos as respostas em barra porque não precisamos delas Agora, na função, primeiro, não precisamos desse texto. Além disso, não precisamos dessa condição e também não precisamos dessa nova variável de resposta. No método fino e de atualização, precisamos adicionar nossa condição. Então, o primeiro é o ID de sublinhado para o ID da postagem e, agora, para encontrar o comando, precisamos garantir que o usuário de login atual seja o autor da postagem ou o autor do comando Então, aqui usamos dólar ou operador, e é uma matriz de condições. Objeto, objeto. Aqui, nossa primeira condição deve escrever ou a segunda condição deve escrever. Em primeiro lugar, verificamos que usuário atual é o autor da postagem ou não. Aqui, adicionamos a coluna do usuário, o ID do usuário e, para a segunda condição, em outro objeto, passamos códigos, sublinhado do ponto de comunicação para o ID do comentário, códigos, comentários, ID do usuário dois usuários O que queremos fazer se alguma dessas duas condições for verdadeira. Queremos extrair esse comando da matriz de comandos. Aqui, no local de push, usamos o operador pull e de qual campo queremos puxar. Sim, queremos extrair dos comandos e aqui passamos a condição, qual item queremos extrair. Então, no objeto, passamos o ID válido para o ID do comentário. Agora não precisamos dessa variável de comentário e, na resposta, simplesmente retornamos mensagem, comentário, excluído com sucesso. Além disso, retornamos comandos para postar comandos de pontos e pronto Aqui, o que eu acho que devemos verificar foi encontrado ou não. Caso contrário, receberemos essa mensagem diretamente sem fazer nenhuma exclusão. Portanto, antes dessa resposta, acrescentamos que a postagem não está disponível, depois retornamos a resposta com o código de status 403 e, no Jason, passamos mensagem para não autorizada ou publicamos comentário Será útil. Salve as alterações e vamos testar essa implementação. De volta ao Postman E aqui, vamos duplicar esse teste da API de resposta, alterar o nome para excluir um comando ou método específico para E no endpoint, só precisamos remover essas respostas e enviar a solicitação C comentou com sucesso e, se enviarmos novamente a mesma solicitação, veja, aqui obtemos um erro de não encontrado, então está funcionando Como você pode ver, criar uma API não é difícil. Se a lógica estiver clara para você, você poderá criar qualquer tipo de API. Agora, existem muitas outras APIs para postagens e comentários. Não estamos criando todos eles porque, como você pode ver, é repetitivo e, se eu mostrar todas as APIs, uma por uma , isso também o entediará Você pode definir APIs de acordo com as necessidades do seu projeto. Depende totalmente de você. 182. Manipulação de erros: Agora, atualmente em nosso projeto, não adicionamos tratamento de erros. Então eu abro aqui nosso projeto anterior, Card Wish, e a partir do arquivo JS de ponto de índice, simplesmente copiamos essa variável do logger e também os dois manipuladores de erros e em nossa pasta InkifIpject in Config, criamos um novo arquivo chamado logger Agora, neste arquivo, precisamos desse objeto Winston. Então, no terminal, escrevemos o NPM, instalamos o Winston, na taxa 3,17 0,0, e também precisamos do Winston MongoDB, na taxa 6,0 0,0, oito Bom. Agora, no topo, custo, Winston é igual a exigir Além disso, precisamos adicionar require Winston Mongo DB para fazer login no Agora, em nosso registrador, precisamos alterar essa string do banco de dados para processar ponto nw ponto ponto E, no final, simplesmente modulamos as exportações de pontos iguais ao logger Podemos usar esse registrador em qualquer um dos nossos arquivos. Portanto, no arquivo index dogs na parte superior, adicionamos Const logger igual a require Vamos para a pasta Config e nesse registrador. Agora, do projeto anterior, também copiamos esse método de cache do Mongoose connect e simplesmente o substituímos pelo nosso método de cache Então, do projeto Cardwih, copiamos esse middleware de erro personalizado para lidar com erros na solicitação de API e o colamos em nosso projeto Linky fi após Além disso, aqui podemos consolar o erro de log de pontos para simplificar. Agora você pode perguntar: não precisamos adicionar essas funções para lidar com exceções não válidas e rejeições de UnhandlePmise Sim, aqui, não precisamos adicioná-los em nosso arquivo de cães de índice porque quando importamos o logger do arquivo de registradores, esses dois métodos serão executados automaticamente porque estão configurados globalmente nesse E é por isso que temos aqui um código limpo. Então você pode ver como é simples. Além disso, eu sempre adiciono esse arquivo de registro no meu repositório Github. Então, sempre que eu precisar desse código de tratamento de erros, posso obtê-lo diretamente. Mas para entender o que está dentro do código. Se você sabe disso, pode usar qualquer código e torná-lo seu. Isso é tudo para esta seção. Na próxima seção, aprenderemos recursos muito interessantes em tempo real. Nos vemos na próxima seção. 183. Introdução da seção 15: Bem-vindo à 15ª seção do curso definitivo sem JS. Nesta seção, aprenderemos sobre a comunicação em tempo real do back-end ao front-end e também do front-end ao back-end. Isso vai ser divertido porque também experimentaremos nossa implementação com um front-end como esse. Imagine que são dois usuários de computadores diferentes e estão conversando entre si em nosso aplicativo inkifi Veja como funciona sem problemas. Nossos dois usuários estão recebendo mensagens em tempo real, e também quando um usuário está digitando uma mensagem, outro usuário recebe o indicador de digitação, o que torna a experiência do usuário uma experiência única para conversar Além disso, implementaremos o bate-papo em grupo e, com isso, mais de um usuário poderá conversar em grupos. Portanto, implementaremos esses recursos em nosso back-end e os experimentaremos com o front-end. Além disso, uma coisa que quero esclarecer é que aqui não vamos criar um front-end do zero. É só para degustar, para que você possa entender mais sobre esses recursos em tempo real Estou muito entusiasmado com esta seção e espero que você também esteja. Então, vamos começar. 184. Criando um chat: modelo de mensagem: Para criar a API Jet, primeiro precisamos criar uma coleção ou modelo do Jet, você quiser chamá-lo. Então, aqui na nossa pasta de modelos, criamos um novo arquivo chamado chats dot js Agora, do modelo de usuário anterior, copiamos o código inteiro e o colamos aqui. Bom. Agora, primeiro, alteramos o nome da variável para esquema de bate-papo Além disso, vamos remover tudo do objeto do esquema e também alterar esse usuário para conversar e pronto Agora, vamos definir o esquema do chat. Mas antes disso, deixe-me esclarecer o que é chat aqui. O chapéu é como uma sala na qual dois ou mais usuários podem se comunicar entre si. Em palavras simples, no Instagram, você viu no lado esquerdo, todos os bate-papos são encurtados pela última mensagem Esses preenchimentos são chat. Podem ser grupos ou conversas individuais. O que precisamos para esses bate-papos. Atualmente, estamos implementando apenas o bate-papo individual, então não se preocupe com os recursos de bate-papo em grupo. Pense em um a um. Portanto, para um bate-papo individual, podemos criar um campo central e também podemos criar um campo receptor. E para ambos, adicionamos tipo aos tipos de pontos do esquema de pontos do Mongos, ID do objeto de ponto e à referência ao usuário Então, suponha que o usuário A envie a mensagem para o usuário B. Adicionamos o usuário A como remetente e o usuário B como destinatário Agora, aqui está um grande problema. Suponha que agora o usuário B esteja enviando uma mensagem para o usuário A. Então, o remetente será o usuário B e o destinatário será o usuário A. Isso criará um novo documento de bate-papo, e esses dois usuários não terão o mesmo bate-papo por falarem um com o outro Agora, qual é a solução aqui? É muito simples. Portanto, ao definir remetente e destinatário separadamente, podemos adicionar um único campo para eles. Como aqui, tivemos participantes, que é a matriz e nela armazenaremos o ID de usuário dos participantes. Digite no esquema de pontos do Mongos, tipos de pontos, ID do objeto de ponto e referência ao usuário Se o usuário A enviar uma mensagem para o usuário B , teremos o usuário A e o usuário B, ambos IDs na matriz de participantes, e se o usuário B enviar mensagem para o usuário A , os dois IDs também estarão disponíveis nos participantes. Dessa forma, obteremos um único bate-papo para o usuário A enviar mensagem para o usuário B ou o usuário B enviar mensagem para o usuário A. Esse preenchimento de participantes é usado para buscar jatos para um usuário específico Agora, depois dos participantes, queremos data e hora. Para isso, podemos simplesmente ativar timestamps como verdadeiros e pronto Agora você pode perguntar o que acontece com as mensagens? Para mensagens, criaremos outro modelo. Então copie esse esquema e, na pasta models, criamos um novo arquivo chamado messages dot js e colamos aqui esse esquema Agora, primeiro, alteramos o esquema de bate-papo para esquema de mensagem e o modelo de bate-papo para Bom. Agora vamos definir o esquema para uma única mensagem Então, para a mensagem, primeiro, precisamos de seu ID de bate-papo. Então, digite no esquema de pontos do Mongos, tipos de pontos, ID do objeto de ponto e faça referência à coleção de bate-papo, que acabamos Agora, depois disso, adicionamos o remetente que enviou essa mensagem e seu tipo de ID do objeto e referência ao usuário Assim, podemos simplesmente recortá-lo dos participantes e colá-lo para o remetente Agora não precisamos desses participantes. Depois disso, temos o tipo de conteúdo como string e obrigatório como verdadeiro. Esse é o conteúdo da mensagem ou o texto da mensagem que os usuários desejam enviar. Agora, depois do conteúdo, o que adicionamos, sim, precisamos do status dessa mensagem. Digite para string um to array e aqui definimos o conjunto de valores como enviar, entregar e ler. E, por padrão, definimos o status para enviar. No futuro, atualizaremos o status quando nossa mensagem for entregue ou lida por outros usuários, e pronto. Além disso, para mensagens, adicionamos carimbos de data/hora ao verdadeiro esquecimento da Agora você pode se perguntar por que não adicionamos essas mensagens no modelo de bate-papo. Podemos fazer mensagens para ordenar e definir todas as mensagens com seu bate-papo relacionado. Sim, podemos fazer isso, mas um dos motivos pelos quais não adicionamos mensagens no modelo de bate-papo é que, no modelo de mensagens vamos adicionar, atualizar e excluir várias vezes. Adicionamos mensagens no modelo de bate-papo e, em seguida, precisamos lidar com dados aninhados muito profundos, o que pode nos confundir Além disso, se adicionarmos uma matriz de mensagens no modelo de bate-papo , quando abrirmos o bate-papo, teremos que buscar todas as mensagens do back-end, seja, muito mais dados em uma única solicitação Então, ao separar as mensagens, só podemos enviar as últimas dez ou 15 mensagens e, se o usuário quiser ver mensagens de bate-papo mais antigas, só então buscaremos outras mensagens usando a técnica de paginação É por isso que separamos as mensagens do modelo de bate-papo. Aqui no modelo de bate-papo, também podemos adicionar mais um preenchimento. Última mensagem, que é digitada para o esquema de pontos Mongos, tipos de pontos dot objectID e ref para Com isso, podemos exibir a última mensagem com chat e não precisamos encontrá-la na coleção de mensagens. Agora, na próxima lição, criaremos uma API para obter a lista de jatos para o usuário de login. 185. Como obter chats para o usuário: Vamos criar uma API para obter a lista de jatos para o usuário conectado Aqui na pasta routes, criamos um novo arquivo chamado jets dot js Agora, primeiro, criamos o roteador, então o roteador Cs é igual a require Express. Essa expressão retornará Express Object, e aqui simplesmente obtemos dot Router. Este é o código de linha única para essas duas linhas que estamos usando até agora. No final, simplesmente exportamos isso com exportações de módulos iguais a Router. Agora, o que faremos é adicionar essas rotas no arquivo de cães de índice, pressionar Control mais P e ir para o arquivo de cães de índice. Aqui, adicionamos o custo das rotas de jato iguais ao necessário, vamos para a pasta de rotas e, dentro dela, jatos na parte inferior, ponto do aplicativo U, aqui adicionamos prefixo API slash jets no segundo parâmetro, adicionamos rotas de jato e salvamos isso Agora podemos definir nossas APIs. Primeiro, queremos descobrir a lista de jatos para o usuário de login atual, ponto de extremidade do roteador dot get para a barra direta, e aqui precisamos do OS Middleware porque somente usuários logados podem ver bate-papos No final, adicionamos a função de retorno de chamada Asyn com solicitação e resposta Agora, dentro dessa função de retorno de chamada, primeiro, obtemos o custo do ID do usuário igual ao ID do usuário do ponto da solicitação Em seguida, podemos encontrar o bate-papo. O custo dos bate-papos é igual ao bate-papo em espera. Veja, a entrada automática funciona com pontos Find e aqui passamos nossa condição nos participantes do objeto para o ID do usuário. Aqui também podemos usar operadores Mongo Di Be, mas isso também funcionará Se não funcionar, nós o mudaremos. Qual é o problema? Agora, no front-end, queremos mostrar algo assim. Primeiro de tudo, usuário que recebe ou envia mensagens. Também a última mensagem, quem enviou a última mensagem e em que horário eles enviaram. Aqui, precisamos preencher os dados do usuário dos participantes. Ponto preenchido. No primeiro argumento, passamos o nome do preenchimento, que são os participantes, e o segundo argumento é o nome do preenchimento, digamos, ID do sublinhado e nome do usuário Agora também precisamos das informações sobre as últimas mensagens. Novamente, preencha o que escrevemos primeiro. Escreva, última mensagem, nome de preenchimento e, em seguida, segundo, quais preenchimentos precisamos da última mensagem Primeiro, precisamos do remetente que enviou esta mensagem. próximo conteúdo, o texto da mensagem e, em seguida, ele é criado em. Aqui, se você está confuso sobre o nome de Phil , também pode assistir Schema Agora aqui, um pequeno desafio para nós. Como podemos ver, estamos recebendo o remetente desta última mensagem, mas também é o ID, não o nome do usuário Precisamos do nome de usuário desse remetente. Então, aqui podemos fazer assim. Depois desse método de preenchimento, adicionamos outro método de preenchimento. Primeiro, adicionamos ponto remetente da última mensagem e o segundo argumento, adicionamos o nome de preenchimento, que é nome de usuário Agora eu acho que isso parece um pouco confuso. Portanto, há outra maneira de escrever o método de preenchimento aninhado. Deixe-me te mostrar. Até agora, no método populate, passamos dois argumentos No primeiro argumento, passamos o nome do campo que queremos preencher e, no segundo, passamos as propriedades que queremos obter da relação Essa é a primeira maneira. Para o método populatet aninhado, podemos passar aqui o método podemos passar aqui Agora, em vez de passar aqui argumentos, podemos passar o objeto. Primeiro, neste objeto, passamos a propriedade path. Esse caminho é um nome de campo que queremos preencher, que é a última mensagem E outra propriedade é selecionada. Aqui, selecionamos quais dados queremos obter da relação. Digamos que o conteúdo seja centralizado e criado em. Agora, aqui queremos preencher novamente os dados do remetente. Depois de selecionar, passamos outra propriedade que é preenchida e aqui passamos o objeto com mesmo caminho de duas propriedades e selecionamos Caminho para o que adicionamos aqui, escreva para o remetente. Não precisamos escrever aqui a última mensagem dot Sender porque já estamos no método de preenchimento da última mensagem e aqui passamos select para o nome do usuário Aqui, se você quiser ir mais fundo, também podemos passar outra propriedade de preenchimento, por enquanto não precisamos dela, então vamos remover isso Agora, aqui, esses dois métodos de preenchimento e esse único método de preenchimento aninhado funcionam Gosto dessa abordagem aninhada porque é clara e não confusa Se você gosta do primeiro, então vá em frente. Não se preocupe, depende totalmente de você. Agora, depois de preencher, queremos mostrar os jatos na ordem inversa da última mensagem Mas aqui, como podemos classificar os jatos? É muito simples. Veja quando alguém envia uma mensagem, como sabemos, atualizaremos esse jato, propriedade da última mensagem e, quando atualizarmos essa propriedade, nossos jatos atualizados na propriedade serão atualizados Portanto, podemos resumir isso atualizado na propriedade. Então, dot short, e em object, passamos o valor de updated at para menos um e, no final, retornamos a resposta dot json, Object with chats para esses bate-papos e pronto Atualmente, obtemos a lista de bate-papo para o usuário de login. Agora, em seguida, quando o usuário abre um bate-papo específico, precisamos mostrar a ele as mensagens desse bate-papo. Na próxima lição, criaremos uma API para isso. 186. Recebendo mensagens de chat específico: Vamos receber mensagens de um bate-papo específico. Então, ponto externo GT. Primeiro, precisamos do ID do bate-papo, então coluna de barra, ID do bate-papo, mensagens de barra Além disso, precisamos aqui de um middleware e, finalmente, está na função de retorno de chamada com solicitação Agora, dentro desse retorno de chamada, obtemos o custo do ID do chat igual a e desestruturamos os PAMs de pontos de solicitação Depois disso, as mensagens de custo são iguais a await message dot find Simplesmente aqui, passamos o ID de bate-papo do objeto para o ID do bate-papo. Deixe-me verificar se é chat ou ID do chat. Sim, é ID de bate-papo. Quando eu não estava aprendendo Jazz, isso acontece comigo. Escrevo um nome de preenchimento errado na consulta e passo quase um dia encontrando erros e, por fim, verifico o nome do preenchimento. Portanto, certifique-se de que isso não aconteça com você. Agora, aqui queremos preencher esses dados. Então, atreva-se a povoar E aqui queremos preencher o remetente, e o que você deseja para obter o ID de sublinhado e o nome de usuário Agora, depois disso, queremos receber as mensagens na ordem inversa, porque é assim que exibimos as mensagens no front-end. Então, classifique aqui no objeto, passamos created at para yes, menos um Agora, essa consulta retornará todas as mensagens desse ID de bate-papo. Mas no mundo real, precisamos apenas últimas dez a 20 mensagens porque ninguém as verá desde o início. Se alguém quiser ver as mensagens anteriores, podemos buscá-las posteriormente como paginação Então, para paginação, escrevemos aqui, deixe que os colchetes Ci, limite de vírgula da página, sejam iguais a desestruturar aqui, solicite a consulta Além disso, passamos aqui esse valor padrão se o front-end não passar esses dados. Então, página para um e limite para, digamos, dez. Depois disso, precisamos convertê-los em números inteiros. Portanto, página é igual a passar um inteiro e passar aqui a página. Duplique essa linha com sift mais Alt mais seta para baixo ou Sift mais Option mais E aqui mudamos esta página para limitar, e também aqui para limitar. Em nossa consulta, simplesmente adicionamos o método Skip e, dentro dele, página menos um em limite, e também adicionamos o método limit e passamos aqui E também, no final, adicionamos o método len. Criamos muitas APIs com paginação, certo? Agora também podemos adicionar aqui C tem mensagens anteriores, é igual à condição aqui que passamos, comprimento do ponto das mensagens é igual ao limite. Se for verdadeiro, retorne verdadeiro, caso contrário, retornaremos falso. Agora, no final, simplesmente retornamos JSUNobject de ponto de resposta para mensagens, tem mensagens anteriores, para mensagens anteriores, página por página e limite para limite E é isso. Por enquanto, não temos bate-papos e mensagens, então experimentaremos essas APIs depois de criarmos o bate-papo e Na próxima lição, criaremos o EPI de mensagem de envio 187. API para enviar mensagens: Agora vamos criar uma API para enviar mensagens. Então, aqui adicionamos o dot post do roteador para o endpoint, adicionamos à nossa coluna de barra jet ID, na qual jato queremos enviar mensagem, mensagem barra ou mensagens, você quiser chamá-lo Além disso, adicionamos o Osmitalware e função de retorno de chamada acing com solicitação e resposta Em primeiro lugar, obteremos o ID do usuário da solicitação dot user dot underscore ID À medida que obtemos o custo, o ID de bate-papo do Calibakets é igual à solicitação de pontos PRMs, o que Precisamos do conteúdo da mensagem que recebemos do corpo. O custo do conteúdo do Calibacket é igual ao corpo do ponto solicitado. Agora, antes de fazer qualquer coisa, vamos verificar aqui as condições. Se o conteúdo não estiver disponível, retornamos a resposta com código Stata 400 e, no método JSON, retornamos o objeto com a mensagem para o conteúdo, ou podemos dizer que mensagem, texto é obrigatório Agora, o que queremos fazer dentro dessa API simplesmente armazenar a mensagem no banco de dados. É isso mesmo. Aqui podemos calcular o custo, uma nova mensagem é igual a uma nova mensagem. Aqui no objeto, passamos o jet ID para o ID do chat, remetente para quem escreve, o ID do usuário e, em seguida, adicionamos conteúdo ao conteúdo Depois disso, aguardamos a nova mensagem ponto c. E, por fim, simplesmente retornamos a resposta com o Código de Status 201 e, em Jason, passamos Object, nova mensagem para nova mensagem Agora, antes de experimentarmos essa API, você pode perguntar: não criamos uma API para criar bate-papo. Então, como podemos passar o Jet ID? Sua pergunta está certa. Precisamos criar a Jet API antes de salvar a mensagem. Aqui, criamos uma nova API, router dot post, point to slash Create chat Aqui, precisamos de middleware e também de uma função de retorno de chamada com solicitação Em primeiro lugar, obtemos o custo do ID do usuário igual ao ID de sublinhado do ponto do usuário do ponto da solicitação Também precisamos do ID do receptor, quem é o receptor ou outro usuário deste jato. ID do receptor de custo é igual ao ID do receptor do ponto, corpo do ponto da solicitação. Como estamos obtendo esse ID de receptor do corpo do ponto de solicitação, é uma boa prática validar Portanto, se o ID do destinatário não estiver disponível, retornamos a resposta com Código de Status 400 e, em Jason, retornamos o objeto com a mensagem necessária para o receptor Agora, antes de criarmos um novo bate-papo, é melhor descobrir que esses dois usuários já têm um bate-papo existente ou não. Então, deixe o chat ser igual a await chat dot Fine one. Aqui no objeto, passamos os participantes para o objeto e adicionamos dólar ou à matriz, ID do usuário, ID do receptor da vírgula Agora, essa consulta significa um jato em cujos participantes existem tanto o ID do usuário quanto o ID do receptor. Agora, e se for um jato coletivo? Então, pode ser possível que haja vários jatos nos quais esses dois IDs estejam disponíveis Aqui, precisamos garantir que somente o ID do usuário e o ID do destinatário estejam disponíveis. Para isso, podemos usar aqui o tamanho de um dólar para dois. Este é outro operador útil do Mongo Dib. Eu aprendi sobre isso recentemente. Agora, e se realmente não houver bate-papo para usuário e destinatário? Basta então criar um novo bate-papo. Portanto, se o bate-papo não estiver disponível, o bate-papo será igual ao New Jet. Aqui no objeto, adicionamos participantes à matriz de ID de usuário, vírgula, ID do receptor e, em seguida, podemos aguardar o ponto de bate-papo c. No final, simplesmente retornamos a resposta com o código de status 201 Em JSON, simplesmente enviamos esse bate-papo e pronto. Agora que criamos a API Jet, antes de criar uma nova mensagem, devemos primeiro verificar se o usuário passou uma ID de bate-papo correta ou não e se também é participante do bate-papo ou não. Se não verificarmos essa condição, qualquer pessoa poderá enviar uma mensagem para qualquer pessoa ou grupo. O custo do chat é igual a await chat dot fine buy ID, e aqui passamos o jatiD Depois disso, verificamos se o Jet não está disponível ou se o jet dot Participants dot inclui o ID do usuário. Se o remetente não estiver entre os participantes, passamos seus pontos de exclamação e, em seguida, retornamos a resposta com o código de status 403 e a mensagem JSON para acesso Agora verificamos o jato. Agora, na nova mensagem, substituímos esse ID de bate-papo pelo ID de sublinhado do ponto de bate-papo Agora, o que mais precisamos fazer quando enviamos uma nova mensagem? Você consegue adivinhar? Certo, temos que atualizar a propriedade da última mensagem do bate-papo. Lembre-se de que, depois de salvar a mensagem, escrevemos o ponto de bate-papo. A última mensagem é igual ao ID de sublinhado do ponto da nova mensagem E depois disso, também aguardamos o chat dot save. E é isso. Agora, finalmente, T é essa API. Abra o Postman e aqui criamos uma nova pasta chamada chats e dentro dela, adicionamos uma nova solicitação chamada criar um novo Bom método para postar. No endpoint, adicionamos SGDP, coluna dupla, barra frontal, host local, coluna 3.000 barra, barra, barra, barra, barra Primeiro de tudo, precisamos passar o token no cabeçalho. De volta à nossa API de login e aqui para a conta Hari, copie bem esse token e em nossa API de criação de chat nos cabeçalhos, tivemos autorização para errar, rastrear esse token e enviar a solicitação Veja, aqui temos um erro interno do servidor porque o ID do receptor é necessário. Então, aqui no corpo, vamos para a lei. Aqui, passamos o JSNobject e passamos aqui o ID do receptor para os códigos, de volta para o Mango Di Becompass e aqui eu copio esse outro ID de usuário e colo no ID do Agora envie a solicitação. Veja aqui que temos um novo jato, copie esta identificação do jato. Como teste, envie a API de mensagem. Certifique-se de salvar essa API com Control plus ou Command plus a e, em seguida, duplique essa solicitação de postagem Altere o nome da solicitação para enviar uma nova mensagem. Além disso, percebo que em nossa API, precisamos passar o ID do chat no parâmetro da solicitação e o conteúdo no corpo da solicitação. Então, podemos fazer algo assim. Podemos alterar nossa API e apontar para enviar apenas mensagens, e aqui obtemos o ID do chat no corpo da solicitação. Bom. Guarde-os e volte para Postman Aqui, mudamos nosso endpoint para cortar bate-papos, cortar No cabeçalho, já temos o token, então só precisamos passar o corpo da solicitação. Aqui no objeto, passamos conteúdo para, digamos que essa seja a primeira mensagem. Também adicionamos o Jet ID e colamos esse Jet ID aqui. Agora envie a solicitação. Veja aqui que obtemos o novo conteúdo da mensagem em nossa mensagem e, no remetente, é nosso ID Agora é melhor que, no local do remetente, possamos ver o ID e o nome de usuário Com isso, é fácil exibir novas mensagens no front-end. No final, definimos o custo, preencher a mensagem é igual a aguardar mensagem dot find byDNew message dot underscore ID, dot Primeiro, adicionamos o remetente e, no segundo argumento, adicionamos o ID de sublinhado e usamos um nome E na resposta, retornamos uma nova mensagem para preencher a mensagem Salve as alterações e vamos enviar outra mensagem. Esta é a segunda mensagem e envie a solicitação. Veja, no remetente, obtemos ID e nome de usuário Então, aqui, nossa API de envio de mensagens está funcionando bem. Adorável. 188. O que são WebSockets: Então, nas lições anteriores, criamos APIs para enviar a mensagem e também definimos a API para receber mensagens de um bate-papo específico Agora imagine que esse é o nosso front-end e tem uma página de bate-papo aberta para dois usuários, Hurley e Mike Então essa é a tela de Hul e essa é a tela de Mike Ambos estão na página de bate-papo em que ambos são participantes, e ambos recebem duas mensagens que são o histórico do bate-papo. Agora imagine aqui Harley digitar uma nova mensagem e clicar em Enviar Então, no botão Enviar, chamaremos a API para enviar uma nova mensagem, certo? E, como sabemos, essa API salvará essa mensagem em nosso banco de dados. Agora, o problema é como Mike receberá essa mensagem porque Mike já pegou todas as mensagens desse jato e depois disso, Hurley envia a nova Uma delas era: Mike enviará solicitação de recebimento de mensagens a cada 5 segundos para receber novas mensagens. É como se Mike perguntasse ao servidor, há alguma mensagem nova para mim? O servidor diz que não. Novamente, após 5 segundos, Mike pergunta: há alguma mensagem nova para mim? Novamente, o servidor diz que não. Então, se o servidor receber uma nova mensagem, em mais 5 segundos quando Mike solicitar novamente a nova mensagem, nesse momento, o servidor enviará a mensagem para ele. Agora imagine que temos 10.000 ou 100.000 usuários em nosso site e todos os usuários enviam solicitações de mensagem a cada 5 segundos, o que realmente não faz sentido, porque só obteremos novos dados quando nosso servidor obtiver novos dados Caso contrário, nossas solicitações simplesmente vão para o servidor e retornam. Isso definitivamente tornará nosso servidor lento ou até mesmo travará algumas vezes. Então, aqui não podemos confiar nessa solução. Precisamos de algo que diga automaticamente a Mike se ele tem uma nova mensagem e a envie automaticamente na tela do mouse. E para resolver esse problema, temos o web socket. Então, o que são web sockets? Web Socket é uma forma de o front-end do nosso site e o back-end do nosso servidor se comunicarem em tempo real É como uma conversa bidirecional. Em palavras simples, os soquetes da web nos ajudarão a criar conversas em tempo real Uma conexão de soquete da web é como uma ligação telefônica entre o navegador e o servidor Depois que a chamada é feita, navegador pode falar com o servidor e servidor também pode responder a qualquer momento Agora você pode perguntar: qual é a diferença entre APIs e soquetes da web Imagine que este é o nosso front-end e este é o nosso servidor. Agora, suponha que no front-end queremos obter alguns dados, então enviamos uma solicitação de API do front-end para o nosso servidor. O servidor processará essa solicitação e enviará uma resposta ao nosso front-end, aqui nossa conexão de API será fechada. Por exemplo, do front-end, Harley envia uma mensagem para nosso servidor usando a API de postagem Agora, nosso servidor armazenará esses dados no banco de dados e retornará a nova mensagem ao front-end. Aqui, nossa conexão está fechada. Essa é a forma de conexão usando as APIs do SGDP. Agora vamos ver como funciona o web socket. Aqui temos o front-end, e este é o nosso servidor. Agora, primeiro de tudo, aqui criamos uma conexão usando o web socket Por essa conexão, nosso cliente pode enviar os novos dados do messet para o servidor sem nenhuma chamada de API O mesmo que o servidor também pode retornar novos dados do messet. Depois que o servidor fez uma nova mensagem de dados, essa conexão ainda permanece lá. Ele não fechará até fecharmos nosso site ou o fecharmos manualmente com o código. Deixe-me explicar com o exemplo do mundo real. Aqui está Harley, aqui está Mike e aqui está nosso servidor Suponha que Harley e Mike criem uma conexão com nosso servidor usando soquetes da web Agora, se Halley enviar uma nova mensagem para o servidor, servidor armazenará essa mensagem no banco de dados e, em seguida, enviará essa mensagem para o microfone sem que Mike envie a solicitação da API Agora, se Mike enviar uma mensagem para o servidor, servidor também armazenará essa mensagem no banco de dados e, em seguida, enviará essa nova mensagem para a Harley Agora, se nosso servidor receber outra mensagem para Mike de um usuário diferente, Mike também receberá essa mensagem, mas isso só acontecerá se Mike criar conexão com o servidor usando o soquete da web Se a Harley estiver conectada ao servidor, mas Mike não estiver conectado ao servidor usando o soquete da web , a nova mensagem será armazenada no banco de dados, mas não chegará ao É assim que o web socket funciona. soquetes da Web são usados para criar comunicação em tempo real entre o front-end e o back-end Não se preocupe, é muito simples. Entenda tudo isso quando aplicamos soquetes web em nosso back-end e provamos com o front-end 189. Conexão do soquete: Agora, na lição anterior, vemos que, se quisermos enviar e receber dados em tempo real , precisamos nos conectar ao soquete da web para lidar com o soquete da web, usaremos o soquete de biblioteca mais popular, dot IO Essa biblioteca é usada por muitas plataformas populares, então definitivamente podemos usá-la. Abra o terminal e aqui escrevemos NPM install socket dot IO na taxa 4.8 0.1 Ele entra. Bom, minimize esse terminal e vamos adicionar um soquete em nosso aplicativo de back-end No arquivo JS de pontos de índice, inserimos o custo Coli Brackets, servidor é igual a exigir soquete dot IO E na parte inferior, podemos adicionar custo AO igual ao novo servidor. Agora, neste servidor, temos que passar nosso servidor SGDP. Sem o servidor SGDP, o soquete não receberá a solicitação de conexão Para isso, precisamos criar um servidor SDDP. O custo do SDDP é igual ao SDP exigido. Este é o módulo SGDP integrado na parte inferior, adicionamos que o servidor Const é igual ao SDP dot Agora podemos passar esse servidor em nosso soquete. Bom. Agora, aqui está uma pergunta em qual placa o servidor de soquete ouvirá Porque aqui para o aplicativo Express, definimos a porta 3.000 e, no final, ouvimos com essa porta Em nossa implementação atual, se adicionarmos o soquete dot Listen a 5.000 , nossas APIs serão executadas na porta 3.000 e nosso soquete será executado Não é isso que queremos. Queremos que nossas APIs e soquete funcionem na mesma placa Então, para isso, aqui no servidor de criação, temos que passar esse aplicativo Express. Com isso, esse módulo SGTP criará um servidor com esse aplicativo expresso e o mesmo servidor que estamos usando para inicializar Também na parte inferior, precisamos alterar o ponto Listen deste aplicativo pelo ponto Lisen do servidor Caso contrário, isso não funcionará corretamente. Salve essas alterações e vamos reiniciar nosso aplicativo para garantir que ele esteja funcionando corretamente ou não. Veja aqui que o servidor está rodando em B 3.000 e também conectamos o Mongo Db Isso significa que está funcionando corretamente. Então, para recapitular rapidamente inicialização do soquete em nosso back-end, precisamos primeiro criar o servidor e passar o aplicativo Express InsideE, então podemos usar esse servidor para criar um servidor de soquete e, no final, também temos que servir o ponto LISN para essa porta Então, aqui inicializamos com sucesso o soquete em nosso aplicativo Agora, do front-end, qualquer pessoa pode se conectar a esse soquete Mas o que queremos fazer quando alguém se conecta ao soquete Precisamos adicionar essa lógica. É muito simples. Aqui, após essas rotas de aplicativos, adicionamos IO, que é o ponto da instância do soquete, e no primeiro argumento, passamos a conexão e, no segundo argumento, aqui passamos a função de retorno de chamada e o que fazemos quando alguém se conecta ao nosso Por enquanto, simplesmente consolamos o log de pontos. Usuário conectado. Sempre que, do front-end, alguém se conectar ao nosso soquete, essa função de retorno de chamada será executada Agora, como podemos provar essa implementação? Para provar isso, criei um aplicativo SGML e JavaScript fictício e simples Não se preocupe. Se você não sabe nada sobre front-end, eu vou te explicar isso. Além disso, se você não quiser provar, poderá ver essa degustação. Também ajudará você a entender o fluxo de trabalho do soquete Na pasta de recursos, temos a pasta Project three e, nela, temos o aplicativo de teste LinkFi, copiamos essa pasta e movemos para a pasta de nossos projetos Aqui colamos essa pasta. Agora abra esta pasta no código Vas. Bom. Aqui, primeiro usamos essa pasta de bate-papo simples. A razão pela qual eu uso aqui aplicativo de front-end é que, com um front-end real, soquete de aprendizado será divertido e também limpará o fluxo de trabalho completo do soquete Não se preocupe, você não precisa escrever nenhum código aqui. Apenas faça o que eu faço. Então, para executar esse front-end, rastreie esse arquivo GML simples de ponto de bate-papo no navegador e abra-o na nova guia Veja, aqui temos esse tipo de interface. Agora, volte ao código vis do front-end e abra este arquivo simples de pontos de bate-papo Na parte superior, você pode ver que o soquete de gravação é igual ao AO e, por dentro, passamos nosso link de back-end, que é a coluna 3.000 do host local Essa expressão significa que queremos nos conectar com o soquete, que é inicializado nesse Além disso, você pode perguntar como estamos obtendo esse método Ao. Estamos recebendo esse método Ao porque eu adicionei um soquete com o Dan Link Veja, aqui está, e por causa disso, estamos chegando aqui Aomthod Salve esta página e volte para o nosso front-end. Vamos verificar nosso console, então clique com o botão direito na página e vá para Inspec Veja aqui que obtemos este erro de curso para barra 3.000 da coluna do host local Agora você pode perguntar: já habilitamos o curso neste aplicativo expresso, por que ainda estamos recebendo esse erro de curso? O motivo é que configuramos o curso apenas para nosso aplicativo expresso, mas também precisamos configurar o curso para nosso servidor de soquete É muito simples. Aqui no método server, no segundo argumento, podemos passar as opções para o servidor de soquete Eu me oponho, passamos o curso aqui também do objeto, da primeira propriedade da origem à estrela, o que significa que qualquer porta é permitida. Além disso, se quisermos passar apenas nosso front-end , aqui podemos passar essa URL. Mas, por enquanto, continuamos com Star. Você pode copiar ou portar do navegador front-end. Agora, após a origem, podemos passar métodos, que são array e passamos aqui, Get e post. Esse método de sun especifica quais métodos SGDP são permitidos durante o soquete web Agora você pode perguntar o que é websocket Hensak. Quando um cliente se conecta a um soquete ou servidor di, ele começa com uma solicitação SDP. O aperto de mão Se for bem-sucedido, ele será atualizado para uma conexão de soquete da web Durante esse handshake, o servidor verifica se o método SDDP de entrada é É importante adicionar esses métodos porque, com isso, nossa conexão será estabelecida. Se não especificarmos os métodos corretos, navegador poderá bloquear a conexão devido a um erro no curso. Salve isso e vamos atualizar nosso front-end. Veja, aqui não recebemos nenhum erro e, se verificarmos nosso back-end no terminal, receberemos a mensagem do console de um usuário conectado. E também atualizamos nosso aplicativo mais uma vez. Então, em nosso back-end, veja, aqui novamente temos um usuário conectado, que significa que nosso usuário front-end está conectado com sucesso ao nosso back-end usando um soquete Então, para recapitular rapidamente, após inicializar o soquete, em nosso back-end, adicionamos ao dot na conexão e, no segundo argumento, passamos a função passamos Portanto, sempre que um novo usuário se conectar ao nosso soquete, essa função de retorno de chamada será executada E também dentro dessa função de retorno de chamada, escreveremos toda a nossa lógica para o soquete É assim que inicializamos e lidamos com a conexão do soquete 190. Emissão de soquete e métodos: Você pode pensar que escrever um código relacionado a soquetes é difícil Ele tem muitos métodos e funções. Como podemos aprendê-las? Se você tem esses tipos de equações, não se preocupe. Pela primeira vez, também acho que o soquete é muito difícil Mas quando eu realmente o aplico no meu projeto, é muito simples. soquete tem principalmente dois métodos, soquete ponto d e soquete 90% do tempo, usaremos esses dois métodos e, acredite, eles são muito simples. Então, como sabemos, o soquete é usado para conversas em tempo real entre o front-end e o back-end Basicamente, isso significa que, a qualquer momento, nosso servidor ou back-end pode enviar e receber dados do front-end sem nenhuma chamada de API, e também funciona ao contrário front-end também pode enviar e receber dados do back-end. Suponha que, do nosso front-end, Harley queira enviar uma mensagem para o back-end, como se essa fosse a nova mensagem Agora, o problema é: como podemos enviar dados do front-end? Então, para isso, usamos o soquete dot E send message. Esse é o nome do evento e, no segundo argumento, podemos adicionar nossos dados. Em inglês simples, emitir significa enviar. Então, estamos dizendo ao nosso soquete, emitimos os dados ou, em palavras simples, enviamos os Com isso, enviamos uma mensagem do front-end, mas no back-end, precisamos também escrever a lógica para lidar com esse evento. E para isso, usamos socket dot no envio da mensagem. Esse é o mesmo nome de evento que enviamos do front-end. E no segundo parâmetro, passaremos a função de retorno de chamada, que será executada quando recebermos o evento de envio de mensagem Então, escreveremos toda a nossa lógica nessa função de retorno de chamada. Se queremos armazenar mensagens no banco de dados ou enviá-las diretamente para outros usuários. Em palavras simples, lembre-se de que quando quisermos enviar dados do front-end para o back-end ou do back-end para o front-end, usaremos o método socket dot com o nome do evento e, quando quisermos receber dados do back-end ou do front-end , usamos socket dot on, e aqui escrevemos o mesmo nome do evento e função de retorno de chamada Vamos implementar isso em nosso aplicativo. Então, primeiro no front-end, adicionei o evento de envio ao nosso formulário, no qual temos a entrada de mensagens e o botão de envio E aqui recebemos a mensagem de entrada e usamos um nome preenchido nessas duas variáveis. Então, tudo está pronto. Temos que enviar mensagem usando o soquete. Então, aqui, qual método de soquete usamos para enviar a mensagem Certo, usaremos o soquete dot m. No primeiro argumento, escrevemos o nome do evento, digamos, enviar mensagem E no segundo argumento, podemos passar os dados que queremos enviar com esse evento. Digamos que passemos aqui o objeto com o remetente para o objeto sob ID quadrado, digamos 123, e usamos um nome para o valor do ponto do nome de usuário E outro conteúdo de propriedade para inserir o valor do ponto, que é o texto da nossa mensagem. Além disso, enviamos criado em para uma nova data e também passamos o status para envio. E é isso. Aqui, adicionamos preenchimentos conforme definimos no banco de dados. Aqui, por meio desse código, enviamos os dados da mensagem quando enviamos um formulário. Agora, vamos ver se estamos recebendo esses dados em nosso back-end ou não Então me diga qual método de soquete usaremos para obter os dados do evento Certo, usamos socket dot on. Você aprende muito rápido, adorável. Em nosso back-end no ao dot on, nós no socket dot on Na primeira discussão, o que passamos? Certo, passamos o nome do evento que queremos manipular, que é enviar mensagem. Certifique-se de escrever o mesmo nome que passamos do front-end. Caso contrário, não funcionará e também diferencia maiúsculas de minúsculas. Agora, no segundo argumento, passamos a função de retorno de chamada, que será executada quando alguém do front-end enviar esse evento de envio de mensagem No parâmetro dessa função, obtemos os dados e, por enquanto, simplesmente consolamos a nova mensagem do front-end e aderimos a esses dados Esses dados são o objeto da mensagem que passamos do front-end. Agora você pode perguntar: como podemos obter soquete nesse retorno de chamada o dot on Simplesmente chegamos aqui a partir do parâmetro. Usando esse soquete, podemos adicionar métodos de emissão e ativação. Salve essas alterações e vamos enviar uma mensagem pelo front-end. Atualize a página aqui, nome de usuário e aqui, mensagem, primeira mensagem e clique em Não enviado Aqui, nada acontece. E se verificarmos nosso back-end, verifique nosso terminal. Veja aqui, conectamos o usuário e, em seguida, obtemos esse objeto de mensagem, o que significa que recebemos a mensagem com sucesso do front-end. É muito simples enviar e obter dados usando o soquete. Só temos que lembrar o soquete e o ponto do soquete no método Agora, aqui recebemos a mensagem do front-end. Em seguida, o que queremos fazer com essa mensagem. Obviamente, queremos armazenar essa mensagem no banco de dados e, em seguida, devolvê-la ao front-end Nosso front-end pode exibi-la na tela. Por enquanto, não se preocupe com a lógica do banco de dados, nós a implementaremos mais tarde. Por enquanto, queremos apenas enviar essa mensagem para o front-end. Diga-me qual método usaremos para enviar os dados do back-end para o front-end. Sim, usamos socket dot e, no primeiro argumento, passamos o evento Receba uma mensagem. Você pode dar a ele qualquer nome. Isso não importa. Agora, o que queremos enviar com este evento? Quer enviar os mesmos dados. No mundo real, enviaremos um novo objeto de mensagem que armazenamos no banco de dados. Agora salve esse arquivo e, no front-end, precisamos lidar com esse evento de mensagem G, e você já sabe qual método devemos usar para lidar com o evento ou obter o evento. Certo, vamos escrever aqui o ponto do soquete. Primeiro, passamos o nome do evento, Get message, e no segundo argumento, passamos a função de retorno de chamada, e nesse retorno de chamada, no parâmetro, obtemos esses dados O que queremos fazer com essa mensagem? Simplesmente, queremos mostrar essa mensagem no navegador. Então, para exibir a mensagem, criei essa função de exibição de mensagem. Basta ligar para isso e passar os dados nele. Essa função criará uma mensagem e a exibirá em nosso navegador. Além disso, aqui você pode ver essa lógica, se quiser. Salve isso e vamos experimentar essa implementação. Certifique-se de atualizar a página depois de fazer qualquer alteração no código do front-end Caso contrário, você não receberá essas atualizações. Agora usamos um nome para Hurley e mensagem para a primeira mensagem e enviamos a mensagem Veja, aqui recebemos a mensagem no front-end em um segundo ou em um segundo Então, para recapitular rapidamente, o soquete tem principalmente dois métodos, soquete dot m e soquete dot O ponto do soquete é usado para enviar ou emitir os dados. E com o ponto de soquete ativado, podemos lidar com o evento enviado ou podemos ver o evento Se você entende esses dois métodos, parabéns. Seu soquete de 90% está pronto. É simples assim. 191. Recebendo mensagens para ambos os usuários: Na implementação atual, provamos com um usuário. Agora vamos experimentar com dois usuários ao mesmo tempo, como se Haley e Mike estivessem conversando um com o outro Portanto, abra outra guia privada do navegador ou você também pode usar outro navegador e abrir o mesmo arquivo S DML Agora, suponha que a primeira tela seja especificação Halley e a segunda tela seja a especificação Mike Eles estão conversando um com o outro. Então aqui Halley envia uma mensagem, e aqui ele recebe essa mensagem, mas Mike não está recebendo a mensagem Como aqui, do back-end, estamos enviando uma mensagem com soquete, como está funcionando para Halley e não para Mike O motivo é que, no back-end, usamos o soquete dot m. Esse método enviará evento somente para o usuário que emitiu o evento de envio da mensagem, e é por isso que Halley está recebendo essa mensagem, mas Mike não está Agora, qual é a solução aqui? Como queremos nossa mensagem, também enviaremos para outros usuários. Simplesmente no lugar do ponto do soquete, usaremos esse método ao dot Usando ao dot, podemos enviar mensagens para todos os usuários conectados ao soquete Salve esse arquivo e vamos experimentar essa implementação. Atualize as duas páginas. Bom. Além disso, aqui escrevemos o nome de usuário para os dois usuários e, a partir do Hal, escrevemos uma mensagem e a enviamos. Veja, agora Mike também recebe essa mensagem. E se enviarmos uma mensagem de Mike, veja, ele também a recebe. E é assim que o bate-papo em tempo real funciona. Ao usar o socket dot do back-end, só podemos enviar eventos para usuários que emitem esse evento E se usarmos ao dot , nosso soquete enviará esse evento para todos os usuários conectados usando o soquete 192. Lógica de participar de uma sala de bate-papo: Na lição anterior, estamos recebendo mensagens instantaneamente em ambos os usuários. E se adicionarmos outra janela e vermos o que acontecerá? Então, vamos adicionar outra janela privada e abrir o mesmo arquivo HTML. Agora escreva aqui, nome de usuário e , na primeira janela, enviamos mensagem. Veja aqui para ambos os usuários, recebemos a mensagem. E se algum outro usuário enviar uma mensagem , outros usuários também receberão essa mensagem, o que significa que nosso soquete está enviando a mensagem para todos os usuários conectados ao soquete É como se você organizasse uma grande festa. Aqui, as pessoas estão conversando em todos os lugares sem salas e, por causa disso, todas as conversas se misturariam. É como o usuário A falando com o usuário B, mas o usuário C ouve tudo, então não haveria uma conversa privada Que engraçado é que todo mundo está sentado em toda a casa em vez de falar gentilmente em uma sala Aqui também temos a mesma situação. Nossa implementação atual está enviando mensagens para todos os usuários. Então, qual é a solução aqui? Precisamos implementar salas. Portanto, salas no soquete podem resolver esse problema, permitindo-nos agrupar usuários Cada grupo ou sala é um espaço privado onde somente os membros dessa sala podem enviar e receber mensagens. Em palavras simples, room in socket são espaços virtuais onde os usuários podem entrar e morar Com isso, você pode transmitir mensagens para todos em uma sala sem incomodar os outros. Suponha que Halley e Mike queiram conversar um com o outro. Quando Halley abre um bate-papo, Halley entra em uma sala que tem um nome exclusivo, como chat HM Halley Agora Mike abre a página do Jet para falar com Halley. Mike também entrou na mesma sala chamada JathM. Agora, os dois usuários estão conectados na mesma sala. Então, se Halley enviar uma mensagem naquela sala, somente Mike receberá essa mensagem, não a terceira pessoa Olá, fecho a aba, então Halley perdeu a conexão com o soquete e quando o soquete é desconectado, o soquete dot IO remove automaticamente o Halley Com essa implementação, nossos jatos não se tornarão públicos e isso também funciona no bate-papo em grupo Suponha que o usuário A, o usuário B e o usuário C sejam membros do grupo e todos estejam conectados a uma sala específica de bate-papo ABC Agora, qualquer um deles está enviando mensagem. Outros dois receberão essa mensagem porque estão conectados na mesma sala. Você entenderá isso adequadamente quando implementarmos e testarmos esse recurso, e faremos isso na próxima lição. 193. Como implementar a participação em uma sala de bate-papo: Agora vamos implementar o recurso de sala em nosso aplicativo inkifi. Mas antes disso, deixe-me recapitular rapidamente o fluxo de trabalho. Então, quando o usuário abre um bate-papo, ele entra na sala com seu ID de bate-papo. Somente usuários na mesma sala podem enviar e receber as mensagens. E, finalmente, quando o usuário sai ou fecha o bate-papo , nós o removemos da sala. Então, primeiro de tudo, quando o usuário abre um bate-papo e, a partir do front-end, um evento deve acionar a chamada para entrar na sala com o ID do bate-papo. Depois disso, no back-end, adicionamos esse usuário naquela sala e, quando alguém envia uma mensagem, enviamos essa mensagem somente para os usuários que ingressaram nessa sala. Aqui em nosso back-end, lidamos com outro evento, socket dot on, e qual evento queremos realizar, sim, é a sala de junção Agora, aqui obtemos dados, ou podemos dizer, do front-end, enviaremos o ID do bate-papo, função de seta e, agora, para entrar na Sala, basta escrever socket dot join e aqui passamos o nome da sala, que é nosso ID de bate-papo, e para garantir que também console dot login in backticks, dólar do usuário Cali Brackets, socket dot ID, que é o ID ou podemos dizer, do front-end, enviaremos o ID do bate-papo, a função de seta e, agora, para entrar na Sala, basta escrever socket dot join e aqui passamos o nome da sala, que é nosso ID de bate-papo, e para garantir que também console dot login in backticks, dólar do usuário Cali Brackets, socket dot ID, que é o ID exclusivo do usuário atual fornecido pelo soquete Junte-se ao ID de bate-papo do Room dollar CL brackets. Agora, na mensagem de envio, queremos enviar mensagem somente para os usuários que estão atualmente nessa sala. Então, comentamos esse método EIT anterior, para que você possa examiná-lo mais tarde E aqui escrevemos uma mensagem MIG ao dot e passamos aqui os dados Agora, para enviar este evento apenas para uma sala separada, aqui adicionamos ao ponto dois e, dentro dele, precisamos passar o nome da sala que definimos como ID de bate-papo. Agora a pergunta é: como podemos obter o ID do chat? Certo, podemos passar o ID do chat pelo front-end. Então, ID do chat de dados, e pronto. Juntamos o usuário na sala e, em seguida, enviamos o evento get message somente para essa sala. Agora, para testar essa implementação, precisamos usar outro arquivo SDML Então, na pasta de testes, você obterá outra pasta chamada Romjat e dentro dela, você obterá o arquivo chamado Rojatt Além disso, em seu arquivo JS, primeiro, conectamos o usuário ao soquete e, em seguida, solicitamos o nome da sala no prompt Depois de obtermos o nome da sala, enviamos este evento de junção à sala. Isso nos ajudará a entrar em uma sala e, em seguida, o resto do código do front-end será o mesmo de antes. Apenas no evento de envio de mensagem, também enviamos o jet ID porque precisamos dele na mensagem de envio. Agora vamos executar esse arquivo. Escave esse arquivo e abra-o no seu navegador. Em primeiro lugar, ele solicitará o nome do quarto. Aqui, para degustação, estamos passando qualquer ID de jato aleatório. Digamos que o chat sublinhe um, dois, três. OK. Enquanto escrevemos, use um nome. Sem isso, podemos cometer um erro. Escreva use um nome, e se em nosso back-end abrirmos o Console, veja aqui podemos ver o usuário conectado e, em seguida, o ID do soquete do usuário, entrar na sala, e aqui obtemos o nome da sala, chat, sublinhado, um, dois, três Ótimo. Agora vamos abrir outra aba e fazer o mesmo. Escreva aqui o nome da sala, converse, sublinhe um , dois, três, porque queremos entrar na mesma sala Agora, aqui escrevemos o nome do usuário. E então escreva uma mensagem e envie-a. Veja, para ambos os usuários, estamos recebendo essa mensagem, então ela está funcionando muito bem. Agora, vamos abrir outra janela e entrar em uma sala diferente. Vamos conversar, sublinhado 45, seis. Bom. Agora, se enviarmos uma mensagem desse usuário, esses dois usuários não receberão essa mensagem. E se algum desses dois usuários estiver enviando a mesma mensagem , esse terceiro usuário não está recebendo essa mensagem. Então, isso também está funcionando. Então, é tão simples entrar sala e enviar uma mensagem para essas salas. Como eu disse anteriormente, o soquete é muito simples Você só precisa entender a lógica. 194. Exercício: indicador de digitação: Agora é hora de fazer pequenos exercícios. Neste exercício, você precisa implementar mostrar indicador de digitação quando alguém estiver digitando a mensagem A lógica é que, quando os usuários começam a digitar a entrada, acionamos a digitação de um evento de soquete E, a partir do back-end, enviaremos dados sobre quem está digitando e em qual sala ele está digitando Agora, depois de implementar isso como um bônus, quando nosso usuário não digitar por 2 segundos, acionaremos outro evento chamado Parar de digitar, que simplesmente removerá o indicador de digitação do front-end se preocupe, se você não conhece o código de front-end, basta escrever o código para o back-end, lidar com o evento e enviar usuário que está digitando ou qualquer Também adicionei código no front-end, que funcionará quando escrevermos algo na caixa de entrada. E também adicionei comandos nos quais você precisa emitir os eventos e também o código que precisa escrever ao lidar com esses eventos O objetivo deste exercício é pensar em termos de eventos. Então, tente implementá-lo e, em seguida, qual é a solução. Agora, vamos ver a solução desse exercício. Então, primeiro de tudo, em nosso back-end, temos que lidar com eventos, digamos, digamos, digitando Então, coloque um ponto na digitação. E a partir do front-end, enviaremos um objeto com jet ID e nome de usuário. Então, podemos desestruturá-lo aqui e obter o ID do jato, e também obtemos o nome do usuário, a função de seta E aqui enviamos essa mensagem para outros usuários que estão na mesma sala. Então, no ponto dois, aqui passamos o ID do bate-papo e, depois disso, ponto, mostramos a digitação E aqui passamos a mensagem em dólar BTI que o nome de usuário está digitando E é isso. Depois disso, também precisamos lidar com o evento, parar de digitar, então o soquete acenda e pare de E aqui também temos um objeto com ID de bate-papo e nome de usuário. E na função de erro, simplesmente optamos por marcar o ponto m, ocultar Aqui passamos o nome do usuário que para de digitar e pronto Não precisamos de mais nada no back-end. Neste exercício, se você confundir com o front-end , não se preocupe com isso Acabei de adicionar o front-end para degustação. Você também pode pular essa parte de degustação assim que souber como escrever a lógica e o evento do soquete Agora, vamos ver rapidamente essa parte da degustação. Como eu disse na lição anterior, aqui na parte inferior, eu adicionei esse código, que será executado quando escrevermos algo nessa caixa de entrada. Aqui, se o valor de entrada não estiver vazio, somente então fazemos o ponto de soquete m e qual evento emitimos, enviaremos o evento de digitação e, na segunda posição, adicionaremos o objeto com ID do bate-papo ao ID do bate-papo e, em seguida, também enviaremos o nome de usuário ao valor do usuário Nesse tempo limite de digitação, que será executado a cada 2 segundos quando escrevermos qualquer coisa na caixa de entrada, quando por dois segundos o usuário não escreveu nada , enviamos outro evento chamado parar de digitar Aqui, duplicamos esse método de emissão e o passamos aqui e alteramos esse evento para parar Fora desse ouvinte de eventos, precisamos lidar com dois eventos que emitimos do back-end Ponto do soquete ligado, mostre a digitação. Aqui, passamos a função Callback, e aqui recebemos a mensagem, usuário está digitando essa função de seta, nosso front-end escreverá sua lógica Por enquanto, simplesmente adicionamos aqui essa lógica que eu adicionei na parte inferior com o comando. Agora, depois disso, adicionamos outro ponto de soquete. Pare de digitar aqui também a função de retorno de chamada. Aqui, podemos usar um nome, se você quiser usá-lo. E aqui movemos essa segunda lógica para parar de digitar. Salve as alterações e dê uma olhada, atualize a página, insira chat, ID, chat, sublinhe um, dois, três e escreva usando um nome, Ali Agora, em outra janela, também atualizamos a página Digite chat, D, chat, sublinhado um, dois, três e escrevemos para usar um nome no microfone Agora vamos escrever algo de Mike. Veja aqui Olá, estamos recebendo a mensagem de digitação Mike está digitando. Mas aqui podemos ver que Mike está recebendo, Mike está digitando. Isso é o que nós queremos. Queremos nosso back-end, envie apenas o evento de digitação de programas para usuários que estão na sala de bate-papo, mas não para o remetente Para isso, aqui no lugar do ponto dois, precisamos fazer o soquete ponto dois e aqui o soquete dt dois , primeiro evento de digitação. Vou explicar isso em apenas um segundo, ver as mudanças e testá-las mais uma vez. Atualize a página, escreva jet ID, para conversar, sublinhe um, dois, três e escreva um nome de usuário, E também para Mike, atualizamos a página. Digite o jet ID, para conversar, sublinhe um, dois, três e escreva o nome de usuário, Mike Agora digite algo, veja que agora só Harley está recebendo Mike está digitando, e depois de 2 segundos, esta mensagem ainda está Deixe-me conferir o evento. Tratamos aqui de parar de digitar do front-end e qual evento estamos emitindo do back-end Oh, é digitação noturna. Então, em nosso front-end, alteramos esse evento para ocultar a digitação. Salve as alterações e vamos testá-las mais uma vez. Atualize a página. Escreva o ID do bate-papo para sublinhar um, dois, três e, aqui mesmo, use um nome Então, para Mike, reprimimos a página, insira o ID do bate-papo para sublinhar um, dois, três e, aqui mesmo, use um Agora escreva uma mensagem a partir daqui e se você parar por 2 segundos , essa mensagem desaparecerá. Então, isso está funcionando bem. Agora, aqui está uma pequena coisa. Veja quando enviamos a mensagem, então, por pouco tempo, estamos recebendo Mike digitando. Nós não queremos isso. Portanto, também emitiremos o evento stop typing quando enviarmos a mensagem Portanto, copie este soquete dot m para Pare digitar e cole-o no final do envio do formulário Guarde as inges e deixe-me prová-las mais uma vez. Atualize a página, escreva o ID e o nome do bate-papo. Além disso, fazemos a mesma repressão, escrevemos o ID e o nome do bate-papo Agora escrevemos a mensagem dela e a enviamos. Veja, agora não estamos entendendo essa digitação. Existem quatro variações de métodos no soquete ao ponto, no soquete ponto I ao ponto dois pontos do quarto M e no soquete do ponto dois do quarto do ponto m. Deixe-me explicar cada um em Então, não mostre a digitação. Isso enviará um evento de digitação de programas para todos os usuários conectados, independentemente de entrarem em uma sala ou não Ele enviará o evento de digitação do show para todos os usuários conectados ao soquete Em seguida, temos o soquete dot m, Mostrar digitação. Isso enviará Mostrar evento de digitação somente para o remetente. Em seguida, temos o ponto dois, a sala de pontos mostra a digitação. Isso enviará o evento de digitação do show para todos os usuários que entrarem nesta sala, incluindo o remetente No nosso caso, eles são Halley e microfone. É por isso que, anteriormente, recebemos evento show typing para ambos os usuários Por fim, temos o soquete dot two room dot show typing. Isso enviará o evento de digitação do show para todos os usuários que entrarem nesta sala, exceto o remetente Se Hal estiver digitando, Haley não receberá esse evento de digitação do programa Essa é a diferença básica entre esses métodos. Podemos usá-los de acordo com nossas necessidades. Não há regras sobre o uso apenas disso ou daquilo. Usaremos o que for mais adequado à nossa lógica. 195. Aplicando o código de mensagem de envio real: Agora, atualmente em nosso aplicativo, quando o usuário envia uma mensagem, simplesmente enviamos essa mensagem para todos os usuários que participam dessa sala de bate-papo. Mas no mundo real, também precisamos salvar essas mensagens em nosso banco de dados. Assim, mesmo que o usuário saia da sala, ele pode ver essas novas mensagens e também o histórico das mensagens. Vamos salvar nossa mensagem no banco de dados. Antes de tudo, quero esclarecer uma coisa. Quando enviamos uma mensagem pelo front-end, deve haver um bate-papo já criado entre os usuários. Por exemplo, se Hurley quiser enviar mensagem para ratos e se eles nunca conversaram entre si, isso significa que o bate-papo não é criado entre eles. Nesse caso, quando a Harley envia a primeira mensagem, chamamos uma API separada, que é nossa API de criação de bate-papo, e quando a Harley tiver et ID, emitiremos o evento de envio de mensagem com a ID do Nós já sabemos disso, certo? Lembre-se de que, no início desta seção, criamos a API de envio de mensagens. Sim, precisamos dessa mesma lógica aqui no evento de envio de mensagem. Então, vamos copiar esse código. E em nosso evento de envio de mensagem, simplesmente colamos aqui. Agora, primeiro de tudo, precisamos tornar essa função de retorno de chamada assíncrona Bom. Agora, aqui estamos recebendo ID do bate-papo e o conteúdo do corpo da solicitação. Mas no soquete, não temos o corpo da solicitação, então precisamos obter o ID do bate-papo e o conteúdo do parâmetro da função Então, aqui nós desestruturamos esses dados e obtemos aqui o ID e o conteúdo do chat Agora, o que mais precisamos? Certo, também precisamos do ID do usuário, então também o obtemos nesses dados. E agora não precisamos dessa linha. Além disso, na parte inferior, estamos enviando dados na resposta. Mas, como sabemos, no soquete, não obtemos resposta, então podemos simplesmente removê-la e, do soquete no local dos dados, enviamos essa mensagem de preenchimento Como no ponto dois, nós apenas no chat ID no lugar do ponto de dados Jet ID. Agora vamos verificar também onde usamos nossa resposta. Sim, no erro de retorno, e também aqui usamos a resposta. No local do envio do erro por meio da resposta, aqui podemos enviar uma mensagem de erro por meio do evento de soquete Mas a questão é para quem queremos enviar essa mensagem de erro? Devemos enviá-lo para todos os usuários ativos nessa sala? Não, queremos enviar essa mensagem de erro apenas para o remetente e me dizer qual método de soquete usamos para enviar eventos apenas para o usuário atual Certo, usamos o soquete dot m. Vamos enviar o evento chamado erro no envio da mensagem e simplesmente enviamos a mensagem de erro com acesso negado Agora, aqui, nosso código inferior ainda será executado. Então, para parar de executá-lo, podemos simplesmente adicionar aqui, retornar. Aqui, também emitimos o mesmo mecanismo de eventos de erro desta mensagem para esta mensagem O texto principal da mensagem de conteúdo é obrigatório e, depois disso, simplesmente adicionamos return, o que impedirá que nosso código execute o resto do código. Além disso, vamos remover esse código. Agora, nosso front-end pode lidar com esse evento de erro da maneira que quiser, seja exibindo alertas ou notificações de torrada Então, aqui precisamos importar esses modelos de chat e mensagem. Na parte superior, antes dessas rotas, adicionamos custo, chat é igual a exigir modelos de período, bate-papos de barra e outra mensagem de custo é igual a exigir modelos de período, mensagens de barra Salve as alterações e vamos experimentar essa implementação. No front-end, arquivo de pontos do roomchat, podemos verificar se estamos enviando os dados ou Sim, antes de tudo, aqui no local do remetente, precisamos enviar o ID do usuário Por enquanto, adicionamos aqui o valor do ponto do nome de usuário. Então, em nossa entrada de nome de usuário, temos que passar o ID do usuário. Depois disso, conteúdo para inserir valor. Aqui, não precisamos que isso seja criado em and status porque ele será gerado automaticamente por mangas e pronto Salve isso e vamos reformular a página. Aqui, precisamos do jet ID, então copiamos o jet ID do Mongo D que passamos e colamos aqui Agora temos que escrever aqui o ID do usuário no local do nome do usuário porque, no caso, definimos o ID do usuário como esse valor de ponto do nome de usuário. Copiamos um ID de usuário da coleção de usuários do Mongo Divi Compass e colamos aqui como remetente. Agora escreva uma mensagem. Digamos que o soquete seja fácil. Veja, recebemos a mensagem e, se verificarmos nosso banco de dados, e na parte inferior, essa nova mensagem também estiver, nosso evento de envio de mensagem está funcionando corretamente. 196. Autenticar o usuário no Socket: Agora, atualmente em nossa implementação, estamos obtendo o ID de usuário atual do front-end. Mas no mundo real, não podemos obter ID do usuário diretamente do front-end. Obviamente, por motivos de segurança, porque qualquer pessoa pode pegar qualquer ID de usuário e enviar a mensagem. Então, precisamos torná-lo um pouco mais seguro. E para isso, usaremos o middleware de soquete. É o mesmo conceito em que aplicamos middleware em nossas Como nosso middleware orth é executado antes de cada solicitação, o mesmo que o middleware de soquete será executado antes de nosso cliente se conectar ao o middleware de soquete será executado antes Deixe-me te mostrar praticamente. Aqui, antes desse método ao dot on, definimos nosso middleware de soquete usando ao dot U. Agora, neste método, passamos a função de retorno de chamada, que será executada antes que nosso usuário se conecte que será executada antes que nosso usuário Por enquanto, simplesmente adicionamos aqui log de pontos do console, executando o middleware de soquete Salve as alterações e vamos atualizar seu front-end. Aqui chat, ID, chat sublinhado um, dois, três. Agora, se verificarmos nosso terminal de back-end, veja, aqui primeiro começamos executar o middleware de soquete. Mas o que é isso? Não conectamos um usuário. Então, aqui em nosso middleware de soquete, nosso código está Precisamos movê-lo na próxima função, da mesma forma que fizemos em nosso Express ou middleware Nessa função de retorno de chamada, na primeira posição, obtemos o objeto de soquete, que é usado para obter informações sobre esse E no segundo parâmetro, obtemos next, que funciona da mesma forma que a próxima função no middleware expresso Agora, depois desse console, simplesmente chamamos essa próxima função. Salve as alterações e reprima a página. Digite aqui jet ID, e agora em nosso terminal, C, primeiro executamos o middleware de soquete e, em seguida, conectamos Com isso, fica claro que middleware do soquete está em execução antes que nosso cliente se conecte ao Agora, neste middleware de soquete, podemos fazer a autenticação do usuário, e como podemos Já fizemos isso antes em nosso middleware de autenticação. Certo. Para autenticação, usamos o JWT Então, nesse middleware, verificamos se o usuário passa o token JWT É válido ou não. Se for válido, somente então o usuário poderá se conectar ao soquete. E se o token não for válido, não permitiremos o usuário porque, para o jet, precisamos de um usuário logado Agora você pode perguntar: como podemos obter token nessa função de middleware Então, aqui vamos usar o objeto de soquete. Portanto, o token Const é igual ao ponto do soquete Hensig. Aqui obtemos dados que passamos com nossa conexão de soquete Nosso planejamento é obter dados no objeto OT e, dentro dele, passamos o token. Aqui escrevemos socket dot hensgtth dot token. Depois disso, simplesmente passamos aqui a condição. Se o token não estiver disponível, o que fazemos? Nós simplesmente rejeitamos a conexão. Para rejeitar a conexão, retornamos aqui a próxima função e, dentro dela, temos que passar um novo erro Aqui, passamos a mensagem de erro para erro de autenticação, token obrigatório. Agora, e se o usuário passar o token? Simplesmente, verificamos esse token e, para isso, precisamos do JWT Portanto, no topo, o custo, JWT é igual ao token web JSON necessário Bom. Agora, no banco de dados, adicionamos o JWT dot verify No primeiro argumento, passamos o token e, no segundo argumento, passamos nossa chave secreta de processo dot Env dot JWT underscore Deixe-me verificar o nome dessa variável. Sim, é a chave JWT. Agora, se esse token for verificado com sucesso, aqui chegaremos aos dados do usuário, que passamos com o token Nós o armazenamos em uma variável chamada usuário e, em seguida, simplesmente podemos fazer com que o usuário do ponto de soquete seja igual a esse usuário Além disso, quero que você saiba que objeto do soquete é diferente para todos os usuários Então, quando nosso usuário se conecta ao soquete, nosso soquete atribuirá a ele esse objeto e, por isso, ele é individual para todos os Este usuário de soquete tem nossos dados atuais de usuários logados. Então, para ver isso, simplesmente consolamos dot log, socket user e aderir socket dot user, e então temos a próxima função Agora, e se esse token não fosse verificado? Precisamos lidar com esse caso também. Então, aqui adicionamos blog try and cache e simplesmente movemos essas quatro linhas no blog Try. Então, se algo der errado nessas quatro linhas, nosso método de cache será executado. Então, no cache, o que fazemos corretamente é simplesmente rejeitar a conexão. Então, vamos copiar a próxima função com o erro e colá-la aqui. Além disso, em nosso front-end de degustação atual, precisamos enviar os dados do usuário do socket dot do back-end Então, aqui eu simplesmente adiciono o evento de dados do usuário socket dot e simplesmente passamos socket dot Nesse evento, nosso front-end registrará os dados dos usuários Caso contrário, precisamos inserir manualmente o ID do usuário para degustação. Agora vamos fazer essa implementação. Para isso, precisamos executar nosso arquivo de teste final. Honestamente, este é o último arquivo de teste. Não se preocupe. Em nossa pasta de front-end, temos uma pasta chamada teste final. E aqui, como sabemos, temos que executar esse arquivo SDML Mas antes disso, vamos ver o que eu fiz no arquivo JavaScript. Em primeiro lugar, peço um token no qual devemos inserir o token Jason Web Se inserirmos o token , somente conectaremos o usuário ao soquete Mas espere nessa conexão, o que eu fiz, eu adiciono aqui o objeto que enviamos para o soquete e nesse objeto, passamos OT e também token para o nosso token Este objeto que estamos recebendo em nosso back-end está no soquete dot hang dot th dot Tgon Agora, se esse token for verificado, nossa conexão será bem-sucedida. E se esse token não for verificado ou expirado, ponto do soquete no erro Connect, obteremos o erro de middleware do soquete Além disso, quando obtemos o evento de dados do usuário, eu simplesmente defino esses dados nessa variável do usuário. Além disso, todos os códigos relacionados ao soquete, foram adicionados aqui nesta condição if. Vamos ver se está funcionando ou não. Então, abra esse arquivo SDML nas abas de fechamento do navegador. Agora, primeiro de tudo, ele pedirá um token. Vamos passar aqui um, dois, três e, como sabemos, esse token não será verificado pelo nosso back-end. Vamos ver o que obtemos. Clique em OK. Veja aqui que obtemos um erro de autenticação, token obrigatório. Abra o postman e simplesmente abra API de login, envie a solicitação e receba o token Copie isso e simplesmente cole em nosso arquivo SDML. Veja, não recebemos o erro e, se verificarmos nosso terminal Bend, colocamos o usuário no soquete dos detalhes de nossos usuários com ID e nome de usuário e também conectamos um usuário, que significa que nosso middleware está funcionando Agora, usamos esse usuário socket dot em nosso evento socket. No evento de envio de mensagem, remova esse ID de usuário do parâmetro e, na parte superior, adicionamos o ID de usuário de custo igual ao usuário de ponto de soquete e um ID de pontuação Certifique-se de verificar o nome da propriedade de ID e também no evento de digitação no local de obtenção do nome de usuário do front-end, podemos passar aqui socket dot user, dot user name, e fazemos o mesmo no evento stop typing, socket dot user, dot user Agora também, removemos o parâmetro de nome de usuário para ambos os eventos. Agora, vamos provar novamente esta mensagem de envio. Portanto, reprima a página e baseie o token. Agora, aqui precisamos do ID do chat, então copie isso também do MongoivCmPass E cole no ID do bate-papo e clique em Entrar na sala. Sem entrar na sala, não podemos enviar mensagens. Agora, se enviarmos a mensagem daqui, digamos que esta seja a primeira mensagem de degustação final Veja, aqui recebemos a nova mensagem e, se verificarmos nosso back-end, ela também será armazenada no banco de dados com os dados corretos do usuário. Portanto, para recapitular rapidamente em nosso soquete, não devemos obter dados do usuário diretamente do front-end. Não será seguro. Então, criamos esse middleware de soquete e solicitamos token JWT antes de conectar o usuário ao Depois disso, verificamos esse token e simplesmente definimos os dados do token no usuário socket dot Então, aqui podemos usar esse usuário de pontos de soquete em toda a nossa lógica de soquete Além disso, como sabemos, o usuário do socket dot é individual para todos os usuários do soquete Então é assim que aplicamos e protegemos nosso soquete usando o JSON Web Token Aqui, como nossos conceitos anteriores são claros, é muito fácil entender tópicos avançados, como o middleware de soquete E é por isso que estou explicando soquete passo a passo para que você possa entendê-lo corretamente 197. Marcar usuários como Online e offline: Como você sabe, em muitos aplicativos de bate-papo, obtemos uma marca ativa ou online do usuário. Você acha como eles aplicam esse recurso? Não se preocupe nesta lição, marcaremos os usuários como online e offline. Em primeiro lugar, o que você acha quando um usuário está online? Pense nisso na linguagem humana. Nosso usuário está on-line quando se conecta ao soquete e, quando está offline, escreve, quando o usuário sai do seu aplicativo, ou podemos dizer que ele desconectado do soquete de forma simples assim Aqui, antes desses métodos de IO, declaramos que um novo custo variável para usuários on-line é igual a um novo mapa Agora, alguns de vocês podem perguntar: o que é esse mapa? O mapa é uma versão avançada do nosso objeto. Também é uma coleção do par de valores-chave. O mapa tem mais recursos do que o objeto. Então, como sabemos, no objeto, a chave é a mola. Em valor, podemos configurá-lo para qualquer coisa. Mas no mapa, podemos definir qualquer string, número, ouro, objeto, matriz, função, qualquer tipo pode ser chave Resumindo, para removedores de adição frequentes, mapa geralmente é mais eficiente do que usar objetos Ele foi projetado para lidar com pares de valores-chave com mais eficiência. Neste mapa, sempre que o usuário entra, podemos adicionar esse ID de usuário como chave e seu ID de ponto de soquete como valor Então, aqui no ponto io na conexão, simplesmente escrevemos o conjunto de pontos dos usuários online. No primeiro argumento, passamos socket dot user dot score ID, que é a chave no segundo argumento, passamos socket dot ID, que é nosso valor Agora só precisamos remover o usuário quando sua conexão for perdida, o que significa simplesmente que esse usuário está offline. Então, na parte inferior, adicionamos o ponto do soquete Aqui, passamos a desconexão e, em seguida, passamos a função Callback método de desconexão será executado quando conexão do soquete do usuário durar Nesse momento, esse método de desconexão será executado automaticamente Além disso, quando o usuário fecha a guia do navegador , esse método de desconexão também será executado automaticamente Portanto, não precisamos nos preocupar com um método de desconexão do front-end Aqui, simplesmente adicionamos os usuários online dot delete, socket dot user dot underscore ID, que é o ID de usuário atual Veja, no mapa, podemos usar diretamente método set e delete para adicionar e remover pares de valores-chave. Agora vamos ver se está funcionando ou não. Portanto, simplesmente aderimos ao log de pontos do console , aos usuários on-line e aos usuários on-line. Então, vamos copiar esse console e colá-lo quando adicionarmos o usuário neste mapa. Agora, vamos provar isso. Então, coloque o arquivo SDML na nova guia, cole aqui seu token E se verificarmos nosso terminal Bend, veja aqui que podemos ver a chave do usuário on-line para o ID do usuário e o ID do soquete como valor E se fecharmos nossa guia , aqui podemos ver que nosso usuário on-line está vazio. Então, isso é fácil. Você pode enviar esses usuários on-line para o seu front-end e mostrar indicadores como ponto verde ou qualquer outra coisa. 198. Vários conectores para um único usuário: Aqui está uma coisa em nossa implementação atual. Como sabemos, nosso aplicativo será usado no navegador ou nosso back-end poderá ser usado em aplicativos Se nosso usuário estiver conectado em uma guia , o ID do usuário e o ID do soquete serão adicionados aos usuários online Agora, se ele abrir uma nova guia e se conectar ao soquete , em nossos usuários on-line, obteremos outra chave como ID de usuário Mas aqui, a chave anterior e a chave atual são as mesmas, por isso, esse ID de soquete será substituído por um novo ID de ponto de soquete Agora imagine que ele fechou apenas a segunda aba. Isso também removerá o valor da chave do usuário e marcará nosso usuário como offline. Mas aqui ele ainda está online. Ele ainda está online na primeira aba. Então, aqui precisamos resolver esse problema de duplicação. Então, qual é a solução aqui? Podemos adicionar o ID do usuário como chave, da mesma forma que antes. Mas, ao definir diretamente o ID do soquete, podemos adicionar uma matriz ou conjunto de IDs de soquete, o que significa que duas guias têm dois IDs que significa que duas guias têm dois IDs Temos ambos nessa matriz e, se o usuário fechar apenas uma guia , podemos remover somente esse ID de soquete específico da matriz Você pode ver o quão avançados estamos avançando. Só estou brincando. Vamos implementar isso em nosso aplicativo. Em primeiro lugar, antes disso, adicionamos o custo do ID do usuário igual ao ID de sublinhado do ponto do usuário do ponto do soquete Agora, aqui no conjunto de pontos dos usuários online, primeiro temos o ID do usuário e, em segundo lugar, como valor, passamos o New Set. Você pode perguntar o que está definido. Set é a versão avançada das matrizes. Não se preocupe. Eles são muito simples. A razão pela qual usamos aqui definido no local da matriz é porque podemos facilmente adicionar e remover IDs de soquete do soquete Essa linha significa que criamos um novo par de valores-chave em usuários on-line. A chave é o ID do usuário e o valor definido está vazio. Aqui, queremos criar um novo par de valores-chave se nosso ID de usuário ainda não estiver disponível para usuários on-line. Então aqui passamos a condição. Se os usuários online tiverem ID de usuário, se isso for falso, passamos exclamação Mg. Só então criamos um novo par de valores-chave. Então mova essa linha aqui. Agora, depois de adicionarmos um novo par, ou mesmo se o ID do usuário já estiver disponível, o que queremos fazer? Certo, simplesmente queremos adicionar o ID do ponto do soquete no valor. Então, escrevemos para usuários on-line ponto G, o que queremos obter? Escreva userId como chave e, para adicionar um valor no conjunto, usamos o método dot add e passamos aqui o ID de ponto do soquete E por essa linha, adicionamos valor do ID do ponto do soquete no conjunto em que a chave é o ID do usuário, simples assim Então, aqui no lugar do socket dot user dot underscore ID, passamos o ID do usuário Agora, na desconexão, queremos remover o ID atual do soquete Portanto, os usuários online não recebem ID de usuário, ponto Dili, ID de ponto de soquete. Isso removerá o ID de ponto do soquete do conjunto em que a chave é o ID do usuário Agora, e se nosso usuário não tiver ID de soquete no valor? Nesse caso, também queremos remover o ID do usuário como par. Com isso, podemos marcar nosso usuário offline. Portanto, aprovamos sua condição se o tamanho do ponto GET userid do usuário dos usuários online for igual a zero Em seguida, nós simplesmente, usuários on-line, pontuamos Dilate UserID. Como você pode ver, podemos facilmente adicionar e remover itens do conjunto. Em vez de usar uma matriz onde temos que encontrar o índice desse item e depois remover esse item, podemos facilmente adicionar e remover itens do conjunto. Vamos ver se está funcionando ou não. Então reprima a página, página aqui, nosso token Agora, no terminal, obtemos o mapa, que tem um valor chave, ID de usuário e soquete Agora, no navegador, abrimos outra guia. Aqui abrimos nosso arquivo DML e, novamente, deixe-me colar o mesmo token Bom, e vamos verificar o terminal. Veja aqui que temos um ID de usuário e ele tem dois valores, que é nosso conjunto de IDs de soquete Agora vamos tentar fechar essa segunda conexão. Novamente, verifique o terminal. Veja que o último ID do soquete foi removido daqui, mas nosso usuário ainda está online Agora, se também fecharmos a primeira guia, verifique o terminal. Veja, nosso usuário foi removido do mapa, o que significa que agora nosso usuário está offline. Então, é tão simples marcar usuários online e offline. Eu sei que esta seção é um pouco longa, mas você pode ver como esse aplicativo em tempo real está funcionando. E se você aprender isso, poderá criar vários tipos de aplicativos em tempo real. Agora, aqui, você pode fazer uma pequena pausa, beber um pouco de água, alongar o corpo ou ouvir música. Aqui também estou fazendo pequena pausa e nos encontraremos na próxima aula. 199. Mensagens de atualização entregues: Vamos ver como podemos atualizar o status da mensagem para entregue. Primeiro de tudo, vamos descobrir a lógica disso para que você tenha uma compreensão clara ao escrever o código. Portanto, o status de entregue significa que a mensagem chegou ao dispositivo destinatário. Agora, existem duas situações. Imagine que o remetente envia a mensagem. Primeiro, armazenamos essa mensagem no banco de dados com status a ser enviado. Agora, naquele momento, se o destinatário estiver on-line, o que saberemos pela variável de nossos usuários on-line. Portanto, se o destinatário estiver on-line, marcamos imediatamente a mensagem como entregue. Essa é a primeira situação. Agora, outra situação é que nosso destinatário está offline, o que também saberemos pela variável de usuários online. Portanto, se o ID do destinatário não estiver disponível nos usuários on-line, isso significa que ele ou ela está offline. Portanto, se o destinatário estiver off-line, inicialmente nosso status de mensagem será enviado. Agora, sempre que o destinatário se conecta ao soquete, no momento, buscamos todas as mensagens não entregues e as marcamos como entregues e as marcamos Essa é a segunda situação. Vamos aplicá-los um por um. Nossa primeira situação, nosso destinatário está online. Se ele ou ela estiver on-line, basta marcar a mensagem como entregue quando o remetente envia a mensagem No evento de envio de mensagem, aqui na nova mensagem, precisamos verificar se o destinatário desse bate-papo está online ou não. Os consores dos usuários on-line pontuam, e aqui temos que passar o ID do destinatário. Mas como podemos conseguir isso? Certo, nós os obteremos dos participantes, mas também é uma matriz com ID do remetente Então, a partir dessa matriz, temos que filtrar o ID do remetente. Então, aqui, const recipients é igual a at dot participants dot filter Aqui, obtemos cada função de seta de ID e simplesmente passamos aqui ID da condição. A string de ponto dois não deve ser igual à ID do usuário Aqui, obtemos uma matriz com ID única porque temos apenas dois usuários em nossos participantes. É por isso que aqui no método He, passamos aos destinatários um pacote quadrado, índice zero, que é o primeiro elemento e é Mongo DiBid, precisamos convertê-lo Portanto, adicionamos uma sequência de dois pontos. Agora, o que queremos fazer se nosso destinatário estiver on-line? Simplesmente, retornamos o status para entregue. Se isso não for verdade, então, caso contrário, retornaremos enviados. É isso mesmo. Essa é nossa primeira situação. Agora, nossa segunda situação é que nosso destinatário está offline. Então, quando o destinatário abre o aplicativo e se conecta ao soquete, buscamos todas as mensagens não entregues e simplesmente as marcamos Aqui no soquete, ouvimos outro evento no soquete, marcamos as mensagens como Nós emitiremos esse evento do front-end quando nosso usuário fizer login e se conectar ao soquete Agora, dentro disso, precisamos fazer algumas etapas. Certifique-se de escrever essas etapas no comando. Caso contrário, você ficará confuso. Primeiro, precisamos encontrar todas as mensagens de bate-papo nas quais nosso usuário está disponível. Portanto, o custo das mensagens não entregues é igual ao await message dot find Além disso, tornamos essa função web de chamada assíncrona. Bom. Como sabemos na primeira posição, aqui passamos objeto com condição. Então, primeiro, o status a enviado e também o remetente não deve ser o usuário atual Remetente no objeto, usamos dólar N para não ser igual e passamos aqui Portanto, não precisamos de todos os campos das mensagens. Então, adicionamos aqui o método select e, dentro dele, passamos um ID de pontuação, ID chat e remetente Agora, essa consulta encontrará todas as mensagens cujo status foi enviado e seu remetente não é nosso usuário conectado, mas não verificará se nosso usuário conectado está participando do bate-papo Aqui também precisamos passar o ID do chat. Portanto, antes dessa consulta, precisamos encontrar todos os jatos nos quais nosso usuário conectado está disponível Portanto, Const chat IDs é igual a await chat dot find. Aqui, passamos o objeto com os participantes para o ID do usuário. Isso nos dará um bate-papo como este. Mas aqui só queremos IDs de bate-papo porque esse ID será passado em nossa consulta de atualização. Portanto, para distrair os únicos IDs dos dados no Mongo Di B, temos outro método chamado distins e, nos códigos, passamos o nome de preenchimento que queremos distrair, que é o ID de sublinhado dos dados no Mongo Di B, temos outro método chamado distins e, nos códigos, passamos o nome de preenchimento que queremos distrair, que é o ID de sublinhado . Então, anteriormente, sem um método distinto, obtemos dados como esses. Agora, com disting, obtemos nossos dados assim. Assim, podemos simplesmente passar esses IDs de bate-papo em nossa consulta fina. Então, o ID de bate-papo vale dois dólares em IDs de bate-papo. Portanto, agora, ele encontrará apenas as mensagens nas quais nosso usuário bloqueado está disponível. Ótimo. Agora precisamos atualizar somente essas mensagens. Então, aqui passamos a condição I para mensagens não entregues com tamanho de ponto, maior que zero Só então queremos atualizar o status das mensagens. Neste pacote de calibragem, aguarde a mensagem dot update many. No início, passamos um objeto para encontrar essas mensagens não entregues Então, passamos o ID de sublinhado para o objeto. Aqui, usamos dollar in e, como sabemos aqui, temos que passar uma série de IDs de mensagens. Como podemos conseguir isso? Nós os obtemos de mensagens não entregues, que é a matriz de IDs. Escrevemos um mapa de pontos de mensagens não entregues. Aqui, obtemos cada função de seta de mensagem e simplesmente retornamos o ID de sublinhado do ponto da mensagem Por essa expressão, obtemos a matriz de IDs de mensagens não entregues porque método map retorna uma matriz Além disso, podemos transmitir diretamente mensagens não entregues aqui. Mas, por enquanto, continuo com isso. Se você quiser fazer isso separadamente , você também pode fazer isso. Agora, o que você quer atualizar? Para isso, passamos outros colchetes de Cali e passamos aqui dólar definido para objeto, status para entregue Certifique-se de escrever a grafia correta que você escreve no esquema da mensagem Portanto, atualizamos as mensagens com sucesso. Agora vem uma parte divertida. O que você acha? O que devemos fazer depois disso? Então, para explicar isso com mais clareza, imagine que Hale e Mike tenham uma conversa Atualmente, Mike está offline e Hali enviou três mensagens. Como sabemos, por padrão, seu status será enviado. Aqui, nosso destinatário não está online. A lógica no evento de envio de mensagem não fará nada. O status permanecerá como enviado. Agora, assim como Halley, John também envia duas mensagens para Mike Seu status também será definido como enviado. Agora, depois de algum tempo, Mike fica on-line e se conecta ao soquete No momento em que atualizarmos essas três mensagens de Halley e duas mensagens de John, o que significa que, para um total de cinco mensagens, atualizaremos o status conforme entregues Agora, o que Halley e John receberão do back-end Simplesmente, podemos enviar ID das três mensagens de Halley para Halley e ID das duas mensagens de John para John e dizer a eles as mensagens cujos IDs são esses. Essas mensagens são atualizadas conforme entregues Portanto, nosso front-end atualizará a parte da interface do usuário usando esses IDs, o que significa que o front-end pode mostrar ícones de verificação dupla. Simples assim. Agora, aqui está uma coisa. Imagine que Halley envie 100 mensagens e Mike fique offline por um ano E quando ele ficar online, após a atualização, se enviarmos todas as centenas de IDs de mensagens para Halley, isso pode aumentar a carga de dados Então, o que eu acho é que, em vez de passar o ID de todas as mensagens, podemos enviar IDs de jet cujos títulos são atualizados para serem entregues, e esse único ID de bate-papo cobrirá todas as mensagens dentro desse bate-papo Portanto, não precisamos passar o ID de todas as mensagens. Então, aqui, nossa conclusão é que criaremos um objeto em que o nome da propriedade é o ID do usuário e, como valor, armazenaremos uma matriz de IDs de bate-papo que são atualizados. A razão pela qual usamos aqui uma variedade de IDs de bate-papo é que ela também funcionará para o bate-papo em grupo. Para um único usuário, pode haver vários IDs de bate-papo cujas mensagens são atualizadas à medida que são entregues. Agora, depois de obter esse objeto, escolheremos esse ID de usuário, encontraremos o ID do soquete em nosso mapa de usuários on-line e simplesmente emitiremos a mensagem de evento entregue e enviaremos esses IDs e simplesmente emitiremos a mensagem de evento de bate-papo Atualmente, não pense em como o front-end atualizará os bate-papos. Ele pode ser gerenciado. Aqui, nosso foco principal é criar esse objeto e enviar a mensagem do evento entregue a cada remetente Resto do trabalho feito pelo front-end. Nosso front-end também atualizará todas as mensagens na lista de bate-papo e na lista de mensagens ou simplesmente redirecionará os Vamos implementar essa parte. Vamos passo a passo. primeira é que precisamos criar esse objeto que tenha ID do usuário como propriedade e uma matriz de IDs de bate-papo como valor. Os IDs de bate-papo agrupados constantes são iguais a mensagens não entregues. Reduza Aqui temos dois parâmetros, AEC, que é o acumulador, acumulador é acumulador À medida que recebemos a mensagem, que é o objeto de mensagem única , a função de seta e, no segundo argumento, podemos passar o valor padrão desse acumulador Então, passamos aqui um objeto vazio. Primeiro de tudo, vamos verificar. O remetente da mensagem já está disponível em nosso objeto SC ou não Colchete I AC para acessar a chave do objeto e passar aqui o ponto da mensagem para o remetente Se estiver no acumulador, o remetente do ponto da mensagem não está disponível, então adicionamos aqui um ponto de exclamação Então, dentro disso, criamos uma propriedade com o nome acumulador, colchete, o ponto da mensagem, o remetente é igual a Depois disso, podemos simplesmente adicionar esse ID de jato nessa matriz. Acumulador, pacote quadrado, remetente de ponto de mensagem, mensagem push de pontos, ID de bate-papo por pontos Essa mensagem JetD é ID do objeto, então temos que convertê-la em string No final, simplesmente devolvemos o acumulador. Isso garante que o acumulador continue crescendo com novas mensagens. Agora, neste código, há um pequeno problema. Se um remetente tiver várias mensagens na matriz , duplicaremos essas IDs de jato na matriz, mas não queremos enviar IDs de jato duplicadas na Então, no lugar dessa matriz, podemos usar set. O conjunto não adicionará valores duplicados. Então, no lugar dessa matriz vazia, adicionamos um novo conjunto e, no lugar de usar o método dot push, usamos o método dot Ed para set. Os IDs de bate-papo em grupo retornarão um objeto com remetente como propriedade e definirão os IDs de bate-papo como valor Agora, também no final, precisamos de valores em matriz, então temos que converter conjunto em matriz. Para isso, usamos aqui para loop const, remetente em IDs de bate-papo em grupo Nesse loop, simplesmente agrupamos os IDs de bate-papo, o remetente do colchete é igual à matriz vazia e, dentro dele, o operador de propagação e simplesmente adicionamos os IDs do bate-papo em grupo ao remetente do colchete Agora temos nosso objeto com ID de usuário como propriedade e matriz de IDs de bate-papo como valor. Agora, precisamos apenas emitir para remetente e passar a matriz de IDs de jato como dados Aqui, usamos novamente for loop, const sender ID, jatos agrupados O ID do remetente é a chave do nosso objeto de IDs de bate-papo em grupo. Agora, neste loop, temos que descobrir se ID do remetente está online ou não Portanto, os soquetes Const são iguais aos pontos dos usuários online. Obtenha o ID do remetente Se tivermos soquetes, que já sabemos, podem ser matrizes e usamos soquetes dot para Aqui obtemos o ID de soquete individual, função de seta e, dentro dele, simplesmente atualizamos o status da mensagem Ioda two socketd.it No segundo parâmetro, passamos IDs de objetos de dados para IDs de bate-papo em grupo, ID quadrada do remetente do pacote Isso enviará todos os CAT IDs para esse remetente. Então, se você quiser, podemos declará-lo separadamente. Portanto, os IDs de bate-papo de custo são iguais aos IDs de bate-papo em grupo, colchete, ID do remetente e, na parte inferior, passamos os IDs de bate-papo para os IDs de bate-papo e pronto Agora vamos ver essa implementação. Então, as mudanças, abra o navegador. Na primeira janela, eu faço login com o token de Hal. E na segunda janela, eu entrei com outra conta Gere um novo token para outra conta. E cole em nosso site. Agora, vamos entrar no Room. Portanto, copie o ID do bate-papo da bússola Mongo Dew, cole-o e entre na sala a partir da conta Agora eu envio mensagem. Isso é testar a primeira situação de entrega e enviá-la. Veja, aqui somos entregues. Esta é nossa primeira implementação quando nosso destinatário está on-line. Agora, vamos testar quando nosso destinatário está off-line. Então, vamos fechar essa segunda janela e, novamente, enviar a mensagem de Olá, isso está testando para uma segunda situação de entrega. Veja aqui que não recebemos mensagens. Se verificarmos nosso banco de dados, coletarmos mensagens, atualizarmos a coleção e, finalmente, recebermos nosso status de mensagem enviada, o que significa não entregue Agora, quando nosso segundo usuário ficar online, status dessa mensagem deve ser atualizado e Hardy também recebe os IDs de bate-papo cujas mensagens são atualizadas Vamos abrir a página SDML na segunda janela. Faça login com o segundo token da conta, onde está, copie e adicione no token. Agora, no momento em que clicamos em Ok, S na primeira janela, obtemos o ícone de notificação nessa guia e, quando nos movemos para essa janela, recebemos suas mensagens enviadas. Isso significa que nossa implementação está funcionando bem e, também no console, você receberá IDs de jato que são atualizados. É uma parte muito interessante do aplicativo de bate-papo. Até mesmo mudar o status para cena não é tão difícil quanto esse status de atualização ser entregue. Se você estiver confuso, poderá ver esta lição novamente, entender a lógica e, com isso, comparar a lógica com seu código. Dessa forma, todas as suas dúvidas serão esclarecidas. Agora, na próxima lição, implementaremos o status das mensagens de atualização conforme visto. 200. Atualizando o status da mensagem para visualização: Vamos ver como podemos atualizar o status da mensagem para cena. O status visto significa que nosso destinatário viu essa mensagem. Então, aqui também temos duas situações. Vamos entendê-los com um exemplo. Imagine que Harley tenha quatro mensagens inéditas de Mike. O status de todas essas quatro mensagens é entregue. Agora, no momento em que Halley abre o bate-papo de Mike no momento, atualizamos o status dessas quatro mensagens entregues para cena Portanto, temos que buscar as mensagens entregues e atualizá-las conforme visto quando nosso usuário abre o bate-papo Essa é nossa primeira situação. Agora imagine que a Harley já está disponível no chat ou na sala e Mike envia uma mensagem Nesse momento, também precisamos marcar a nova mensagem Setters cena porque Hurley já está disponível na sala de bate-papo Esta é a nossa segunda situação. Vamos implementá-los um por um. Portanto, na primeira situação, temos que atualizar as estatísticas quando nosso usuário entra na sala com o ID do chat. Então, aqui ouvimos mais um evento, chamamos o soquete dot on, marcamos as mensagens como vistas e passamos aqui a função de retorno de chamada Em primeiro lugar, encontraremos novamente todas as mensagens que não foram vistas pelo nosso usuário atual Portanto, const unseen messages é igual a await message dot find, e aqui passamos primeiro ID do chat do objeto de comparação para o ID do chat, e obteremos o ID do chat do front-end neste parâmetro R: vamos tornar essa função assíncrona. Voltando ao nosso objeto de comparação, bate-papo para ID do bate-papo, remetente para os colchetes de Cully, dólar NE não é igual ao ID do usuário, que é o ID do usuário atual que estamos obtendo do middleware do soquete e à medida que passamos o Agora, aqui também, queremos obter apenas os preenchimentos selecionados, então selecione o ponto e atribua o ID e o remetente Agora, após essa boa consulta, aderimos à condição de que comprimento do ponto das mensagens não vistas seja maior que zero, somente então executamos a consulta de atualização Então, nessa condição, escrevemos mensagens de espera, atualização de pontos, muitas Em primeiro lugar, precisamos do mesmo objeto de condição. Portanto, copie esse objeto do método find e cole-o aqui. Bom. Agora, no segundo argumento, precisamos passar objeto, conjunto de dólares úmidos, objeto, status, para a cena. Deixe-me verificar se passamos esse valor em nosso esquema ou não. Oh, aqui passamos a ler. Portanto, coloque isso cena porque é mais fácil Guarde isso e volte para o nosso evento. Agora, novamente, a pergunta é a mesma. O que queremos fazer depois de atualizar as mensagens conforme vistas? Certo, informaremos todos os remetentes cujas mensagens forem atualizadas para o SN Então, aqui precisamos apenas do ID do remetente porque nosso ID de jato é fixo, que obtemos do front-end Por isso, é muito mais fácil do que um evento entregue. Portanto, o custo dos IDs do remetente é igual para me dizer qual método usamos para extrair a nova matriz da matriz existente Certo, usamos mensagens não vistas no mapa de pontos. Aqui, obtemos a função de seta de mensagem única e simplesmente retornamos o remetente do ponto da mensagem Esse remetente é o ID do objeto, então precisamos convertê-lo em string Agora, como sabemos, esse método de mapeamento coleta todos os IDs de bate-papo das mensagens não vistas, então podemos obter IDs de remetentes duplicados Podemos resolver isso usando set. Encapsulamos esse método de mapa com parênteses e, aqui mesmo, Criará o conjunto e, agora, para converter esse conjunto em matriz, simplesmente o envolvemos com colchetes e distribuímos o conjunto aqui Esse método de mapeamento nos fornecerá uma matriz com IDs de remetente duplicados É por isso que o convertemos em conjunto. Eu defino que não podemos duplicar valores e, depois disso, os convertemos novamente em uma matriz simples Agora temos IDs de remetente, então podemos simplesmente usar o loop const sender, que é o ID de remetente individual dos IDs de remetente Certifique-se de usar de not in aqui porque usamos in para obter chaves de objeto e usamos de esquecer o valor da matriz Anteriormente, nossos IDs de bate-papo em grupo eram objetos. É por isso que usamos em. Mas aqui, os IDs do remetente são matrizes. É por isso que usamos here off. Eu cometo esse erro antes e é muito frustrante porque não recebo o erro e ainda assim o código não está funcionando da maneira que eu quero Portanto, certifique-se de se lembrar disso. Nesse ciclo, novamente custamos soquetes iguais aos usuários on-line que recebem o remetente Aqui, fazemos o mesmo de antes. Se houver soquetes disponíveis , os soquetes não são. Aqui obtemos ID de soquete único, função de seta e, dentro dela, fazemos Iot two, ID de soquete, cena de mensagem dot m. Como dados, enviamos o ID do bate-papo para o ID do bate-papo e também enviamos o ID do usuário que envia essas mensagens. Visto por dois IDs de usuário, e pronto. Você pode ver como é simples. Essa é nossa primeira situação. Agora vamos implementar a segunda situação. Nesse caso, nosso usuário já está disponível nessa sala. Precisamos atualizar o status quando outro usuário envia uma nova mensagem na mesma sala. Portanto, em vez de escrever a lógica na mensagem de envio, podemos emitir as mesmas mensagens marcadas do evento visto no front-end quando o usuário recebe a nova mensagem na sala associada Portanto, nossa implementação final relacionada ao cenário de status está completa aqui. Agora, vamos simplesmente experimentar essa implementação. Então, no front-end, ao entrarmos em uma sala, depois disso, emita aqui esse evento, marque as mensagens como vistas e passe aqui o valor do ID do chat Além disso, temos que emitir o mesmo evento quando recebemos a nova mensagem No evento GET message, adicionamos se a ID do ponto de sublinhado do ponto do remetente dos dados da condição não for igual à ID do sublinhado do ponto do usuário Este é o ID de usuário do nosso usuário logado. Se isso for verdade, então fazemos socket dot, marcamos mensagens como vistas No segundo argumento, passamos pelo valor do ponto d. Veja as mudanças e dê uma olhada. Vamos atualizar esta janela e passar aqui o token da Harley. E também entre no jato. E do fundo, enviamos a mensagem. Isso é para degustar o status da cena e enviá-la. Agora, se em nosso banco de dados, verificarmos nossa última mensagem, veremos seu status para envio. E agora, se abrirmos uma nova janela e fizermos login com meu primeiro token de conta. Agora, novamente, se verificarmos o status da mensagem, veremos que ela foi atualizada para entregue. Agora, copio esse ID de bate-papo e, de outro usuário, entro nesta sala. Agora, vamos verificar novamente nosso banco de dados e atualizar os dados. Veja aqui que levamos a mensagem para a cena e também que o usuário receberá dados com o chat atualizado e quem viu essa mensagem é. Então é assim que atualizamos o status conforme visto usando o soquete. 201. Adicionando campos de grupo no schema: Agora vamos adicionar alguns recursos em nosso aplicativo. Atualmente, em nosso chat, implementamos apenas um para um chat. Agora vamos adicionar um bate-papo em grupo também e não precisamos fazer muita coisa nele. Em primeiro lugar, adicionaremos alguns campos relacionados a grupos em nosso esquema de bate-papo Aqui nos participantes, podemos adicionar vários usuários que fazem parte desse grupo. Depois disso, também precisamos da última mensagem e, depois disso, passamos esse grupo e o configuramos para digitar como Bullion e o padrão é false Aqui podemos adicionar comandos para grupos. Então, quando implementamos recursos de grupo, podemos lembrar quais campos precisamos manipular. Agora, depois disso, o grupo tem administrador, ou seja, administradores, que podem ser um ou mais Simplesmente copiamos a matriz de participantes com ID do objeto e referência para o usuário. Adicione aqui. Em seguida, o que precisamos? Sim, precisamos do nome do grupo, que é do tipo string, e o usuário também pode adicionar o ícone do grupo ou a imagem do grupo, que também é do tipo string. Acho que isso é suficiente para um bate-papo em grupo. Além disso, aqui, certifique-se de não adicionar required a true para preenchimentos de grupos, pois se o chat for um para um, então required to true para preenchimentos de grupos pode nos causar um erro de esquema Agora vamos ver o que precisamos fazer no esquema de mensagens. Aqui para grupos, não precisamos adicionar muita coisa. Só precisamos de status para todos os membros do grupo. Na mensagem de grupo, o status não será suficiente. Então, aqui, simplesmente adicionamos o status de entrega do arquivo, que é matriz, e dentro, armazenaremos objetos para o status de cada participante. Então, primeiro, usuário no tipo de objeto entre o esquema de pontos Pontos Tipos de pontos ID do objeto Referência ao usuário. Esse é o ID de usuário de cada participante. Além disso, para esse usuário, adicionamos status, então copie esse mesmo objeto daqui e cole dentro dele. Agora, depois disso, também precisamos horário em que nossa mensagem seja entregue, entregue no tipo até a data, e também precisamos ver e digitar até a data e pronto, não precisamos de mais campos. Se, no futuro, precisarmos, podemos definitivamente adicioná-los aqui. 202. Crie uma nova API de grupo: Agora vamos criar uma API para criar um novo grupo. Aqui, não precisamos usar o soquete para isso. Na rota de bate-papo, podemos simplesmente copiar essa API de criação de bate-papo e colá-la na parte inferior. Bom. Agora altere o endpoint para criar um grupo E nessa função, temos que fazer pequenas mudanças. Primeiro, no local do receptor, obtemos a matriz de participantes, que são os IDs de usuário dos participantes. Além disso, obtemos o nome do grupo dela. Para imagem de grupo, podemos adicionar outra API separadamente. E aqui precisamos desestruturar o corpo da solicitação. Em seguida, também mudamos a condição. Se os participantes não estiverem disponíveis, retornaremos a mensagem de erro, os participantes são obrigatórios. Agora, aqui não precisamos encontrar nenhum bate-papo porque os mesmos participantes podem ter vários grupos. Simplesmente removemos essa variável de bate-papo e a condição “if”. E aqui adicionamos const chat. Dentro do objeto, adicionamos participantes aos participantes. Mas aqui também precisamos adicionar o ID de usuário atual na matriz de participantes. Aqui, adicionamos uma matriz e aderimos ao ID do usuário. Em seguida, nome do grupo para nome do grupo. A é group para true, e passamos administradores para o array e, dentro dele, passamos o ID do usuário atual Se, no futuro, precisarmos adicionar mais participantes ou quisermos remover participantes, adicionar novos administradores ou atualizar o nome do grupo, atualize a imagem do grupo Por tudo isso, podemos criar APIs separadas. Por enquanto, não precisamos deles porque nosso foco principal é aprender os recursos de bate-papo em tempo real. Então, vamos testar essa API. Para isso, abrimos o Postman. Precisamos de outro usuário para adicioná-los ao grupo. Então, abra e registre uma nova API de usuário. Aqui, passamos outro nome de usuário. John underscore 24, e-mail para john em red gml.com e senha, eu mantenho a mesma de um a oito Você sabe por que, porque eu esqueci as senhas. Bom novo usuário criado. Agora, vamos duplicar a solicitação de criação de bate-papo e renomeá-la para criar um novo grupo e apontar para a barra API HATS slash Também no cabeçalho, já temos o token e no corpo do objeto, primeiro tivemos os participantes para organizar aqui adicionamos todos os usuários. Do banco de dados, simplesmente copiamos o ID de outras duas pessoas. Certifique-se de não copiar o ID do objeto da sua conta atual, o token que você passa no cabeçalho. Bom. Agora, depois dos participantes, passamos o nome do grupo e qual nome devemos dar ao grupo? Digamos que ninjas de nodos. Esse é o nome da escola, certo? Sim, e envie o pedido. Veja, aqui eu recebo um erro interno do servidor. Deixe-me verificar o que está errado. Em um terminal, recebemos erros nos participantes. Ah, aqui eu passo diretamente matriz dentro da matriz. Então, distribuímos a matriz de participantes, salvamos as alterações e enviamos a solicitação novamente. Veja, aqui criamos um novo jato de grupo. 203. Adicionando a lógica de grupo de bate-papo em eventos de socket: Vamos aplicar a lógica do bate-papo em grupo em nossos eventos de soquete. Em primeiro lugar, começaremos com o evento de envio de mensagem. Imagine aqui, o usuário enviar uma nova mensagem em um grupo. Agora, em ambos os casos, se o usuário enviar uma mensagem individual ou enviar uma mensagem em grupo pelo front-end, precisamos apenas passar o conteúdo da mensagem e também o ID do bate-papo. Portanto, em nosso bate-papo em grupo, também verificamos se o conteúdo foi passado ou não. Além disso, encontramos o jato por sua identificação. Em seguida, também criamos uma nova mensagem com o mesmo objeto, mas na mensagem de grupo, temos que aderir ao status de entrega, selecionar o status de entrega e, depois disso, passamos a condição se o grupo jette for verdadeiro, então precisamos criar uma matriz de objetos parecida com esta Então, para isso, usamos o status de entrega igual ao mapa de pontos dos participantes do jet dot. Aqui, obtemos a função de seta do usuário e, dentro dela, simplesmente retornamos Object. Agora, no objeto, de usuário para usuário e status para aqui, passamos a condição. Usuários online não usam. Se isso for verdade, adicionaremos o status foi entregue. Conforme enviado. Além disso, adicionamos delivery at two aqui, também precisamos da mesma condição, para que possamos adicionar a variável antes desse retorno. O custo on-line é igual ao ponto dos usuários on-line como usuário. Agora, no local dessa condição, passamos on-line e na entrega também, se o usuário for verdadeiro, passamos uma nova data, caso contrário, passamos nula Agora, aqui está uma coisa. Nesses participantes, também recebemos o ID do remetente e não queremos adicionar o ID do remetente no status de entrega Aqui temos destinatários, que é a versão filtrada dos participantes Então, no lugar dos participantes do jet dot, adicionamos o mapa de pontos dos destinatários Com isso, não precisamos atualizar o status explicitamente na parte inferior Depois disso, também atualizamos o último status no chat. Agora, aqui preenchemos os dados do Sendar e emitimos o evento get message para o ID do chat Agora também preenchemos os dados, mas aqui também precisamos preencher status de entrega do usuário porque, individualmente, usamos apenas nosso status global, mas no bate-papo em grupo, temos que exibir a hora de cada usuário Aqui, adicionamos outro método de preenchimento. No início, o status de entrega é pontuado pelo usuário e o que você deseja preencher Escreva o ID de sublinhado e o nome de usuário. Agora vamos ver o que precisamos fazer para marcar mensagens como evento entregue. Então, como sabemos, tornar o status de entrega do usuário logado em uma mensagem de grupo é um pouco confuso Então, em vez de usar o mesmo evento, é melhor criarmos um evento separado para mensagens de grupo. Portanto, eles marcam as mensagens, pois o evento entregue é para apenas um bate-papo individual. Além disso, precisamos fazer pequenas mudanças. Como sabemos, esses IDs de bate-papo são todos os IDs de bate-papo nos quais nosso usuário está disponível, mas isso também incluirá bate-papos em grupo Então, aqui no método chat find, passamos mais uma condição. Agrupe como falso, o que significa que ele retornará apenas um jato para um, e pronto. Não precisamos mudar nenhuma outra coisa. Agora, vamos criar um novo evento. Então, socket dot on event, digamos, marque as mensagens do grupo como entregues, e passamos aqui uma função synclWC Chamaremos esse evento quando nosso usuário fizer login no front-end, mesma forma que emitimos mensagens marcadas como evento entregue Agora, primeiro de tudo, precisamos todos os IDs de jato de grupo nos quais nosso usuário está disponível. Jet IDs é igual a await chat dot find. No objeto de comparação, passamos os participantes para o ID do usuário. Do grupo à verdade. E aqui só queremos identificações. Então, qual método vamos usar, certo, usamos ponto distinto e passamos aqui o ID de sublinhado Agora, depois disso, precisamos encontrar mensagens não entregues nesses IDs de grupo cujo status é enviado Assim como antes, as mensagens não entregues const são iguais a await message Objeto, passamos o ID do chat para o objeto, e dólar para o ID do chat. Além disso, remetente para objeto, dólar N para zero é igual ao ID do usuário, que é o ID do usuário conectado Agora, precisamos também encontrar as mensagens que não são entregues ao usuário conectado no momento Então, aqui passamos o status de entrega. Objetar, e como sabemos, status de entrega é uma matriz de objetos com o usuário e seu status. Precisamos verificar o usuário, pois nosso ID de usuário e status estão definidos para envio. Para isso, precisamos especificar a condição que deve corresponder aos elementos individuais de uma matriz. No nosso caso, é usuário e status. Não se confunda, veja isso. Podemos usar aqui outro Mongoiboperator, dollar Aleem, correspondente ao objeto, e aqui passamos o usuário para o ID do usuário, e o status do usuário deve ser enviado Então, por meio dessa imagem, podemos especificar a condição mesmo na matriz de objetos. Além disso, não precisamos de mensagens ou informações, então simplesmente adicionamos os dados de seleção de pontos e passamos aqui ID de sublinhado, ID de rede , remetente e dados de entrega. Ótimo. Agora, depois disso, passamos se a condição mensagens não entregues for maior que zero Só então queremos executar a consulta de atualização. Neste registro de IP, usamos uma mensagem constante de quatro loops de mensagens não entregues E dentro desse loop de quatro, simplesmente ponderamos a mensagem dot update one. Primeiro, passamos o objeto de comparação, ID de sublinhado para o ponto da mensagem, o ID de sublinhado e, nos códigos, o status de entrega, ponto de usuário para ID de usuário No segundo argumento, passamos Objeto com dólar definido para objeto primeiro em códigos, status de entrega ponto, status de dólar , status de dois entregues. Aqui, esse status de ponto em dólar nos ajudará a atualizar apenas o preenchimento cujo usuário é o ID do usuário. Agora, também, queremos adicionar entregue no momento, em códigos, status de entrega, ponto em dólar entregue, e passamos aqui uma nova data. E pronto. Esse loop for atualizará o status para entregue para todas essas mensagens não entregues Agora, o que queremos fazer depois de atualizar as mensagens? Certo, queremos enviar os IDs do jato cujo status está atualizado. Portanto, a partir do nosso evento anterior de marcar mensagens como entregues, podemos simplesmente copiar toda essa lógica após esse método de atualização. E cole depois do loop de outono e certifique-se de que também esteja no blog I. Em primeiro lugar, neste blog, estamos criando objetos para remetentes e, como valor, buscamos o conjunto de IDs de bate-papo que são atualizados O motivo pelo qual usamos este conjunto é porque ele removerá todos os IDs de bate-papo duplicados e nos fornecerá IDs de bate-papo exclusivos Depois disso, convertemos isso em matriz e, por fim, executamos esse loop de outono para seu remetente a partir de IDs de jatos de grupo E nesse loop, encontramos os IDs de soquete desses remetentes e simplesmente emitimos o status atualizado da mensagem de evento e passamos esses IDs de jato para o remetente relacionado Portanto, não precisamos mudar nada nessa lógica. Você pode ver como é simples. Só precisamos esclarecer o que queremos fazer. Agora vamos passar para o último evento, que é marcar as mensagens como vistas. Aqui também, criamos um evento separado para marcar mensagens de grupo como vistas. Ponto de soquete em Marcar mensagens de grupo como vistas. E aqui passamos a função de retorno de chamada ASN e, no parâmetro dessa função, precisamos do Jet ID desse grupo Agora, copiamos a consulta de mensagens não entregues do evento entregue em grupo e a colamos aqui Agora, aqui mudamos as mensagens não entregues para mensagens não vistas, ID do chat, ID do chat, remetente para objeto, dólar NI para não igual ao ID do usuário, status da entrega, imagem, ID do usuário para o usuário e o status é objeto, dólar, dólar, Agora podemos passar a condição I se comprimento do ponto das mensagens não vistas for maior que zero, então queremos executar a consulta de atualização Novamente, copiamos esses quatro loops do evento de grupo entregue e os colamos em nosso evento visto. Agora, aqui mudamos essas mensagens não entregues para mensagens não vistas e, no dólar de atualização definido no local de entrega, comercializamos SN e também no local de entrega em, atualizamos SN Certifique-se de não receber erros em nenhum desses colchetes CLI Tenha cuidado com isso. Agora, o que você quer fazer depois de atualizarmos as mensagens conforme vistas? Simplesmente, copiamos a lógica do evento de cena simples. E cole-o após nossa consulta de atualização. Basicamente, aqui enfrentamos o remetente sary dessas mensagens e, usando for loop, simplesmente emitimos uma mensagem em um evento com ID de bate-papo e vista por, e pronto Agora vamos testar essa implementação. Aqui, abrimos o arquivo SDML final no navegador, passamos o token para o usuário Bom. Agora precisamos entrar no bate-papo em grupo. Do Mongo Di que incluímos na coleção de bate-papo, simplesmente copiamos nosso ID de bate-papo em grupo , colamos no ID de bate-papo e entramos na Agora vamos enviar a mensagem neste grupo. Olá, este é um bate-papo em grupo e envie-o. Bom. Se verificarmos nosso banco de dados, atualizarmos a coleção e, na parte inferior, C, recebermos a mensagem e, no status de entrega, obteremos uma matriz vazia Deixe-me ver o que está errado. Vá para nosso evento de envio de mensagens. Aqui na nova mensagem, esquecemos de adicionar o status de entrega Então, status de entrega para status de entrega, salve as alterações e vamos testar novamente nossa implementação. Atualize o navegador, passe o token do usuário. Copie a ID de bate-papo da coleção , cole-a na ID de bate-papo e entre na sala. Agora vamos enviar novamente a mensagem. Olá, este é um bate-papo em grupo e envie esta mensagem. Agora, se verificarmos novamente nosso banco de dados, atualizarmos a coleção na parte inferior, receberemos uma nova mensagem e, no status de entrega, agora obteremos o status de cada participante Ótimo. Agora vamos adicionar outra janela aberta novamente SDMLFle aqui eu adiciono um token de uma conta diferente E no momento em que pressiono Enter, veja em nossa primeira janela, recebemos uma notificação de que sua mensagem de envio foi entregue, o que significa que nossa marcação de evento em grupo como evento entregue está funcionando. Eu atualizo o banco de dados, vejo no status de entrega da mensagem, que o status do usuário é entregue, e também chegamos aqui entregues na hora Bom. Agora deixe-me entrar no mesmo bate-papo. Então vá com esse Jet ID. E cole aqui e entre na sala. Veja, na primeira janela, recebemos uma notificação de que sua mensagem foi vista por esse usuário. Se verificarmos novamente o banco de dados, atualizarmos a coleção e, na parte inferior, consultarmos esse usuário, atualizaremos nosso status como visto e também obteremos a cena no momento Isso significa que nossa marcação de mensagens de grupo como evento de cena também está funcionando corretamente. É muito simples e não confuso porque separamos a lógica em diferentes eventos de grupo Então é assim que implementamos o bate-papo em grupo no soquete. 204. Seção 16 — Opções de implantação: Bem-vindo à última seção do curso definitivo de nodos hair. Nesta seção, veremos processo de implantação de aplicativos de nós. Então, atualmente, nosso aplicativo está sendo executado em nossa máquina local. Agora, para usar nosso aplicativo globalmente, precisamos implantá-lo. É uma coisa muito fácil. Não se preocupe com isso. Portanto, há duas maneiras de implantar aplicativos de nós. Podemos usar pass, que significa plataforma como serviço, ou podemos usar o Docker Agora podemos perguntar o que é pass e Docker. Portanto, passar nossa plataforma como serviço significa que podemos usar uma plataforma que nos ajude a implantar nosso aplicativo. PAS, temos Render, Eoco, Google Cloud Platform, AWS, Microsoft, Azure, etc. Essas plataformas oferecem uma variedade de funcionalidades, por isso não precisamos nos preocupar muito com o processo de implantação. É como se você quisesse abrir uma barraca de comida. Agora, em vez de se preocupar em comprar um fogão, configurar a eletricidade e obter conexões de água, basta alugar uma cozinha totalmente equipada Aqui você só precisa trazer seus ingredientes, cozinhar sua comida e começar a vender. É exatamente isso que o PAS faz para os desenvolvedores. Com o PAs, não precisamos nos preocupar em configurar servidores, bancos de dados, redes ou esquiar. Essas plataformas cuidam de tudo isso para nós. Nós apenas escrevemos nosso código JS de nota, o implantamos e ele é executado. Simples assim. Por outro lado, se você quiser controlar sua implantação ou se quiser implantar aplicativo node em seu próprio servidor web , o Docker é uma ótima opção Com o Docker, podemos criar uma imagem do nosso aplicativo e implantá-la em qualquer computador do mundo Como você imagina, usar o Docker é um processo um pouco complexo. Por enquanto, não precisamos nos preocupar com isso. Portanto, se você não quiser se preocupar com servidores, balanceadores de carga, infraestrutura ou reiniciar seu aplicativo em caso de falha , a plataforma como serviço é uma boa opção Portanto, nesta seção, usaremos render para implantar nosso aplicativo de nó porque ele tem a maneira mais fácil de implantar o aplicativo de nó e também fornece ótimos recursos Pessoas diferentes gostam de plataformas diferentes, mas acho que a renderização é uma ótima maneira de implantar e também tem pneus livres Assim, podemos implantar nosso aplicativo gratuitamente e sem detalhes do cartão. 205. Simplificando o código: Antes de implantar nosso aplicativo, vamos tornar nosso arquivo js index dot mais limpo e legível Isso criará uma boa impressão em nossa equipe e também todos nós gostamos de trabalhar em código limpo. Vamos fazer isso acontecer. Aqui, criamos um arquivo separado para coisas separadas, como para conexão de banco de dados, arquivo separado. Para rotas, temos outro arquivo e, para soquete, também temos um arquivo separado como esse É muito simples. Vamos fazer isso um por um. Primeiro, separamos a conexão com o banco de dados. Aqui em nosso projeto, criamos uma nova pasta chamada startups. Dentro disso, criamos um novo arquivo chamado DibtJS. Agora, neste arquivo, queremos adicionar código para conexão com o banco de dados. Aqui, a partir do arquivo JS de pontos de índice, recorte o método Mongoose dot Connect E cole em nossos novos cinco. Agora, aqui precisamos de algumas coisas. Primeiro, precisamos das mangas. Suced Mangoose é igual Além disso, precisamos desse registrador, sconct logger é igual a require, vamos uma pasta para cima, vamos para a configuração, vamos para a configuração, Agora, uma pergunta que você pode fazer: como podemos adicionar esse código em nosso arquivo JS de pontos de índice? É muito simples. Não se confunda. Deixe-me te mostrar. Aqui na parte inferior, simplesmente modulamos que as exportações de pontos são iguais a. Aqui adicionamos uma função dentro dessa função, simplesmente movemos esse método Mongoose dot Connect Voltar ao arquivo JS de pontos de índice. Diga-me como podemos inserir algo do arquivo db dot js? Usamos o DV de startups de barra avançada exigido. Essa expressão retorna o que exportamos desse arquivo DB e o que exportamos da função. Podemos armazenar isso em uma variável chamada const DB e, em seguida, podemos chamar essa função Em vez de fazer isso em duas linhas, podemos simplesmente fazer isso em uma linha. Além de armazenar essa função em banco de dados variável, podemos simplesmente chamá-la aqui Quando chamamos essa função, código de conexão é executado, e é isso que queremos. Então, aqui nosso primeiro passo está feito. Agora vamos separar a implementação de todas essas rotas. Na pasta de inicialização, criamos um novo arquivo chamado routes dot js. Além disso, como antes, exportamos o módulo dot exports é igual à função dentro dessa função, adicionamos todas as nossas rotas. Portanto, corte todas essas rotas de aplicativos com o middleware de aplicativos course express dot Json e também o middleware de erro global Eles e cole-os em nosso arquivo de rotas. Agora, aqui precisamos de algumas coisas. Primeiro de tudo, precisamos desse aplicativo e como podemos obtê-lo? Devemos criar um novo aplicativo nesse arquivo e depois usá-lo? Não, não podemos fazer isso porque isso criará um novo aplicativo Express. Mas aqui queremos usar nosso mesmo aplicativo. Qual é a solução aqui? A solução é muito simples. Aqui, a partir do arquivo js de índice, após esse banco de dados, tínhamos período exigido, inicialização de barra, rotas de corte, que é nossa função Chamamos essa função e simplesmente passamos app como argumento. Em nossa função de rotas, simplesmente obtemos o aplicativo como parâmetro. Em seguida, o que queremos? Precisamos de curso e como podemos obter sim, podemos usar da mesma forma. Mas, como sabemos, o curso é nosso pacote e podemos usar o pacote em qualquer arquivo simplesmente inserindo. Com o aplicativo, não podemos fazer isso, só é por isso que obtemos o aplicativo como parâmetro. Então, no topo, o curso de custo é igual a exigir Cos. Além disso, precisamos do Express, que também podemos importar aqui. Cost Express é igual a require express. Agora, depois disso, também precisamos de logger, sconct, logger, é igual a require, temos um filer up, config Agora, em seguida, precisamos dessas rotas, rotas econstUser, é igual a require Aqui, também movemos uma pasta para cima, direcionamos os usuários. Agora duplique essa linha mais duas vezes usando alter plus sift, seta para baixo ou opção dot Sift mais seta para baixo Aqui, primeiro, alteramos o nome da variável para postar rotas e o arquivo para post. Em seguida, alteramos a variável para rotas de bate-papo e arquivo para bate-papos e pronto. Terminamos a Etapa dois. Agora vamos separar nossa lógica de soquete. A partir dessa variável de usuários on-line, selecionamos nosso código até obtermos o ponto LISN do servidor Corte isso na pasta de inicialização, criamos um novo arquivo chamado socket dot js Neste arquivo, novamente, o módulo dot exports é igual à função. Nessa função, adicionamos nosso código. Agora, primeiro de tudo, aqui precisamos desse método AO. Diga-me, devemos criar um novo objeto Ao? Precisamos usar o mesmo objeto Ao que criamos usando o servidor. No arquivo index dot js, precisávamos de um soquete de inicialização de período E aqui chamamos essa função e simplesmente passamos aqui Ao Object. No arquivo socket dot js, aqui obtemos um parâmetro para o objeto Io. Simples assim. Agora, nessa lógica, temos que importar muitas coisas, então não tente se apressar Vamos linha por linha. Veja, neste caso, precisamos desse JWT Na parte superior, JWT é igual a exigir o token web JSON. Em seguida, o que precisamos. Sim, precisamos desse modelo de bate-papo e também precisamos desse modelo de mensagem. Então, no topo, o gráfico de custos é igual ao necessário, aqui está uma pasta de modelos de bate-papos Além disso, se você se confundir ao importar o arquivo, deixe-me mostrar minha trigonometria quando estou importando Aqui, queremos importar o modelo de mensagem. A mensagem de custo é igual a exigir. Em primeiro lugar, eu fecho todas as pastas usando esse botão e, em seguida, simplesmente abro a pasta na qual estou trabalhando. É a inicialização e também pasta aberta da qual eu quero importar. Isso são modelos. Atualmente, estamos na pasta Stu. Precisamos sair dessa pasta, então adicionamos ponto e barra de avanço de ponto Em seguida, queremos ir para a pasta Modelos e importar do modelo de mensagens. Veja, é simples assim. Agora deixe-me ver o que mais precisamos importar. Acho que é tudo o que precisamos. Se perdermos alguma coisa , obteremos um erro. Não se preocupe com isso. Agora vamos ver a aparência do nosso índice Dsi Veja, está claro agora, mas vamos deixar isso mais claro. Aqui temos muitas entradas não utilizadas. Nós podemos removê-los. Primeiro, removemos a linha de entrada de código, então pressione Control plus X ou Command plus X para remover a linha inteira. Portanto, removemos Mongos e removemos todas as importações realizadas , que nem todas são usadas Veja, agora nosso código parece mais limpo, fácil de escalar e todos nós adoramos trabalhar com esse tipo de aplicativo limpo. É assim que o código de desenvolvedores profissionais deve ser. 206. Como preparar o aplicativo Node para produção: Agora, antes de iniciarmos o processo de implantação, é melhor preparar nosso aplicativo de nós para produção. Então, para isso, precisamos de alguns pacotes, como o primeiro é o capacete Já usamos isso em nosso projeto anterior. Basicamente, o capacete é usado para segurança do nosso aplicativo É uma excelente opção para aumentar a segurança do nosso aplicativo com configuração mínima. Além disso, ele protege nosso aplicativo contra vulnerabilidades comuns da web, configurando cabeçalhos STDP adequados Em nosso terminal, instale o capacete NPM e, se quiser usar a mesma pessoa que o meu, use na taxa 8.1 0.0 e Agora, outro pacote é a compressão. Esse também é um pacote muito útil para aplicativos de nós. Como sabemos, às vezes precisamos enviar dados de grande porte para muitos usuários. Por exemplo, lista de postagem ou lista de mensagens. Este pacote comprimirá esses dados de grande porte e reduzirá a carga de envio de grandes dados Então, o NPM instale o Compression no d 1.8 0.0 e pressione Enter. Bom. Agora, vamos implementar esses pacotes em nosso aplicativo. Não se preocupe, são apenas duas linhas de núcleo. Então, aqui na pasta inicial, criamos um novo arquivo chamado prod dot js Neste arquivo, importamos esses dois pacotes. Portanto, const, capacete é igual a exigir capacete e const, compressão é igual a exigir compressão Da mesma forma que antes, exportamos a função deste módulo. Portanto, as exportações de pontos do módulo são iguais a aqui que exportamos a função. Aqui temos o aplicativo como parâmetro e, dentro dele, queremos implementar essa forma intermediária. Capacete App dot U, que é a função, nós o chamamos. Por isso, apenas o capacete é aplicado em nosso aplicativo. Além disso, adicionamos a compressão app.us, e também a chamamos e pronto Com essas duas linhas de código, aplicamos esses pacotes em nosso aplicativo. Além disso, você pode adicionar esse código no arquivo route dot js. Não há nada de errado nisso. Agora, aqui só precisamos importar esse módulo em nosso arquivo js de ponto de índice principal. Aqui, antes dessas rotas, simplesmente exigimos o período DatabSpd que retornará essa função Então, temos que chamar essa função e simplesmente passar seu aplicativo como argumento. Certifique-se de que ele seja adicionado antes da importação dessa rota. Portanto, nosso capacete e compressão se aplicam a todas as rotas e pronto Ao usar essas duas linhas, podemos tornar nosso aplicativo um pouco melhor. 207. Visão geral do processo de implantação: Vamos ver a visão geral do processo de implantação para não nos confundirmos. Atualmente, nosso código está disponível em nossa máquina local, ou podemos dizer, em nosso computador. Agora, para tornar nosso aplicativo ativo na Internet, usamos a plataforma de renderização. Primeiro, faremos o upload do nosso código no Github e, em seguida, conectaremos nosso repositório Github ao nosso serviço, que é renderizar. Não se preocupe com isso. É muito simples. Vou explicar todas as etapas de forma simples e fácil. Além disso, veremos como atualizar nosso código depois de implantarmos nosso aplicativo. Vamos começar com o upload do aplicativo Node no Github. 208. Como fazer upload do aplicativo de Node no Github: Vamos ver como podemos fazer o upload do nosso projeto no Github. Se você não conhece o Github, em resumo, é um site que permite aos desenvolvedores armazenar, compartilhar e colaborar no código com outros Além disso, o Github permite que os desenvolvedores criem um repositório ou podemos chamar repositórios onde eles podem armazenar seu código e acompanhar as alterações Essa é a melhor e mais fácil maneira de as equipes trabalharem juntas em um mesmo projeto sem sobrescrever o código umas das outras Portanto, há muitas maneiras de fazer upload de nosso código no Github, mas veremos a maneira mais fácil e simples, que é usando o aplicativo de desktop Github Acesse o navegador e pesquise aplicativo Github Dektop e abra este Agora clique no botão Download. Isso levará algum tempo. E depois de concluir esse download, abra a configuração e nosso processo de instalação será iniciado. Bom. Agora, se você abrir este aplicativo pela primeira vez, precisará fazer login com sua conta do Github Então, para mostrar isso, eu removo minha conta do Github do aplicativo de desktop Gitub. Agora, para fazer o login, acesse o arquivo e abra Opções e clique neste login em forgitub.com Continue com o navegador. Isso nos redirecionará para o site do GitUbOficial, preencha seu nome de usuário e senha da sua conta do Gitub Preciso verificar minha conta e pronto. E agora clique neste aplicativo de desktop Open Github. Ele nos redirecionará automaticamente em nosso aplicativo. Não se preocupe, você só precisa configurar pela primeira vez. Agora vamos verificar se estamos logados ou não. Então, novamente, vá para Arquivo e Opções e, nas contas, podemos ver que temos nossas contas. Vá para a opção Git e, a partir daqui, podemos definir nosso nome e e-mail para o nosso Github Então, quando enviarmos o código no Github, outros membros da equipe verão esse nome e e-mail Além disso, certifique-se de selecionar seu e-mail oficial aqui e clicar em Salvar. Agora, antes de avançarmos, como sabemos, em nosso projeto, temos a pasta de módulos do nó. Não queremos postar isso no Github porque, a qualquer momento, podemos gerar a pasta Node Module usando o comando de instalação do NPM Portanto, é inútil fazer o upload de toda a pasta de módulos do nó, que tem muitos arquivos Portanto, temos que evitar que essa pasta seja carregada no Github. Para isso, em nosso projeto na raiz, criamos um novo arquivo chamado dot git ignore Certifique-se de não cometer nenhum erro de digitação no nome desse arquivo. Deveria ser dot gitignore. Agora, neste arquivo, podemos adicionar quais arquivos e pastas queremos ignorar ou, em palavras simples, quais arquivos e pastas não queremos carregar no Github Suponha que queiramos ignorar essa pasta de módulos do nó, então escrevemos módulos de sublinhado do nó, que é o nome da pasta, e a barra invertida, que indica que essa é Da mesma forma, queremos ignorar a pasta de registros. Então, o que escrevemos? frontal de gravação de registros. Agora, aqui está uma coisa. Quando carregamos nosso código no Github, como sabemos, esse código se tornará público e todos poderão ver nosso projeto Agora, suponha que enviemos nosso projeto e esse DonVFle também seja carregado no Com isso, todas as nossas informações secretas se tornarão públicas e qualquer pessoa poderá usá-las indevidamente Portanto, também temos que adicionar esse arquivo dot NV e gitignore. Deixe-me mostrar um atalho para obter o arquivo Gate Ignore. Basta acessar seu navegador e pesquisar, Get Ignore, Github. Abra este primeiro link e aqui temos todos os modelos para diferentes tipos de aplicativos. Faça com que o Android Git Ignore. Além disso, você tem C plus, C e muitos outros arquivos. Agora pesquise no topo, node gitignore e abra Veja, aqui temos o conteúdo do arquivo GetI Nur. Basta copiar esse código e adicioná-lo ao nosso arquivo GetI Nur. Salve as alterações e teremos nosso arquivo GetI Nur. Legal. Agora vamos finalmente fazer o upload do nosso código no Github. Para adicionar nosso código ao repositório, acesse Arquivo e selecione Adicionar repositório local E aqui selecionamos o caminho do nosso aplicativo inkifi. Agora aqui diz que temos que criar um novo repositório, então clique nesse link E aqui temos que passar o nome do nosso repositório. Além disso, podemos escrever aqui a descrição. Este é o aplicativo de mídia social e clique em Criar repositório. Agora vamos verificar se tínhamos o caminho certo ou não. Então clique em mostrar no Explorer e veja aqui nossa pasta Linky five, então feche-a e simplesmente clique em Repositório publicado Aqui podemos alterar o nome e a descrição do repositório, além de selecionar a privacidade do código Além disso, você pode torná-lo privado, mas eu quero lhe dar esse código. É por isso que eu o torno público e clico em Publicar. Isso levará algum tempo e pronto. Vamos ver no Github, então clique em visualizar no Github e veja aqui que obtemos nosso aplicativo Adorável. Você pode ver como é simples fazer upload de código no Github. Agora, na próxima lição, configuraremos nossa conta de renderização. 209. Implantando o aplicativo de Node na renderização: Vamos implantar nosso aplicativo de back-end no Render. Então acesse render.com e, antes de tudo, registraremos nossa conta aqui Podemos usar o Google ou o Github para registro ou podemos simplesmente usar e-mail e senha, e temos esse painel. Não se preocupe com isso. Basta clicar no botão Novo e aqui selecionamos o serviço web. Agora, aqui precisamos conectar nossa conta do Github. Então, o Glicon conecte o Github e faça login com sua conta do Github Certifique-se de usar a mesma conta do Github na qual publicamos nosso código de back-end Nessa página, podemos selecionar qual repositório queremos adicionar em nossa conta de renderização Você também pode adicionar todo o repositório, mas, na minha sugestão, selecione somente a opção de repositório selecionada A partir daqui, podemos selecionar o repositório, para que possamos selecionar nosso aplicativo inkifi Agora, isso nos redirecionará para a página inicial do painel. Veja, agora chegamos aqui ao nosso repositório. Basta clicar neste repositório e aqui obtemos nosso formulário Agora, primeiro de tudo, aqui adicionamos o nome do nosso aplicativo, que é nosso Linkifi Obteremos esse nome como nosso URL base do nosso aplicativo. Em seguida, temos o ambiente definido como node. Não mude isso. Em seguida, podemos selecionar a ramificação do nosso repositório Github que é principal ou principal Além disso, podemos selecionar a região. Agora, para o diretório raiz, adicionamos ponto final e, para o comando build, escrevemos NPM install Para o comando start, simplesmente adicionamos node index dot js. Basicamente, por meio desse comando, render executará nosso aplicativo. Na parte inferior, selecionamos nosso tipo de serviço, que selecionamos gratuitamente. Agora clique neste menu suspenso Avançado e selecione Adicionar arquivo secreto e dê a ele um nome de ponto e V. Agora, de volta ao nosso projeto de vagão, e nele abrimos dotyNVFle, no qual temos Basta copiar todo o código e, no site da Render, clicar em Conteúdo e colar nosso código aqui. Agora, basta clicar em Criar serviço web e ver nosso processo de implantação iniciado. Isso levará algum tempo, como cinco a 10 minutos. C, construa com sucesso. Agora ele está sendo implantado e, depois disso, recebo um erro em uma boa conexão B. Deixe-me verificar isso. É um erro relacionado à variável do banco de dados. Acho que cometi um erro ao adicionar um arquivo secreto. Então, aqui vamos para a guia de ambiente, e aqui, deixe-me verificar o conteúdo do arquivo. Isso é bom. Oh, aqui eu insiro o nome do arquivo errado. Deveria ser dotNV. Eu crio esse erro intencionalmente porque quero mostrar como verificar o ambiente de um ônibus Então, as mudanças, e de volta ao Logstab. Aqui, ele iniciará novamente o processo de implantação. E veja aqui, novamente obtemos um erro na conexão com o banco de dados. Por quê? Portanto, atualmente, nosso banco de dados é um banco de dados local, o que significa que está funcionando em nossa máquina local. Agora, quando implantamos o aplicativo Node, não podemos acessar o banco de dados local. Então, nesse momento, temos que adicionar o banco de dados Cloud, e faremos isso na próxima lição. 210. Adicionando o MongoDB Cloud: Atualmente em nosso back-end, temos um banco de dados Mongo Debe local, então temos que criar nosso banco então temos que criar nosso dados Mongo Dibe Com isso, todos os usuários usarão o mesmo banco de dados. Então acesse mongotib.com e simplesmente se inscreva com sua conta e simplesmente se inscreva A configuração levará apenas 1 minuto. Eu já me inscrevi, então aqui eu tento fazer login com minha conta. Graças a Deus, está aberto. Agora, no canto superior esquerdo, temos o novo botão Projeto. Clique nele e aqui escrevemos o nome do nosso projeto, que é nosso Linky fi, e clicamos em Avançar Agora, a partir daqui, podemos adicionar membros da equipe ao nosso projeto. Basta clicar em Criar projeto. Agora clique no botão Criar. Aqui, selecionamos o plano, basta ir para a versão gratuita e clicar em Criar implantação. E veja aqui que obtemos nosso nome de usuário e senha para nosso banco de dados. Então eu copio o primeiro nome de usuário e na nota paga, colo aqui. Depois disso, copie também essa senha aleatória e cole-a também. Essa é a etapa mais importante. Podemos salvar esse nome de usuário e senha como backup do nosso banco de dados. Agora clique em Criar banco de dados. Em seguida, clicamos em, escolhemos um método de conexão. Selecione aqui Bússola. Veja, aqui temos o URL de conexão Mangaib para nuvem. se preocupe, basta copiar este link do banco de dados e, em nosso arquivo ENV no local dessa tinta local de Mangaibi, colamos nosso link colamos nosso Além disso, aqui eu esqueci de adicionar um nome de banco de dados no final desta URL Portanto, certifique-se de adicioná-lo assim. Está bem? Agora vamos continuar. Temos que dar acesso a uma rede que possa ler e gravar dados em nosso banco de dados. De qualquer lugar, o usuário pode acessar nosso banco de dados e receber postagens dele. No lado esquerdo, vá para Network Xs. Aqui temos nosso endereço atual. Clique em Editar e simplesmente clique em Permitir acesso de qualquer lugar. Você define nosso endereço como 0.0.0.0, que é o ás para cada um e clica em Confirmar Isso levará pouco tempo e verá que está ativo. Bom. Além disso, se você quiser verificar a configuração relacionada ao acesso ao banco de dados, como editar a senha ou algo assim, poderá fazer isso nesta etapa. Agora, vamos verificar se está conectado ou não. Então, abra o terminal e escreva node, index dot js e pressione Enter. Isso levará algum tempo e conseguiremos nos conectar com sucesso, então está funcionando. Agora temos que atualizar nosso código implantado. Como podemos fazer isso? Simplesmente, precisamos enviar nosso código para Github e a renderização detectará automaticamente essas alterações, e é por isso que não adicionamos nenhum projeto ao Github Agora, aqui está uma coisa. Sabemos que ignoramos esse arquivo Dotty e V ao fazer o upload no Para atualizar os valores das variáveis de ambiente, precisamos acessar o site de renderização. Aqui, selecionamos variáveis de ambiente. Clique em editar e, simplesmente a partir daqui, podemos editar nossos valores. Eu substituo o URL do banco de dados pelo Cloud. Aqui também, você precisa adicionar o nome do seu banco de dados no final dessa URL. Agora, clique em, salve, reconstrua e implante. Bom. Se verificarmos nossos registros, depois de algum tempo, obteremos novamente o registro de implantação E veja aqui, conectamos Mongo a B com sucesso. Adorável. Agora, vamos provar que nosso aplicativo está realmente funcionando ou não. Então, aqui copiamos o URL do Cspace do nosso aplicativo implantado. Agora abra o postman e, com isso, duplicamos essa API de criação de novo usuário porque apenas criamos o novo banco de dados, para que não tenhamos nossos dados anteriores nele Agora, vamos alterar a URL do host local pela URL do nosso aplicativo implantado e enviar a solicitação Veja, aqui temos o token JWT, o que significa que nossa API está funcionando. Vamos verificar isso. No site da Mongo Deb, acesse nosso aplicativo Linkify, aqui obtemos Browse Collection e veja, aqui obtemos todas as nossas coleções e eu Veja, aqui temos o novo usuário. Adorável. Mas espere, enquanto estou chegando aqui, experimente o nome do banco de dados. Acho que esqueci de adicionar o nome do banco de dados na URL da coleção Vá para variáveis de ambiente, clique em Editar. E sim, depois dessa URL, adiciono slas de encaminhamento e aqui adiciono o nome do banco de dados Digamos que nosso Linky se corrija e simplesmente clique em Salvar, reconstruir e Ele reconstruirá nosso aplicativo e, no final, nos conectaremos ao nosso banco de dados Deixe-me experimentar novamente a API, enviar a nova solicitação do usuário e aqui eu recebo o novo token. Bom. Agora acesse o site do Mongoib e atualize o banco de dados. Veja, aqui eu tenho nosso banco de dados inkifi. Ótimo. Agora, deixe-me mostrar também como podemos atualizar nosso código e reimplantá-lo Então, em nosso projeto, o que podemos mudar? Vamos ver esta mensagem do console, servidor está rodando na porta PT Isso é apenas para demonstração, salve as alterações e atualize o código na renderização. Precisamos apenas colocar nosso código no Github, renderizar, buscar automaticamente nossas atualizações e reimplantá-las Então, de volta ao nosso aplicativo de desktop Github, e aqui passamos a mensagem Commit Digamos que atualize a mensagem do console e clique em Confirmar um arquivo para o principal e, no final, simplesmente envie a origem. Agora, em nosso site de renderização, vamos para a seção de implantação e, após um a 2 minutos, podemos ver que está sendo implantado e, no final, o servidor está sendo executado na porta Nossa porta, que significa que nosso código foi atualizado com sucesso Você pode ver que o processo de implantação é muito simples e fácil. Basta fazer o upload do seu código no repositório Github e , usando a renderização, implantaremos nosso aplicativo rapidamente E se quisermos atualizar nosso aplicativo, basta enviar as alterações no Github e, em dois a 3 minutos, nosso servidor será reiniciado e receberemos nossas atualizações 211. O que é a arquitetura MVC? [BBONNUS]: Agora, se você está trabalhando como desenvolvedor , com certeza já ouviu falar sobre a arquitetura MVC em grandes projetos Então, vamos ver o que é a arquitetura MVC e por que precisamos dela. Então, MVC significa controlador de visualização de modelo. Basicamente, é uma forma de organizar o núcleo do nosso aplicativo. Portanto, no futuro, será muito mais fácil gerenciar, manter e escalar o aplicativo. Em palavras simples, é uma estrutura de pastas que separa diferentes partes do nosso aplicativo Na arquitetura MVC, criamos três pastas separadas. Um para modelo, segundo para visualização e terceiro para controlador. Não se confunda. É muito simples. Portanto, a pasta do modelo é onde nossos dados residem. Aqui, temos que definir como os dados devem ser estruturados e como interagir com seu banco de dados. Por exemplo, no aplicativo Node, já criamos a pasta models e armazenamos todos os modelos e esquemas de cada coleção Mongo be, e é por isso que chamamos essa pasta Em seguida, temos a pasta de visualização. Visualizar significa o que o usuário vê. É a parte da interface do usuário do nosso aplicativo. Por exemplo, no aplicativo Node, podemos ter mecanismos de modelo como EJS ou PUG ou temos arquivos SDML ou CSS, que queremos exibir Portanto, se tivermos código relacionado ao front-end , podemos armazenar esse código na pasta de visualização. Agora, finalmente, temos a pasta do controlador. Na pasta Controller, armazenaremos a lógica do nosso aplicativo. Por exemplo, se abrirmos a rota do nosso usuário, aqui podemos ver que essa é a função de retorno de chamada do ASN, que é executada quando alguém envia solicitação de postagem nesse endpoint Essa é a parte lógica. Na pasta do Controller, armazenaremos as funções do ASN separadamente e, em seguida, apenas as importaremos aqui nas rotas Não se preocupe, basta recortar e colar essas funções. Veremos isso em apenas um minuto. Aqui, entendemos o modelo MVC para dados, visualização de coisas relacionadas à interface e o controlador para a lógica do aplicativo Mas você pode perguntar: qual é o objetivo dessa arquitetura MVC Por que grandes empresas gostam disso? Então, como sabemos, em grandes empresas, há grandes equipes trabalhando em um aplicativo. Se criarmos uma pasta separada para cada peça, como modelo , visualização e controlador, isso criará uma separação de interesses. Aqui, por separação, nosso código pode ser mais fácil de gerenciar. Suponha que uma equipe trabalhe nos recursos relacionados à postagem, segunda equipe trabalhe nos recursos relacionados ao pagamento e outra equipe trabalhe nos recursos relacionados ao usuário. Cada equipe não precisou tocar modelo de postagem, no arquivo do modelo de pagamento ou no arquivo do modelo do usuário. Eles trabalharão em seus recursos separados, e é por isso que, quando enviam código para o Github, isso não gera grandes conflitos Além disso, outro benefício do MVC é a facilidade de manutenção. Queremos atualizar o modelo, então não precisamos atualizar os arquivos de visualização. Outro benefício é que é muito mais fácil escalar. À medida que nosso aplicativo cresce, fica mais fácil adicionar novos recursos porque tudo já está bem organizado, e é por isso que grandes empresas e hoje em dia freelancers também baixam essa arquitetura MVC Agora, aqui está a estrutura de pastas para a arquitetura MVC no Node JS A primeira é a pasta principal do nosso projeto. Depois disso, adicionamos o arquivo JS de pontos de índice, que é nosso arquivo principal. Além disso, adicionamos outros arquivos ou pastas, como dot sn do pacote ou o arquivo dot ENV ou a pasta middleware, você fica aqui na Depois disso, adicionamos a pasta de modelos em todos os modelos que armazenamos. Em seguida, pasta para todos os arquivos relacionados à interface do usuário e, em seguida, pasta Controllers para toda a parte lógica, e no Node JS, temos a pasta routes Então, adicionaremos todas as rotas nessa pasta. Agora, essa estrutura de pastas é boa para projetos de pequeno ou médio porte, mas grandes empresas como Paypal e Netflix usam uma estrutura de pastas pouco diferente. Definitivamente, depende de você e da sua empresa a estrutura de pastas que você seleciona. Eu vou te mostrar as duas opções. Essa outra opção é um pouco diferente e é boa para aplicações Big Bend. Aqui estamos na pasta principal do projeto. Nisso, tínhamos o arquivo JS de pontos de índice, que é o principal ponto de entrada do nosso aplicativo. Além disso, nós da ENV files, package dot jCNFle Docker files e uploadedFles, e Depois disso, aqui adicionamos outra pasta chamada source ou SRC, onde podemos armazenar nossa pasta de middleware, pasta transmissão e pasta Utils , Além disso, na pasta SRC, armazenamos a pasta de módulos para cada módulo e, nessa pasta, podemos adicionar pastas para cada recurso, como pasta do usuário, pasta de postagem etc Em cada pasta, podemos definir três arquivos, user dot model dot gs user dot routes dot js e user dot controller dot js. Assim, podemos adicionar mais um arquivo user dot service dot js. Esse arquivo não é obrigatório, mas algumas empresas gostam de usá-lo Nesse arquivo de serviço, podemos armazenar a consulta do banco de dados. Não é obrigatório adicionar esse arquivo dot service dot js do usuário, mas algumas empresas gostam de adicioná-lo Assim, também podemos adicionar quatro arquivos para a pasta de postagem. Quando queremos adicionar um novo recurso, como produto, criamos a pasta produto aqui na pasta de módulos e, em seguida, podemos adicionar quatro arquivos na pasta do produto. Como podemos ver, isso é muito complexo, mas é muito bom para aplicações grandes e complexas. Você pode usar o que quiser. Depende totalmente de você. A estrutura de pastas pode ser um pouco diferente de empresa para empresa. Não se preocupe com isso. Agora, na próxima lição, aplicaremos a arquitetura MVC em nosso aplicativo e, em seguida, implantaremos essas alterações 212. Aplique a arquitetura de MVC [BBONNUS]: Agora, vamos aplicar a arquitetura MVC em nosso projeto Linky Fi Portanto, atualmente em nosso aplicativo, temos uma estrutura muito organizada, como se já tivéssemos a pasta de modelos e a pasta Routes. Aqui, não precisamos visualizar a pasta porque não há código de mecanismo de modelo. Portanto, precisamos fazer um pouco para gerenciá-lo. Então, vamos fazer isso. Primeiro de tudo, aqui criamos uma pasta chamada SRC. N S, como esta pasta de configuração, segure a tecla Control ou Command selecione-a até as pastas Stu Certifique-se de não mover essas pastas de módulos do Node. Bom. Agora vamos ver o que temos que mudar no arquivo JS de índice. Principalmente, temos que alterar as partes do arquivo de entrada. Veja, aqui temos esses caminhos iniciais. Temos que atualizá-lo. Aqui, criamos vários cursores pressionando alter ou option. E adicione aqui SRC, para ter certeza de que estamos recebendo esse arquivo ou não, deixe-me verificar removendo o nome do arquivo Veja aqui que estamos recebendo sugestões de arquivos, o que significa que está certo. Agora, não precisamos alterar nada no índice para o arquivo JS. Agora, na pasta SRC, já temos modelos e a pasta Routes Mas, como sabemos, aplicamos aqui. Estrutura complexa do aplicativo Node. Então, aqui, criamos uma nova pasta chamada modules. Nesta pasta de módulos, temos que criar principalmente quatro pastas porque aqui temos quatro modelos. Vamos criar a primeira pasta chamada Jet, depois outra pasta chamada message. Em seguida, outra pasta para postagem e última pasta para usuário. Agora lembre-se de que em cada pasta, temos que criar três arquivos. Então, vamos fazer isso. Primeiro, movemos o arquivo JS do usuário da pasta models e o fizemos na pasta do usuário. Aqui, renomeamos seu nome de arquivo para user dot model dot js. Aqui, ele pode solicitar entradas de atualização. Certifique-se de clicar em “Sim”. E se você não está recebendo esse menu, então você tem que fazer isso manualmente. Agora, vamos mover o arquivo dot js Route dos usuários da pasta routes e fazê-lo na pasta do módulo do usuário. Agora ele está solicitando uma atualização. Diga aqui para atualizar o nome do arquivo dot js Route do usuário. Agora vamos renomear esse arquivo para user dot routes dot js. Veja, agora ele não está pedindo atualização. Não se preocupe, atualizaremos isso manualmente. Agora, na pasta do módulo de usuário, criamos mais um arquivo chamado user dot controller dot js. Agora você pode perguntar o que adicionaremos no controlador. O controlador é onde armazenamos a lógica do nosso aplicativo. É uma coleção de funções de retorno de chamada de nossas APIs. Deixe-me te mostrar isso. Aqui na rota do usuário, primeiro registramos a API, e essa é sua função de retorno de chamada Esse é o controlador dessa rota. Corte essa função de retorno daqui e no arquivo do controlador, temos que exportar essa função Portanto, o usuário de registro do Cast é igual e superior a essa função de retorno de chamada aqui Agora, para exportar essa função, adicionamos exportações de módulo iguais ao objeto porque, a partir daqui, queremos exportar várias funções. Então, aqui podemos adicionar um usuário registrado para registrar um usuário, ou podemos remover isso. Salve esse arquivo e agora temos que adicionar essa função na rota do usuário. Então, na parte superior, adicionamos que o custo do controlador de usuário é igual ao necessário, aqui importamos do usuário dot forward slash do usuário dot Controller Agora, no lugar da API CallwayFunction, simplesmente adicionamos controlador de usuário, usuário de registro de pontos Certifique-se de não chamar essa função aqui, temos que adicionar uma referência de função. Agora vamos fazer o mesmo com outras APIs também. Então corte esse controlador de API de login. Em nosso arquivo, definimos uma nova função, custo do usuário de login é igual a colar o retorno de chamada aqui Em seguida, temos essa função de retorno de chamada da API. E em nosso arquivo de controlador, criamos uma nova função. Custo, obter usuário é igual a colá-lo aqui. Da mesma forma, temos que cortar cada função de retorno de chamada e separá-la no arquivo do controlador Eu sei que isso é um pouco preocupante, então coloque um pouco de música e podemos completar isso juntos Corte a função de retorno de chamada e, no arquivo, Custo, solicitação, redefinição de senha é igual a colá-la aqui Corte a próxima função de retorno de chamada e, no arquivo, Cast reset password é igual a colá-la aqui Corte a próxima função de retorno de chamada para seguir o usuário e, no arquivo, Cast, follow user é igual a colá-la aqui Agora corte a próxima função de retorno de chamada, para rejeição, solicitação. No arquivo, Transmitir, rejeitar, seguir, solicitar, é igual a colá-lo aqui. Agora recebi a próxima ColbkFunction para aceitar a solicitação e, no arquivo, o custo, exceto a solicitação de acompanhamento, é igual a colá-la aqui. Corte a próxima função de retorno de chamada, para a lista de seguidores, e no arquivo, const, get other user, follow, list, é igual a colá-la Não se preocupe, só nos restam alguns. Corte a próxima função de retorno de chamada, para a lista a seguir. E no arquivo, const, get other user, a lista a seguir é igual a colá-la aqui Corte a próxima função de retorno de chamada. E no arquivo, adicionamos o custo e seguimos que o usuário é igual a colá-lo aqui. Além disso, voltando ao arquivo de rota, precisamos dessa função geral Cs para a API de registro e login. Então, também cortamos toda essa função e a colamos no arquivo do controlador. Aqui, você pode ter atualizado função de geração de tokens para o token em excesso e de referência ao token. Aqui eu tenho meu código antigo porque essas são atualizações após a publicação do curso, mas não se preocupe, é o mesmo processo, recorte toda a função e dt no arquivo do controlador. Além disso, se você tiver uma rota de atualização e uma rota de desconexão, faça o mesmo com essas APIs Aqui, só precisamos exportar essas funções e adicioná-las ao arquivo Routes. Então, depois de registrar o usuário, adicionamos o usuário de login, obtemos a solicitação do usuário, redefinimos a senha, seguimos o usuário, rejeitamos, seguimos a solicitação, aceitamos, seguimos, solicitamos, obtemos outro usuário, seguimos a lista, obtemos outro usuário, lista de seguidores e o último usuário que deixa de seguir Salve esse arquivo e, em nosso arquivo de rota, adicionamos o usuário dot login do controlador EEUUser Não estou desestruturando as funções aqui porque, se alguns novos desenvolvedores visualizarem nosso código , eles poderão ficar confusos Agora, controlador de usuário dot god user, user Controller, dot request password reset, user controller dot reset password, user controller dot reset password, user Controller dot Followser user Controller, dot reject, follow, request, user Controller, dot accept, follow request Controlador de usuário, dot get user, follow list. Em seguida, controlador de usuário, ponto para obter outro usuário, lista de seguidores e, por último, controlador de usuário, ponto para deixar de seguir usuário Agora temos que importar as coisas necessárias para esses controladores Na parte superior, podemos ver todas as importações não utilizadas que são classificadas. Assim, podemos juntá-los movendo o molho para baixo e simplesmente cortar essas importações e colá-las na parte superior do arquivo do controlador. Bom. Agora, aqui, temos que atualizar o caminho do modelo do usuário, então o alteramos para o modelo de pontos do usuário com barra de ponto porque está na pasta atual Além disso, podemos garantir que esses caminhos estejam corretos. Sim, eles estão bem. Salve esse arquivo. E se verificarmos nosso arquivo de rota, veremos que parece muito limpo. Dessa forma, podemos ver claramente endpoints da API com os métodos da API Agora temos que fazer o mesmo com jatos e postes também. Vamos fazer isso rapidamente. Primeiro, movemos jet model na pasta jet Module e renomeamos o nome do arquivo para chat dot model dot js Vamos mover a rota do bate-papo na pasta de módulos de bate-papo e atualizar a entrada. Agora renomeie o nome do arquivo chat dot Rous dot js. Agora temos que criar um novo arquivo para chat dot controller dot js. Voltar ao arquivo Routes. Primeiro, cortamos esse primeiro retorno de chamada da API e, no arquivo do controlador, criamos uma nova função O custo de obter chats, é igual a colá-lo aqui. Depois disso, cortamos a próxima função de retorno de chamada e, no arquivo, Cast get chat messages equivale a colá-la aqui Em seguida, corte a próxima função de retorno de chamada e, no arquivo, custo, criar bate-papo é igual a colá-lo aqui seguir, não precisamos da API de envio de mensagens porque temos um identificador com o Socket Podemos remover esse bem agora temos a próxima função de retorno de chamada e, no arquivo, o custo de criação do grupo é igual a colá-lo aqui Agora temos que exportar essas funções daqui. No final, as exportações do módulo são iguais a Object, Gchat a GChat, então podemos remover as mensagens getchat, criar bate-papo e criar grupo Salve isso e, no arquivo de rota aqui, inserimos o custo, controlador de bate-papo é igual ao exigido aqui, controlador de pontos de bate-papo parlas Agora, em nossas APIs, adicionaremos essas funções Portanto, controlador de bate-papo, jatos Dot GAD, controlador de bate-papo, dot get messages, controlador de bate-papo, dot create chat e último controlador de chat dot Create Group Agora, cortamos essas importações de modelos daqui, salvamos esse arquivo e, em nosso arquivo de controlador, na parte superior, colamos. Bom. Agora, aqui, também temos que atualizar o caminho desses dois modelos. Portanto, alteramos o caminho do modelo de bate-papo para modelo de ponto de bate-papo com barra direta e, para a mensagem A, adicionaremos o modelo de mensagem na pasta Módulo de mensagem Então, vamos para o modelo de ponto de mensagem de barra de mensagem de uma pasta para cima. Salve este arquivo e teremos que mover o modelo de mensagem na pasta do módulo de mensagem. Agora altere o nome do arquivo para message dot model dot js. Agora, precisamos apenas fazer esse processo para nosso último módulo de postagem. Primeiro, movemos post Model na pasta post Module e renomeamos o nome do arquivo para post model dot js Agora vamos mover post route na pasta post Module, atualizar a entrada, renomear o nome do arquivo, post dot routes dot js Bom. Agora temos que criar um novo arquivo para os controladores post dot js Voltar ao arquivo Routes. Primeiro, cortamos o primeiro retorno de chamada da API e, no arquivo do controlador, criamos uma nova função Cast create post é igual a colá-lo aqui. Depois disso, recortamos ao lado função de callback e no arquivo Cast, get my post é igual a colá-lo aqui Em seguida, corte a próxima função de retorno de chamada. E no arquivo, Cs get following post é igual a postado aqui. Em seguida, cortamos outra função de retorno de chamada da API. E no arquivo, const, delete post é igual a, e cole aqui Não perca apenas as últimas funções que faltam. Corte a próxima função do Colbeg para curtir e não gostar E no arquivo, const, tipo, ao contrário de post é igual a, cole aqui Corte a próxima função Colbeg. E no arquivo, adicionamos custo, adicionamos comentário é igual a colá-lo aqui. Corte a próxima função de retorno de chamada. E, novamente, no arquivo, adicionamos custo, adicionamos comentário, respondemos é igual a colá-lo aqui. E agora, para a última função de retorno de chamada da API, recorte-a e, no arquivo do controlador, adicionamos o custo, excluímos o comentário, é igual a colá-lo aqui Agora temos que exportar essas funções. As exportações de pontos do módulo são iguais a in object, create post to create post, get my post. Uma postagem seguinte, exclua uma postagem, curta uma postagem, adicione um comentário, adicione uma resposta ao comentário e exclua o comando. Salve isso e, no arquivo de rotas de postagem na parte superior, adicionamos que o custo do controlador de postagem é igual ao controlador de postagem de barra lateral necessária Agora, em nossa API, podemos adicionar esses controladores, copiar post Controller e escrever, postcontroller, dot create post, postcontroller, dot GET myPost, post Controller, dot GET following Post, post Controller, dot GET following Post, post Controller, dot delete Post Controlador de postagem, ponto, ao contrário de postagem, controlador de postagem, comando de adição de pontos, controlador de postagem, resposta de comentário de adição de ponto e comentário atrasado por pontos do controlador de postagem. Bom. Agora vamos cortar as importações não utilizadas do arquivo Routes Salve esse arquivo e, no arquivo do controlador na parte superior, nós o colamos aqui. Agora, aqui, temos que atualizar esses dois caminhos, ponto final, modelo de pós-ponto com barra e, para o caminho do usuário, colocamos uma pasta para cima, pasta do usuário, modelo de ponto do usuário Salve isso como podemos ver, nossos arquivos parecem mais organizados. Então, aqui nossos modelos e pastas de rotas estão vazias agora, então podemos simplesmente excluí-los, e acho que temos que atualizar o caminho em mais um lugar, que é routes dot Jsle na pasta de inicialização Veja aqui o caminho não foi atualizado automaticamente. Então, aqui, simplesmente alteramos o caminho para módulos, usuário, barra, ponto do usuário, rotas Módulos publicam rotas post dot e módulos rotas JET Jett, e pronto Ótimo. Agora, vamos enviar rapidamente esse código para o Github. E com isso, nosso código pode ser implantado automaticamente. Então, abra o aplicativo de desktop Github. E aqui temos todas as mudanças. Escreva a mensagem de confirmação. E cometa isso. E, finalmente, simplesmente colocamos esse código no Github e pronto Isso será implantado automaticamente. É assim que, no mundo profissional, as grandes empresas gerenciam seu código sem JS. Além disso, pode haver uma abordagem um pouco diferente dependendo das empresas ou da equipe com a qual você trabalha, mas essa é a estrutura de pastas mais comum que os desenvolvedores profissionais usam atualmente.