Como sair do ZERO em Node.js em apenas UMA aula

162.13k views15630 WordsCopy TextShare
Rocketseat
FALTAM POUCOS DIAS para a oportunidade CONFIDENCIAL ser revelada: https://rseat.in/ENt90Atzj → G...
Video Transcript:
Fala dev! Meu nome é Diego Fernandes e hoje estou aqui para criar junto com vocês a sua primeira aplicação utilizando o Node.js. Vamos dar uma olhada no nosso cronograma. O que vamos fazer hoje? Hoje é um vídeo bem prático, então não vou explicar todos os fundamentos por trás ou por que escolhemos o Node.js, mas vamos direto para a prática, abrindo o terminal, o Visual Studio Code, e começando a criar nossa primeira aplicação com essa tecnologia. Vamos instalar o Node.js e configurar nosso ambiente de desenvolvimento. Vamos criar nosso primeiro servidor HTTP com essa tecnologia e depois
partir para a criação do nosso projeto prático utilizando o Fastify, o PostgreSQL e várias outras tecnologias legais. No final desta aula, seu projeto estará online, e também vou fornecer um roadmap de estudos para o Node.js, ou seja, coisas interessantes para você estudar daqui para frente. Além disso, no final desta aula, tenho um presente especial para você, apenas para aqueles que ficarem até o final. Vamos lá! Mais uma coisa, o que é o Node? Para completar nosso primeiro item do nosso roadmap, o Node nada mais é do que uma plataforma que permite executar JavaScript, uma linguagem
feita nativamente para ser executada no contexto de um navegador. Dentro do âmbito de um navegador, podemos usar JavaScript para construir aplicações. Aplicações que rodam no servidor geralmente são aquelas que interagem com bancos de dados, acessam APIs sensíveis, como APIs de pagamento e envio de e-mails, entre outras operações comuns em tecnologias como Java, PHP, Python, Ruby, entre outras. Com o Node, podemos utilizar a mesma tecnologia que usamos nos navegadores para manipular o DOM no backend e construir nossas aplicações. Isso é fantástico! Essa tecnologia foi desenvolvida por Ryan Dahl e deu vida a grandes coisas. Hoje, o
Node é usado não apenas para construir backends, mas também para automação de tarefas. Automação de tarefas envolve a execução de scripts que realizam processamentos, convertem dados de um formato para outro, geram builds de aplicações, ou seja, torna o Node uma ferramenta indispensável. Ele é usado por outras tecnologias, como o React, Angular e várias outras do frontend, para automatizar tarefas. O Node é uma tecnologia muito famosa no mundo do backend e oferece muitas oportunidades. Agora que entendemos o que é o Node, vamos direto para a instalação. Para isso, vou colocar minha câmera aqui ao lado. Abri
meu navegador e já estou no site do Node.js. A instalação não é complicada, como você pode ver. Existem várias formas de instalar o Node em nossa máquina. Recomendo que, em vez de simplesmente clicar na versão LTS (Long Term Support), você vá até a seção de downloads. Aqui, encontre o seu sistema operacional. Por exemplo, se você estiver no Windows... Você vai clicar aqui em Windows e aqui você vai ver que existe a opção de instalar o Node.js utilizando esse carinha aqui que é o Chocolatey. O Chocolatey é um gerenciador de pacotes, assim como o APT dentro
do Linux, por exemplo. No Mac, usamos o Homebrew, que também é um gerenciador de pacotes diferente de simplesmente baixar um executável na nossa aplicação. Isso permite que, futuramente, eu consiga atualizar a versão do Node de uma maneira mais fácil ou remover o Node caso esteja acontecendo algum problema. Ou seja, o gerenciador de pacotes cuida dessas instalações para a gente, para que não precisemos procurar em qual pasta foi instalado, o que tornaria uma dor de cabeça gigantesca. Ainda assim, se você estiver em um sistema como o Linux ou o Mac, eu recomendo muito que você dê
uma olhadinha no NVM, que é um gerenciador de versões para o Node, ou no N, que é o que eu uso aqui, que é esse carinha aqui, o tj/n. Esse carinha também é muito legal, pois são maneiras mais simples de você conseguir instalar várias versões do Node na sua máquina. Isso pode ser útil mais para frente, conforme você se profissionaliza, porque pode ser que existam projetos com versões diferentes rodando na sua máquina, todas com o Node instalado. Você deve conseguir vir aqui dentro do seu terminal e executar o "node -v" e ele vai mostrar a
versão atual do Node. Veja que tem que ser a versão LTS. Não precisa ser exatamente a minha. E ele vai instalar junto o npm. Se você conseguir executar um "npm -v" e ele mostrar alguma versão aqui, show de bola, a gente já está pronto para continuar. O npm é a biblioteca que vem instalada junto com o próprio Node. Como o nome sugere, é o Node Packet Manager, ou seja, o gerenciador de pacotes do Node. O que ele faz basicamente é permitir que a gente instale bibliotecas de terceiros dentro da nossa aplicação. Isso é importante porque
há muito código que a gente vai reutilizar, frameworks, e por aí vai, que a gente vai instalar. Toda biblioteca tem um package manager, seja lá no PHP com o Composer, no Ruby com o Gem, no Python com o Pip, e por aí vai. Aqui começamos a configuração do nosso ambiente de desenvolvimento. Vamos criar uma pasta chamada "node-do-zero" e vou entrar nessa pasta e abrir no Visual Studio Code. Durante toda a criação do nosso projeto, vou estar utilizando o Visual Studio Code, mas você pode usar o editor de sua preferência. Quanto à edição do meu editor
e do ambiente de desenvolvimento, como estamos vendo, não há muito segredo. O que mais recomendo é configurar um tema. Atualmente, estou utilizando o tema "Mimimal", como o próprio nome sugere, é bem minimalista, com poucas estilizações. Também gosto de usar a extensão "Material Icons", que coloca ícones diferentes quando criamos nossos arquivos, tornando-os mais visualmente agradáveis. Além disso, se você quiser copiar qualquer configuração que tenho no meu Visual Studio Code, basta acessar o site fala.dev e encontrar todas as configurações do meu Fast Code, extensões que utilizo, configurações do meu terminal e meu setup. Se tiver alguma dúvida
em relação a isso, é só acessar esse site e copiar as configurações. Outra extensão que recomendo é o ESLint. O ESLint é uma das ferramentas mais famosas do ecossistema JavaScript. Ele tem o objetivo de encontrar erros dentro do seu código, mas não são erros técnicos, são erros de padrões. Imagina que você está trabalhando em um time e várias pessoas têm diferentes preferências, uma pessoa gosta de colocar ponto e vírgula no final das linhas, outra não gosta. Algumas usam aspas simples, outras usam aspas duplas. O ESLint cria uma padronização para o seu projeto, e você pode
definir qual é esse padrão. Vamos fazer isso juntos sem problemas. Vamos lá, agora criar o nosso primeiro projeto com Node.js. Vou criar um arquivo chamado "server.js" aqui dentro. Com o Node instalado, já devemos conseguir importar o módulo "http" do Node.js. Uma das coisas importantes é que, quando instalo o Node na minha máquina, ele traz várias funcionalidades por padrão, como manipulação de arquivos (criação e leitura de arquivos), e por aí vai. Podemos importar isso com const fs = require('fs') se quisermos trabalhar com, por exemplo, a parte de criptografia. O Node também tem o "crypto". Se quisermos
trabalhar com a criação de servidores HTTP, como vou fazer agora, importamos do http. De dentro do http, consigo importar uma função chamada createServer. Essa função é a mais importante para começarmos a criar nosso servidor HTTP, que é um servidor acessado através do navegador. Vou começar criando meu servidor simplesmente fazendo: Server igual a Create server. Para essa função, passo como parâmetro uma função com req (request) e res (response). Essa função aqui como parâmetro permite que eu coloque um console.log dentro dela, por exemplo, "Oi". Após criar meu servidor, o server me devolve um método chamado listen. Posso
chamar esse método e passar uma porta para minha aplicação executar. A porta é basicamente o que usamos para acessar a aplicação através do navegador, como localhost ou o IP da máquina. Podemos informar uma porta, por exemplo, 3333, que é o que costumo usar. Agora, podemos executar nossa aplicação com node server.js. Vai dar erro porque estou tentando usar uma sintaxe de importação do Node.js, que é uma sintaxe um pouco mais recente. Para usar essa sintaxe, preciso criar um arquivo de configuração chamado "package.json". Posso usar o npm para isso com npm init -y, e ele vai criar
o package.json. Nele, posso informar o "type", que indica que quero usar a nova sintaxe de importações dentro do JavaScript, chamada ESM (ECMAScript Modules). Por enquanto, não mexeremos em mais nada. Agora, posso rodar node server.js, e nosso projeto já está em execução. Como sei que está em execução? Lembra que hospedei na porta 3333, então se acessar localhost:3333 no navegador, não carregará nada, mas no terminal, já apareceu "Oi", que é exatamente o que esperava. Dentro desse createServer, passamos uma função que pode receber dois parâmetros: request (req) e response (res). O request serve para obter dados da requisição
feita para o servidor HTTP. Por exemplo, se estivermos criando uma funcionalidade de criação de usuário, no request, buscaríamos os dados para criar esse usuário, como nome, e-mail e senha. O request traz informações da requisição sendo feita para a nossa API. Por outro lado, o response (res) é o objeto que usamos para enviar uma resposta para quem está chamando nossa API. Dentro do response, podemos usar o res.json() para enviar uma resposta no formato JSON, ou seja, estamos configurando como nosso servidor lida com as requisições e envia as respostas. E veja que ele tem vários métodos aqui
dentro. Por enquanto, vou usar apenas o método end. Aqui dentro, vou dar o console.log novamente. Agora, quando cancelo a execução da minha aplicação usando Ctrl+C e a executo novamente, e depois dou um F5 no navegador, a tela fica branca. Por que a tela ficou branca? Porque agora a requisição, aqui no final das contas, ela foi finalizada antes. Ela não ficou ali executando para sempre, e o "Oi" apareceu aqui sem problemas nenhum. Mas se eu quiser retornar um texto aqui dentro, eu também consigo. Veja que existem vários e vários métodos para eu utilizar aqui dentro desse
response, e um desses métodos que eu tenho aqui é o método write. O método write ele serve justamente para eu escrever algo na minha resposta. Então vamos testar ele. Eu vou aqui em cima no lugar onde eu tinha um "Oi" e vou dar um response.write("Oi"), salva aqui. Agora vamos cancelar e executar o meu servidor de novo. F5, e veja que agora dentro do navegador aparece "Oi" e ao mesmo tempo ele finalizou a requisição. Outra coisa um pouco chata aqui no Node é que eu tenho que ficar toda vez que eu faço uma alteração no código,
eu tenho que vir aqui e alterar o nosso cancelar e executar o nosso script de novo. Mas nas versões mais recentes do Node, eu posso executar a minha aplicação com uma Flag aqui, ó, traço traço watch, e automaticamente, agora toda vez que eu editar o meu arquivo, por exemplo, trocar aqui de "Oi" para "Hello, World" e salvar, veja que ele já faz um restart automático no meu servidor. Ou seja, basta eu voltar aqui e fazer a alteração, e ela foi feita automaticamente. E aí, a gente pode ver que quando eu executo isso, ó, ele fala
que isso aqui é uma feature experimental do Node. E aí, caso você não goste desse aviso, você pode vir aqui, ó, e só passar uma Flag no warnings. E aí pronto, ele já não mostra mais aquele rinho, né, de experimental. Outra coisa que eu gosto de fazer, que é muito legal, é como eu não quero ficar lembrando desse script aqui do zero toda vez, né, detalhe do zero, eu posso vir aqui no meu package.json, veja que aqui eu tenho um script chamado "vou trocar", e criar um novo aqui chamado "dev". E aí eu vou jogar
aquele script que eu acabei de executar ali no meu terminal. E agora, se eu voltar aqui dentro da minha aplicação e executar npm run dev, veja que ele vai executar esse script que eu acabei de criar, onde "dev" é exatamente o nome do script que eu criei aqui, e minha aplicação continua funcionando. Agora que a gente já criou o nosso primeiro servidor HTTP nativo, ou seja, usando nenhuma tipo de biblioteca externa, criando apenas com o Node, a gente não vai dar muita profundidade nisso, até porque ninguém cria um servidor nativo com Node em produção. Nenhuma
empresa, nenhum projeto roda dessa forma. Muito difícil. A gente vai criar um servidor, né, da maneira que geralmente as empresas queriam, que é utilizando um framework. O Framework, né, ele vai facilitar pra gente lidar com várias coisas, além de ele também ter essa estrutura de criação de um servidor. O Framework vai facilitar com que a gente consiga dividir o nosso servidor em várias rotas diferentes. Então, imagina que eu tô criando uma aplicação que ela gerencia vídeos. Então, eu quero ter uma rota que eu crio vídeos, por exemplo. Então, é uma rota que eu vou utilizar
o método HTTP POST, que é o método utilizado quando eu quero fazer a criação de um recurso. Eu posso ter um método de DELETE que eu quero deletar um vídeo. Então, o Framework, ele vai ajudar a gente, né, principalmente com essa parte de redirecionar dependendo do endereço que o usuário está acessando para funcionalidades diferentes da nossa aplicação. Fora isso, o Framework ajuda com muitas outras coisas, como integração com bibliotecas de terceiros para envios de e-mail, autenticação, pagamento, e por aí vai. Mas nem tudo a gente vai ver hoje. O Framework também facilita a gente trabalhar
com banco de dados, que é uma das coisas que a gente vai trabalhar daqui a pouco. Utilizando o banco de dados PostgreSQL, que, para mim, é o melhor banco de dados. Se você não sabe qual banco de dados você precisa utilizar, banco de dados PostgreSQL é o único banco de dados SQL verdadeiramente open source. O MySQL não é open source. É importante entender isso. Existe um fork do MySQL, que é o MariaDB. Esse sim é o open source. E eu recomendo, se você está iniciando no mundo do desenvolvimento backend, não utilizar um banco NoSQL, como
por exemplo o MongoDB, porque vai ser muito mais difícil, muito mais suscetível a erros. Eu recomendo altamente que você utilize um banco relacional, um banco SQL, e nesse caso, o PostgreSQL para construção das suas aplicações, principalmente nesse começo. E aí, o que que a gente vai fazer aqui agora, então? É começar instalando a nossa primeira dependência aqui dentro. E para isso, eu vou usar o npm install, e vou instalar o Fastify. O Fastify é o framework que a gente vai estar utilizando. Existem vários frameworks dentro do sistema do Node, mais para frente vou até falar
um pouquinho sobre eles. Existe o Express, que é um dos mais famosos, existe o Koa, o Hapi, o Restify, o Next, o Fastify, e por aí vai. Qual que é o grande ponto do Fastify? O Fastify, ele é um microframework. Então, se você veio lá do PHP, eu acho que existia o Lumen. Ruby existia, acho que é o Sinatra, não lembra. Exatamente, meu Python tem o Flask e o FastAPI. Bom, existe em cada linguagem o seu microframework. O microframework, qual que é a vantagem dele? Ele traz pouca opinião, ou seja, ele é um framework muito
pequeno que traz poucas funcionalidades, coisas que são essenciais em todas as aplicações. Para todo o resto, a gente fica livre para escolher. Ou seja, ele não é o framework que vai determinar como é a estrutura de pastas que a gente tem que seguir, ou qual que é a convenção de nomenclatura de arquivos. Ele não define nada disso, ele só traz algumas funcionalidades que são comuns em todas as aplicações. No nosso caso aqui, principalmente a parte de roteamento, que é o usuário acessar um endereço específico e ele direcionar para alguma parte da aplicação. E é isso,
ele não vai forçar que a gente siga qualquer tipo de convenção. Com o Fastify aqui instalado, a partir do comando npm install Fastify, a gente vai ver que o Node automaticamente criou um arquivo package-lock.json, que a gente nunca vai mexer, que é um sistema de cache que ele tem. E ele criou uma pasta node_modules. A pasta node_modules guarda todas as dependências que a gente instala no nosso projeto. Dentro do node_modules, eu vou encontrar o Fastify. Você pode se perguntar: "Pô, eu instalei o Fastify, por que tem uma cambada de outras pastas e extensões aqui dentro?".
Porque o próprio Fastify, se a gente for abrir ele aqui e vier no package.json dele, ele também tem um monte de dependências. Ou seja, uma dependência pode ter várias outras dependências e por aí vai, criando uma extensão gigante. Por isso que tem tanta coisa instalada ali dentro. Agora, a gente vai fazer a mesma coisa que a gente fez, vou até comentar o que a gente criou, porém agora usando o Fastify. Então, veja que a mesma coisa que a gente fez com o HTTP nativo seria da seguinte forma: eu vou importar de dentro do Fastify o
próprio Fastify, vou criar o meu servidor, e para criar o servidor, aqui é basicamente dessa forma. Não precisa fazer mais nada. E para ouvir uma porta, a mesma coisa, a gente vai usar aqui. Deixa eu ver certinho. Fastify, o que que eu tô fazendo de errado? Será que é com letra minúscula? Pode ser. Deixa eu ver se é dessa forma aqui. Agora sim. Eu tinha que importar com letra minúscula aqui dentro. Agora sim, né? E eu já tenho o método listen, e eu posso passar 3333. Só que aqui, ó, ele fala que o método listen,
na verdade, tá depreciado. A gente não é mais para utilizar o método listen no Fastify. A gente tem que usar agora o ah, não. Ao invés de usar a porta diretamente, a gente passa um objeto e aí manda a porta. Eu tava acostumado com outro modo. Mas as bibliotecas atualizam. Então, a gente tem que ir acompanhando, show! Só que agora a gente não tem nenhuma parte aqui onde a gente fala o "Hello World". O que que eu vou fazer aqui dentro? Eu vou criar uma rota, minha primeira rota aqui dentro da minha API. Então eu
vou falar aqui: quando o usuário chamar o endereço "Barra", ou seja, "/", que significa que ele não informou nada além de "localhost:3333", né? Então é o endereço raiz da minha aplicação. Eu vou executar esta função aqui. Esta função aqui, ela vai simplesmente retornar "Hello World". Mudou algumas coisinhas aqui dentro. Quando eu crio um servidor HTTP com Node tradicional, todas as rotas, todos os endereços que o usuário acessa da nossa API, sempre vão cair na mesma função, que é essa que eu tinha criado aqui em cima. E aí dentro dessa função, eu tenho que diferenciar a
rota. Com o Fastify, eu crio várias rotas diferentes. Então, eu posso ter a rota raiz, que é quando o usuário simplesmente acessa "localhost:3333". Posso criar uma rota "Hello", né, e aqui eu vou trocar o nome para "Hello Rocket City". E vou criar uma rota "Node", ou seja, vai estar "Hello Node.js", ou seja, três rotas diferentes. Ou seja, no Fastify, tem essa mudança aí. Salve isso aqui, agora vou rodar minha aplicação: npm run dev. Isso aqui não muda, veja, já tá executando. E agora, se eu volto no navegador, acesso logo a rota "/". Dá um F5.
Tá lá, "Hello World", que é exatamente o que foi retornado aqui. Só que agora, se eu venho aqui em cima, no endereço, e boto "/Hello", veja que ele já mostra, que é o que eu botei nessa rota aqui. Se eu boto "/Node", veja que ele mostra "Hello Node.js", que é o que eu botei nessa rota aqui. Ou seja, o Fastify faz exatamente isso: uma forma da gente separar nossa aplicação em várias rotas, em vários endereços, de acordo com o que o usuário tiver acessando. Agora que a gente já criou o nosso servidor com o Fastify,
a gente vai começar a trabalhar com uma das coisas que você mais vai ter que fazer quando você for trabalhar com APIs, que é o CRUD. Caso você não saiba, né, é uma sigla para Create, Read, Update, e Delete, ou seja, todas as operações básicas que a gente pode fazer em uma entidade na nossa aplicação. Então, por exemplo, se eu tiver construindo uma API que gerencia vídeos, né? Então, imagina que eu tô construindo o próximo YouTube ou o próximo Vimeo, eu preciso fazer upload de vídeos, ou seja, cadastrar vídeos, eu preciso listar vídeos, eu preciso
poder alterar vídeos, né, editar o título, a descrição, eu preciso poder deletar vídeos, quem sabe. Ou seja, a gente vai trabalhar com todas essas operações aqui dentro da nossa API e, claro, utilizando um banco de dados. A gente vai primeiro criar um banco de dados em memória, ou seja, sem instalar qualquer coisa na nossa máquina, PostgreSQL nem nada disso. E depois a gente vai utilizar um banco de dados. E aí eu vou te mostrar como que a gente pode fazer isso. E no final, a gente faz o deploy do nosso projeto. Bora lá, então. A
API que a gente vai criar aqui é uma API que gerencia vídeos, né? Como a gente já estava falando antes. Então, eu vou ter uma rota que ela cria vídeos, uma rota que lista os vídeos, uma que eu altero os vídeos, e uma que eu deleto os vídeos. E com isso, a gente vai aprender um pouquinho sobre tipos de parâmetros aqui, e informações que a gente pode enviar em cada requisição. Porque, né, existem dentro do protocolo HTTP, existem vários métodos. Os métodos são basicamente formas da gente diferenciar semanticamente, ou seja, de acordo com significado, as
ações que a gente faz numa API. Então, quando a gente usa o GET aqui dentro, a gente tá utilizando o método do HTTP GET, que ele é utilizado quando eu quero fazer uma operação na minha aplicação onde eu busco alguma informação. Então, geralmente a gente faz isso pra listagem, para obter o detalhe, né, de um vídeo, alguma coisa assim. Mas existem outros métodos também que a gente pode usar aqui no lugar do GET, como POST, por exemplo, que ele é utilizado para criação. Ou seja, quando eu quero criar um registro, então quando a gente for
criar o vídeo, o POST é para alteração, o DELETE é para deletar. E esses são os quatro mais famosos, mas existem outros, como por exemplo, o PUT, que a gente pode usar quando eu quero alterar apenas uma informação específica de um recurso e não todos os dados, né? Então, imagina que eu tô ali num vídeo e eu quero alterar se o vídeo é público ou privado, ou seja, eu tô alterando uma pequena informação do vídeo e não todos os dados do vídeo ao mesmo tempo, que seria mais no caso o PUT. Aqui existem vários, aqui
eu poderia botar o PATCH, por exemplo, mas a gente não vai falar sobre todos eles, tá? E aqui que a gente vai começar fazendo agora, então, é criar as nossas rotas. Então, vamos lá, primeiro eu vou ter uma rota onde eu posso criar um vídeo, então eu vou utilizar o POST, porque eu quero criar, e o endereço aqui vai ser "/vídeos", ou seja, quando eu chamar com o método POST a rota "localhost:3333/vídeos", eu vou estar criando um novo vídeo. E aí eu vou ter também uma rota do tipo GET, que é o mesmo endereço. Então,
veja uma coisa interessante: quando a gente cria uma API, eu posso ter o mesmo endereço, né, o mesmo recurso, que a gente chama com métodos HTTP diferentes. Isso não vai dar problema, são duas rotas totalmente diferentes. Eu vou ter uma rota para atualizar um vídeo, e aí, uma das coisas importantes é, quando eu vou atualizar um vídeo, eu vou sempre estar atualizando um único vídeo específico, e por isso, aqui na rota, a gente recebe, geralmente, o ID do vídeo que a gente quer atualizar. O ID, ou algum tipo de identificador único, né, mas geralmente o
ID. E esse ID, ele é identificado por algo que a gente chama de "route parameter". Ele é basicamente um parâmetro que é enviado aqui na rota. E a gente identifica ele aqui dentro do Fastify com dois pontos e o nome que a gente quer dar para ele, por exemplo, "id". E aqui, basicamente, agora, nossa rota entende que quando eu acessar "localhost:3333/vídeos" com o método GET, eu preciso enviar o ID do vídeo, "um", "dois", "três", por exemplo, se for um ID numérico ou qualquer coisa parecida. Legal, né? E por último, rota DELETE, mesma coisa, quando eu
quero deletar um vídeo, eu sempre vou estar deletando um vídeo específico, e por isso, eu preciso receber o ID aqui dentro. E aí, como eu falei anteriormente, a gente vai criar a nossa aplicação utilizando um banco de dados em memória no primeiro momento, e depois trocar para usar o PostgreSQL, que é um banco de dados em memória, né? O que é um banco de dados em memória? Banco de dados em memória é quando eu salvo uma informação aqui na memória da minha aplicação, ou seja, numa variável. Qual que é o ruim disso? Quando eu reiniciar
minha aplicação, todos os dados vão ser perdidos. A facilidade disso é que eu consigo testar muito mais rápido a minha aplicação e desenvolver a aplicação mais rápido, ou seja, em produção, é claro, né, quando a gente botar o nosso projeto online, é claro que a gente não vai usar bancos em memória, mas agora que a gente está só aprendendo a criar o projeto, não tem problema. Então, vou criar aqui dentro um arquivo chamado "DatabaseMemory.js" e aqui eu vou criar uma classe chamada "DatabaseMemory". E aqui é só uma forma da gente centralizar, digamos, né? Eu vou
criar uma classe só para eu colocar todas as funções ali dentro. Vou exportar essa classe daqui de dentro, porque assim, agora aqui dentro do meu projeto, eu consigo importar ela, né? Então, olha só, se eu passar aqui em cima import DatabaseMemory from './DatabaseMemory', passando o meu DatabaseMemory, eu consigo executar. Só que aqui eu preciso, nesse caso, colocar o ".js" aqui no final, tá? O Node, quando eu tô usando o ESM module aqui, ó, eu preciso passar a extensão do arquivo aqui dentro também. Feito isso, agora dentro do meu banco de dados, eu vou começar criando
uma chave privada aqui dentro, e por isso a cerquilha, ou seja, essa informação só vai ser visível por dentro dessa classe, onde ela vai armazenar os itens aqui. Eu vou até trocar o nome para "vídeos", são os vídeos do meu banco de dados em memória, e aí eu vou começar criando aqui alguns métodos para manusear esses vídeos. Então, vamos lá. Eu vou ter, primeiramente, um método chamado "Create". Esse método "Create" aqui, o que ele vai fazer, ele vai receber o vídeo e vai salvá-lo dentro aqui dos meus vídeos. Então, é videos.push(video) para eu colocar dentro
do array o vídeo. Show de bola. Vou ter um outro método, que é o "Update". O "Update", o que ele vai fazer, ele vai receber o ID do vídeo e precisa atualizar. Mas espera aí, porque agora se eu tenho um ID nos vídeos, seria melhor se esse meu banco de dados aqui tivesse uma forma de eu fazer algum tipo de relacionamento, né? Tá, o vídeo tem o ID, ou seja, tem uma estrutura de dados aqui dentro do JavaScript. Por isso que é importante a gente estudar um pouco sobre estruturas de dados. Além dessas estruturas de
dados convencionais, como objetos que a gente tem no JavaScript à primeira vista, existem duas estruturas de dados que eu particularmente adoro utilizar, que é o "Set" e o "Map". O "Set" ele é como se fosse um array no JavaScript, porém, o grande diferencial dele é que ele não aceita valores duplicados. Então, pode ser legal trabalhar com ele. O "Map" ele é como se fosse um objeto no JavaScript, mas ele tem algumas particularidades. Uma das coisas mais legais do Map é que ele tem uma API muito mais legal, ou seja, uma forma da gente trabalhar com
ele diferente do que a gente trabalha com objetos. Eu vou te mostrar como é que funciona isso. Olha só, ao invés de eu criar meu videos como simplesmente um array, eu vou criar ele como um "Map". E olha que interessante, quando eu cadastrar um vídeo aqui dentro, eu não vou simplesmente usar um push, né? Até porque o método push não existe dentro do "Map". Veja aqui dentro do "Map", eu tenho alguns outros métodos, como por exemplo o método "set", que serve para eu adicionar uma informação dentro do meu Map. Só que eu não vou simplesmente
só jogar a informação aqui dentro, porque o método "set" ele recebe dois parâmetros: a chave, que nesse caso vai ser o meu ID do vídeo, e o valor, ou seja, para este ID de vídeo, aqui estão as informações do vídeo. Então, o que que eu vou fazer? Olha que interessante, quando eu criar um vídeo aqui no meu banco de dados em memória, eu vou gerar um ID para ele aleatório. E para isso, eu posso utilizar um método que vem de dentro do módulo "crypto" aqui do Node. E aí, eu gosto de prefixar assim os módulos
do Node, é opcional, mas eu gosto, que é o randomUUID. Nunca lembra a ordem, mas basicamente é um ID único universal, ou seja, isso aqui sempre vai me retornar um ID único mesmo. E agora eu posso simplesmente falar que este vídeo com este ID aqui é esse vídeo que eu estou recebendo aqui em cima. Beleza? Por enquanto, a gente não tá fazendo qualquer tipo de validação aqui, não é o foco, mas eu poderia fazer um pouco de validação para ver se esse vídeo que eu tô recebendo aqui tem as informações que eu entenderia que ele
tivesse, mas vamos continuar. Agora, no "Update", é muito mais fácil. Veja aqui, eu vou simplesmente utilizar novamente o método "set". E agora, como eu já tenho o ID, eu não vou criar um ID novo, eu só venho aqui e uso ele para substituir o valor que está lá dentro do meu Map. Dentro do "Delete", eu vou receber apenas o ID, porque para deletar não preciso saber as informações do vídeo, e vou usar o método "delete" aqui do nosso Map. Por último, para listagem, vou até criar aqui em cima, vou criar aqui um método chamado "list".
Ele não vai receber nenhum parâmetro, mais para frente a gente poderia receber, quem sabe, filtros, paginação ou qualquer coisa semelhante. E aí eu vou simplesmente retornar todos os vídeos. Só que eu quero apenas... Será que eu quero o ID dos vídeos também? Eu quero salvar o valor, né? Depende, a gente pode formatar isso da maneira que a gente quiser. Por enquanto, o que eu vou fazer, eu vou retornar somente os valores, ou seja, ele vai retornar todos os vídeos, porém sem os IDs, porque os IDs eles são as chaves e não os valores aqui do
meu map, tá? Então, vou simplesmente fazer dessa forma. Depois a gente pode ir alterando aqui para ver como é que fica, né? Legal, feito isso, nós já temos o nosso banco de dados aqui em memória, e agora a gente vai implementar as nossas rotas. Vamos começar com a nossa rota POST, né? Eu vou aqui dentro criar o nosso banco de dados, então vou chamar de Database igual ao new DatabaseMemory, e a gente vai começar a usar nossas funcionalidades. Então, vamos lá, dentro da rota POST, o que que eu quero fazer? Eu quero adicionar um novo
item. Por isso, eu vou chamar o Create, e aqui eu vou passar um objeto que é o meu vídeo, contendo as informações do vídeo. Por enquanto, vou passar informações fictícias, como por exemplo, o título do vídeo "01", uma descrição, "Esse é o vídeo 01", e quem sabe uma duração em número de segundos, vou estar aqui 3 minutos, ou seja, 180 segundos. O que acontece agora depois de ouvir aqui e adicionar esse vídeo na lista, se eu fizer um console.log aqui embaixo, listando os vídeos, eu devo conseguir ver esse vídeo que eu acabei de adicionar. Então,
vamos testar. Salvei aqui, meu servidor já tá rodando, mas agora, se eu tentar acessar a rota localhost:3333/videos, ou melhor, não é nem "localhost", é "http://localhost:3333/videos", o que que vai acontecer? Ele mostrou "Hello Rocket City". De onde está vindo isso aqui? Daqui de baixo, porque quando o navegador, ele... Quando eu acesso uma rota aqui pelo navegador, o navegador sempre utiliza o método GET para fazer a requisição. Ou seja, eu não consigo, pelo navegador, testar rotas que sejam POST ou DELETE, só rotas do tipo GET. Por isso, a gente vai ter que fazer nossas requisições aqui de
uma outra forma. E o que a gente vai fazer aqui no VSCode? Eu vou instalar uma extensão chamada "REST Client". Quero que você também instale essa extensão. Com essa extensão instalada, você vai criar um arquivo dentro do seu projeto chamado routes.http. O nome do arquivo tanto faz, desde que a extensão seja .http. E aí, aqui, a gente vai criar a nossa primeira rota. Olha só, eu vou escrever "post", porque é o nome do método, e o endereço HTTP, localhost:3333/videos. E agora, olha só, eu já consigo clicar em "Send Request", e ele vai enviar uma requisição
aqui para o meu servidor. Só que ele tá "waiting" aqui, ó, ele tá executando e nada acontece. Por quê? Porque dentro aqui, ó, da nossa requisição, faltou a gente retornar algo. Só que é muito comum dentro de uma API, quando a gente faz uma operação de criação ou de deleção, por exemplo, a gente não retornar nada, não retornar nada no corpo, porém, mesmo assim, a gente precisa devolver uma resposta para falar que aquilo lá finalizou, que terminou. Então, daqui de dentro, eu vou simplesmente dar um return. E aí, lembra que lá quando eu tava explicando
o servidor HTTP tradicional do Node, a gente podia acessar o request e o response? Aqui no Fastify, a gente também pode acessar. A gente pode acessar o request, e aqui ele não chama de response, é reply, mas é a mesma coisa. Se você quiser usar o "response", pode ser, eu só tô usando o padrão que o Fastify usa, tá? E aí, aqui dentro, a gente então vai retornar reply. e a gente vai ver que tem várias opções aqui dentro. Aqui, eu quero usar é o status. O que que isso aqui vai fazer? Eu consigo mudar
qual que é o status code retornado da minha rota. O que é o status code? O status code é uma forma de informar para o sistema que tá fazendo a chamada aqui da minha rota, né? Se for um frontend, por exemplo, que tá requisitando essa rota, qual que foi, digamos, o status? Se deu sucesso, não deu; se deu sucesso, qual o tipo de sucesso; se deu erro, qual tipo de erro, por aí vai. Então, aqui, ó, eu vou usar o status 201. O HTTP status code 201, ele significa que algo foi criado. Simples. E aí,
eu posso vir aqui e usar um método, por exemplo, E aí, pronto, eu acho que já vai dar certo dessa forma. Vamos testar aqui, beleza? Vamos voltar aqui no nosso "Routes," clicar em "Request," e veja que já deu certo. Então tá aqui, HTTP 201 Created, que foi exatamente o que eu retornei. E lembra que eu coloquei um console.log aqui para listar os dados do meu banco de dados. Se eu vier aqui no terminal, veja lá, o meu vídeo dentro do meu banco de dados, interessante, né? Então agora a gente já tá com a nossa primeira
rota. Deixa eu tirar esse console.log daqui de dentro. Ou seja, a gente já tá criando um vídeo, porém eu tô criando todos os vídeos com o mesmo título, mesma descrição e mesma duração, né? Isso aqui não é tão interessante. O certo é toda vez que eu faço uma requisição para o meu backend, eu envio dados diferentes. E para isso, a gente vai usar o request body, ou seja, toda vez que eu utilizo o método POST e PUT, principalmente, nesses dois métodos, no GET a gente não pode usar esse tipo de parâmetro aqui, é no POST
e no PUT que eu posso um corpo para a requisição. O corpo, geralmente, é onde a gente envia os dados de um formulário, por exemplo. Então, se eu tô fazendo uma inserção de um vídeo, eu vou enviar quais são os dados daquele vídeo que eu tô querendo inserir. Como é que a gente faz para acessar esses dados? Então, aqui de dentro, eu vou pegar body igual a request.body, que tá vindo aqui da minha requisição. Se eu der um console.log aqui nesse body e fizer uma requisição, a gente vai ver o que achou. Vou até abrir
meu terminal aqui, ó. Quando eu faço a requisição, ele vem vazio, porque eu não tô enviando nenhum corpo aqui na minha requisição. Agora, se eu der enter aqui embaixo, coloco um objeto, porque eu quero, como eu tô criando um vídeo, eu quero enviar os dados para essa API em formato convencional da web, que é o JSON, né? O JSON é o formato mundial de troca de informações entre frontend e qualquer outro sistema. E aí, eu vou enviar aqui, por exemplo, título: "vídeo 1". Veja que agora, quando eu dou "Send Request", ele media type, né? O
que que é isso aqui? Acontece que, quando eu faço uma requisição do meu frontend aqui para o backend, veja que ele não conseguiu ler esse formato de JSON, né? Então, o que que a gente vai ter que fazer? Quando eu faço uma requisição do frontend aqui para o backend, eu preciso falar para o backend qual que é o formato dos dados que eu estou enviando para o backend. Ou seja, se eu tô enviando um JSON, o frontend precisa falar: "Olha, o conteúdo, o tipo do conteúdo que eu tô te enviando é do tipo application/json." Esse
content-type aqui, eu estou enviando ele no cabeçalho da requisição. O cabeçalho são essas informações que eu posso tanto enviar na hora que eu tô fazendo uma requisição quanto também eu recebo na hora que eu estou recebendo uma resposta daquela requisição. São metadados da requisição. Metadados são, digamos, pensa assim, eu tô criando um vídeo, quais são as informações para criar o vídeo? Ah, é título, descrição, duração. Isso vai no corpo da requisição. Se eu precisar enviar alguma informação que não necessariamente tem a ver com o vídeo que eu tô querendo criar, mas que é importante para
aquela requisição, eu envio nos metadados. O que que eu posso enviar nos metadados? Geralmente, os sistemas utilizam os metadados, por exemplo, quando o sistema ele é multi-idioma. Então, imagina que o meu backend ele pode retornar um erro, né? Então, ele pode retornar: "Ah, o vídeo que você tá criando tem um título muito pequeno." Vamos supor. Só que essa mensagem de erro, ela precisa vir internacionalizada, né? De acordo com o país que o usuário está acessando. Então, a gente pode enviar um metadado, por exemplo, aqui nos cabeçalhos, falando: "Olha, qual que é o idioma, né? O
x-accept-language aqui do usuário." Eu envio Ah, é português, então o backend já sabe, né? Que ele precisa devolver a mensagem em português. Então, assim, os metadados, eles são essas configurações, digamos assim, que a gente pode fazer na requisição, mas show. Feito isso, quando eu vou enviar a requisição agora, veja que o nosso console logo lá dentro já mostra o título aqui do vídeo, e eu posso enviar mais dados. Então, descrição é "esse é o primeiro vídeo," por exemplo, e posso enviar aqui a minha duração, 180 segundos. Veja que, se eu dou um "request," aparece tudo
aqui dentro. E agora, como a gente está enviando essas três informações, title, description, e duration, a gente pode vir aqui de dentro do nosso body e fazer uma desestruturação para pegar eles. Então, agora, ao invés de criar o vídeo com esses dados fictícios, eu só venho aqui e falo: a informação title é o meu title que eu tenho aqui em cima, o description é o description que eu tenho aqui em cima que veio do body, e a duration, a mesma coisa. No JavaScript, quando o nome né da chave do objeto é igual ao nome que
eu tô passando para o valor, ó, tá vendo? title é igual title, description é igual description. Eu posso fazer só assim, ó, isso aqui. Opa, só assim, ó. A gente chama isso aqui de short syntax no JavaScript, então fica mais legal, né? Salva aqui. Agora, volto na minha rota, dou um Send, e a gente pode ver que veio 201, ou seja, foi criado com sucesso. Mas eu não consigo ver se deu tudo certo, porque eu não tenho hoje uma rota para listar os meus vídeos. Então, aqui no server.get("/vídeos"), eu vou fazer o seguinte: const vídeos,
né? Sendo que a rota para listagem igual é database.leste, ou seja, quero listar todos os vídeos, e aqui eu vou dar um return replay. O status já é o padrão 200. Então, nesse caso, não preciso colocar ele. O padrão de todas as requisições que dão sucesso é 200, e aqui eu dou um, ou melhor, faltou pegar o replay aqui, né? Então, request.replay, e aí, replay.send. Eu posso dar o send ou, no caso, quando eu só quero retornar alguma coisa de dentro de uma rota sem mudar o status, nem nada, eu posso só retornar aquilo diretamente.
Então, não preciso nem pegar o request.replay e dar return direto nos vídeos. Posso fazer isso aqui, vai funcionar, o Fastify vai tratar isso pra gente. Agora, para testar isso aqui, eu posso vir aqui no meu "routes.http", colocar três cerquilhas aqui, e aí, ele copio a rota que eu tinha usado aqui de cima e colo ela aqui embaixo. Agora, eu tenho duas requisições. Ou seja, isso aqui, ó, separa as requisições. Vou usar o método GET agora, não POST, né? Como eu não tô enviando o corpo na requisição, não preciso do content-type, e não preciso desse objeto
aqui embaixo. É muito simples, a rota fica agora. Vem aqui, dá Send, e veja que ele me trouxe um objeto vazio, porque toda vez que eu altero alguma coisa no meu servidor, o meu servidor reinicia, e com isso, toda a memória é limpa. Ou seja, eu sempre vou perder os dados no meu banco de dados. Então, vou criar um novo vídeo, e agora eu vou listar, e veja que agora ele não trouxe os vídeos. Vamos entender o que tá acontecendo aqui, né? Vamos dar um console.log nesses vídeos. Entendeu o que que tá sendo retornado? Então,
vamos lá. Criar primeiro, listar, e veja que, no console.log, ele tá trazendo só, tá vendo que ele trouxe aqui esse MapIterator, né? Ou seja, o que que acontece aqui de dentro do meu método last? Eu tô utilizando o método values para retornar os vídeos. Só que isso aqui me retorna, não me retorna uma array, ele me retorna uma classe aqui, ó, sei lá das contas. Então, o que que eu vou fazer? Eu vou só encapsular, e quando eu digo encapsular, é colocar isso aqui dentro da execução de uma função, que é a Array.from. Esse Array.from
ele converte uma estrutura de dados que não é uma array para uma array. Então, isso aqui, ó, se eu salvar aqui, agora, vamos voltar lá nas rotas. Eu crio o vídeo, e depois listo os vídeos. Agora, sim. Veja que ele me trouxe o vídeo que eu recém criei. Legal, né? Agora, o que que a gente vai fazer? Vamos criar as demais rotas aqui na nossa aplicação. Então, deixa eu fechar aqui dentro. A gente vem para rota PUT, e a rota PUT, diferente das outras que a gente já criou, ela tem uma informação adicional, que é
o ID do vídeo que eu quero alterar. Para pegar esse ID, basta eu acessar params ponto e o nome do parâmetro, nesse caso, id, que é exatamente o nome que eu coloquei aqui em cima, ou seja, dentro de params, eu consigo acessar todos os parâmetros que vêm aqui na rota com esses dois pontos. E agora, o que que eu posso fazer? const vídeo = database.update... E aí, eu quero atualizar o vídeo que tem este ID aqui, e aí preciso passar para ele as informações que eu quero atualizar, ou seja, o PUT é bem parecido com
o POST porque ele também vai precisar receber no corpo da requisição as informações que eu quero atualizar daquele recurso. Então vou copiar essa linha aqui do request e colocar aqui embaixo. Veja que agora eu também tenho title, description, e duration aqui dentro, e aí eu passo aqui dentro do nosso update. E no caso do update, eu também não preciso retornar uma resposta, mas é legal eu retornar um status code diferente. Olha só, eu vou pegar o reply aqui e aqui agora eu vou dar um return, reply.status, e eu vou usar o status code 204. O
204 significa uma resposta que teve sucesso, mas que ela não tem conteúdo na resposta. Ou seja, eu tô retornando uma resposta vazia, e aí eu uso o send só para finalizar aqui a requisição. Esse vídeo, como eu não tô usando ele aqui, ó, só remover e pronto, método PUT finalizado. Vou fazer o seguinte, vou novamente colocar três cerquilhas aqui, e eu vou copiar essa nossa primeira rota aqui que é o POST. Vou botar aqui embaixo, trocar o método para PUT, e agora, para conseguir atualizar um vídeo, eu preciso ter um ID do vídeo que eu
quero atualizar. Ou seja, isso aqui hoje é um problema porque o meu banco de dados, né, ele não tá mostrando aqui em nenhum momento o ID do vídeo, nem na listagem. Então, a gente vai mudar aqui um pouquinho a estrutura de listagem dos vídeos. Ao invés de eu retornar aqui na listagem somente o título, descrição, e duração do vídeo, eu quero retornar o ID também. Como é que a gente faz isso, né? Eu vou primeiramente fazer o seguinte. Olha só, eu vou, ao invés de usar o values aqui dentro, eu vou usar o entries. Vou
até te mostrar o formato que ele retorna quando eu cadastro um vídeo, e agora, quando eu for listar, tá, olha só. O entries agora ele traz o ID do vídeo junto, mas ele traz isso separado do restante das informações do vídeo, ou seja, antes ele me retornava, quando eu usei o values, apenas um array com vários desses aqui dentro, com vários objetos contendo as informações do vídeo. Agora ele me retorna um array com vários arrays dentro, olha aqui, diferente, né? Onde cada um desses arrays aqui, ó, representa um vídeo, onde a primeira chave do array
é o ID, e a segunda é o restante das informações. E por que isso é importante para mim? Porque agora eu posso fazer o seguinte. Como isso aqui tá me retornando um array com vários arrays, quando eu nem falei, eu posso usar um método map que serve para eu percorrer um array e fazer algum tipo de modificação. E aí, dentro desse map aqui, ó, eu vou receber cada um destes carinhas aqui, ó. Então eu vou chamar ele de vídeoArray, como eu falei, dentro do vídeoArray, na primeira posição, eu tenho o ID. Então, o ID tá
dentro de vídeoArray na primeira posição, e o restante das informações do vídeo tá dentro de vídeoArray na primeira posição, né, que no caso é na segunda, né, que no caso o JavaScript começa sempre em zero. E agora, eu vou fazer o seguinte. Vou retornar daqui de dentro um objeto contendo o ID do vídeo e todas as demais informações. Ou seja, eu quero esse objeto aqui, ó, ele é exatamente este objeto aqui, ou seja, eu quero copiar os dados desse objeto para dentro deste novo objeto que eu tô retornando. Tem várias formas, a mais simples para
mim, ponto a ponto. Ou seja, usando o spread. Salve isso aqui. Agora, veja que quando eu volto, agora eu crio um vídeo, volto para listar os vídeos, olha lá, agora eu tenho o ID dos vídeos junto com as demais informações. Legal, né? E agora eu posso testar o método PUT. Então, vou copiar o vídeo, o ID, né, coloco aqui no final da rota, e agora eu vou trocar o título do vídeo para "vídeo 2". Vem aqui e, don, "send". Já deu 204, que quer dizer que deu sucesso. Venho na listagem de novo, e tá lá,
o título mudou para "vídeo 2". Legal, né? A gente vai voltar agora no nosso server para fazer a nossa última rota que é a de delete. O delete, eu também preciso pegar o vídeo que a gente quer deletar do request.params.id, e vou fazer o database.delete no nosso vídeo e, por fim, retorno uma resposta em branco. Para isso, vou também pegar o reply aqui e fazer um reply.status(204), que é uma resposta de sucesso, porém em branco, e send para ele finalizar aqui, entender que acabou. Bora testar agora. Tenho nas minhas rotas: envio, criei o vídeo, visto
já tá aqui, copio o ID, venho aqui, coloco três cerquilhas para criar mais uma rota e escrevemos "delete". http://localhost:3333/videos/{ID} do vídeo que a gente acabou de copiar aqui do lado. Feito isso, clico em "Send" e já retornou 204, ou seja, sucesso. Listo os vídeos de novo, e o vídeo já não existe mais no nosso banco de dados em memória. Então, a gente finalizou toda parte, entendeu o que que é o request body, entendeu o que que é o "params" aqui, e faltou só mais um tipo de parâmetro aqui, que é o "query params", que a
gente vai falar bem rapidamente sobre ele agora antes de a gente seguir. Então, a gente entendeu aqui as diferentes formas que a gente tem de enviar dados da nossa requisição para dentro do nosso backend. Uma das formas é o corpo da requisição, que é usado geralmente para enviar esses dados quando eu tô criando um registro ou atualizando um registro. Tem os parâmetros na rota, que é geralmente utilizado para identificar um recurso na hora de atualizar ou deletar, e esses parâmetros sempre são obrigatórios naquela rota, isso é super importante. E o último método que a gente
não falou aqui são os "query params". Tem formas diferentes de falar esses parâmetros. Eles são utilizados para a gente identificar informações que são opcionais e geralmente utilizadas para filtrar os dados ou fazer algum tipo de paginação. Então, esses são geralmente utilizados em rotas de listagem de dados para a gente fazer algum tipo de busca, filtro, paginação, ordenação, ou seja, uma forma de modificar o retorno dado pelo backend, mas não são parâmetros obrigatórios, são só caso a gente queira enviar. Então, olha só o que que eu vou fazer aqui na rota que eu tô listando todos
os vídeos. Que hoje ela literalmente retorna todos os vídeos, eu vou enviar aqui no final da rota um ponto de interrogação e enviar para ela o seguinte: search. E aí, mandar uma busca, por exemplo, eu quero procurar por vídeos que tenham a palavra "node". E aí agora eu vou salvar. A gente vem lá no nosso servidor, e aqui dentro no get, eu vou fazer o seguinte: de dentro do meu request, eu quero buscar os meus "query params". E agora, se eu dou um console.log nesse search aqui, salvo, volto aqui na rota, venho aqui, envio a
minha requisição, veja que lá no meu terminal mostrou aqui, ó. Tá vendo? Só que eu posso pegar um "query param" específico, então eu dou um ponto aqui dentro. Ele retorna. Deixa eu ver se eu consigo buscar diretamente o search dessa forma aqui, não lembro se não faz dessa forma. E ele trouxe somente "node", lembra? Então agora eu quero fazer o seguinte: esse método list que tem aqui no nosso banco de dados, eu vou fazer com que ele possa receber um parâmetro que é opcional, chamado "search", beleza? E aqui, eu vou fazer o seguinte: dentro aqui,
antes do meu map, lembra que eu tenho um map aqui, ou pode ser no final, pode ser no final de tudo aqui, ó. Eu vou realizar... Vou até quebrar as linhas para ficar um pouquinho mais fácil. Aqui é o nosso map, então, que ele converte o formato dos dados. E agora, eu vou ter um filter. O filter ele vai receber cada um dos vídeos, e eu vou fazer o seguinte: se eu tiver uma busca, eu quero retornar somente os vídeos em que o título inclui a palavra que foi escrita aqui dentro de "search". Opa, aqui
escrevi "vídeos", tem que ser "vídeo". Se não tiver uma busca, normal, retorna todos os vídeos. Então, o método filter ele espera que retorne de dentro dele um true, caso eu queira manter aquele vídeo dentro da listagem, ou seja, não queira retirar, e false, caso eu queira retirar aquele vídeo, ou seja, se tiver uma busca, eu vou retornar true ou false, se o vídeo tem aquela busca dentro do seu título ou não. Se eu não tiver fazendo uma busca, eu não quero filtrar nada, eu quero retornar todos os vídeos. Por isso, eu dou um true aqui
para retornar tudo. Salvo isso aqui. Agora, a gente vai enviar a busca aqui para dentro da listagem. Lembrando que ela é opcional, certo? Salva aqui. Agora, voltamos na rota. E olha lá, eu vou criar o vídeo um e vou criar o vídeo "note". Botar aqui nessa forma. Perfeito. Ou seja, se eu vier aqui, ele está todos os vídeos sem enviar o search. Veja que agora ele lista todos os vídeos. Se eu coloco o search como "note" e dou o envio da requisição, ele retorna somente o vídeo "note". Ou seja, os query params são utilizados para
a gente fazer algum tipo de filtragem, ordenação, paginação e por aí vai. E aí, gente, também já finalizou o nosso banco de dados em memória, e por último agora a gente vai integrar essa nossa aplicação com um banco de dados real, usando um banco de dados que é o que provavelmente você vai utilizar no seu dia a dia. E depois, a gente vai fazer o deploy desse projeto, para aí a gente falar sobre o nosso Roadmap de estudos, aí que eu recomendo você seguir dentro do ecossistema. Beleza? Bora lá. Pra gente usar o Postgres aqui
dentro da nossa aplicação, a gente precisa de um banco de dados, e esse banco de dados você pode executar de qualquer forma. Talvez se você já é um usuário um pouco mais avançado, você queira executar o Postgres na sua máquina, utilizando um Docker, por exemplo, ou qualquer outra estratégia. Como eu quero democratizar o acesso ao Postgres com isso, para todo mundo, eu vou utilizar um serviço online chamado "ElephantSQL". Você pode acessar o site "elephantsql.com". Ele tem um plano gratuito que você não precisa colocar cartão de crédito, nem nada disso. Então, aqui em "Pricing", você vai
ver que esse é o plano gratuito dele, que tem 1 GB de RAM e até 3 GB de dados. Isso é bastante para a grande maioria dos projetos, tá? E você pode clicar aqui em "Get Started" e criar sua conta sem pedir cartão. Aqui, você vai ver que eu já tenho alguns projetos, mas eu vou criar um projeto novo com você. Então, clicando aqui em "New Project", você vai selecionar a versão. Pode deixar a versão que ele traz selecionada por padrão. Na região, pode deixar a região que ele traz selecionada para o padrão, também. Não
é um problema. Aqui, pra gente, e eu vou botar o nome aqui do nosso projeto. Aqui, eu vou botar "NovoDoZero". Você pode colocar o nome do seu projeto. E aí, vou criar o projeto. E pronto, ele já dá uma URL aqui para a gente fazer a conexão. Aqui do lado, ele traz também várias formas de fazer a conexão com esse banco de dados. Se eu clicar aqui em "Libs", ele vai trazer formato de conexão aqui usando a lib "pg-promise". Só que a gente não vai usar essa biblioteca em si. A gente vai utilizar outra biblioteca,
que na verdade é essa biblioteca sim. Então, é isso. A gente vai usar essa lib, eu achei que era possível no JS, mas o nome da biblioteca é fechado. A gente vai copiar, então, aqui, em instalação. npm install postgres. Agora, sim, eles botaram esse dólar junto, que eu acabei copiando junto aqui. Feito isso, a gente vai criar agora um arquivo aqui dentro, chamado "sql" ou, melhor, chamar de "db.js". Tanto faz o nome, no final das contas, né? Só estou seguindo aqui a documentação. E aí, a gente vai copiar essas linhas aqui dentro, colocar aqui, e
beleza. Aqui, como bem pode ver, eu posso passar algumas configurações aqui dentro. E essas configurações, eu tenho alguns dados aqui para fazer a conexão, na nossa no nosso Postgres. Aqui, se eu não me engano, ele tem um exemplo aqui dentro do Elephant de conexão, e é isso que a gente vai fazer. Então, olha só. Eu vou vir aqui dentro, e aí, uma das coisas que é super importante a gente aprender, isso aqui vai ser um bônus, né, é que dentro de aplicações também, mas backend principalmente, a gente tem um conceito, né, que a gente usa,
que a gente chama de variáveis de ambiente. Variáveis de ambiente são variáveis, geralmente, que são segredos, que são "secrets". Ou seja, são credenciais sensíveis, como, por exemplo, acesso ao banco de dados, e principalmente variáveis que a gente quer que sejam diferentes enquanto a minha aplicação está em desenvolvimento e quando ela está em produção, né? Por exemplo, banco de dados, quando eu estiver desenvolvendo a minha aplicação, provavelmente eu vou estar usando uma quantidade ali, todo zoado, cheio de registros bestas, né? É um banco de dados para desenvolvimento. Quando eu coloco minha aplicação em produção online, já
é outro banco de dados, ou seja, está vendo como eu tenho que ter uma conexão diferente com o banco de dados se meu projeto estiver rodando em produção ou desenvolvimento. Ou seja, a gente configura isso com variáveis de ambiente. Como é que a gente faz isso, né? Na maioria dos projetos, a gente vem aqui, cria um arquivo chamado ".env". E aí, para esse arquivo aqui dentro do VS Code, ele ter a sintaxe, Lite ali, eu acho que tem que instalar essa extensão aqui, ó, chamada "dotenv". E aí, esse arquivo aqui, ó, você vai colocar as
variáveis que você quer que sejam diferentes em cada ambiente. E aí, eu vou fazer o seguinte: vou copiar aqui, ó, todas as variáveis que o Neon traz para mim. Então é o PGHOST, PGDATABASE, PGUSER, PGPASSWORD, e PGPORT. Então você vai copiar essas variáveis ali do seu banco de dados, caso você esteja rodando o seu banco de dados local. Você também vai ter todas essas variáveis aí, né? Só vai mudar que você não vai ter só esse endpoint aí, que tá o resto tudo é host, tudo certinho, né? E aí, agora, a gente vai fazer o
seguinte: nós vamos instalar uma biblioteca aqui dentro do Node, chamada "dotenv". E essa biblioteca, ela é uma biblioteca temporária, porque o Node está incluindo na sua versão 20, mas ainda não é a versão LTS, que é a versão de suporte longo, suporte, né? Na versão 20, eles estão incluindo o acesso a variáveis de ambiente de forma nativa, sem instalação de qualquer biblioteca. Mas como ainda estamos na versão 18 aqui, não, infelizmente, não posso usar essa funcionalidade aqui no "db.js". Agora que eu já instalei aquele "dotenv" ali, né, que é o arquivo que lê as variáveis
ambiente, eu vou aqui no topo de tudo, ó, importar dotenv/config. Isso aqui que ele vai fazer, ele vai abrir o arquivo ".env", vai ler todas essas variáveis ambiente e vai salvar para gente numa variável global do Node, chamada process.env. Dentro dessa variável process.env, vai estar cada uma dessas variáveis ambiente que a gente configurou aqui dentro. Então, se eu vier aqui, e dou um console.log, a gente vai visualizar, mas não precisa nem fazer isso. E agora, o que que eu vou fazer? Eu vou copiar todas essas linhas aqui, ó, da parte de conexão do banco de
dados, e colocar aqui embaixo. Veja que esse arquivo, o que que ele faz? Ele lê host, database, aqui, as variáveis que eu criei. E aí, ele cria uma URL de conexão. Essa URL de conexão é basicamente a URL para eu conseguir acessar o meu banco de dados. E por que tudo isso aqui é importante a gente fazer? Porque, dessa forma, a gente vai, também, caso você queira utilizar o Git aqui no seu projeto, eu vou criar um arquivo ".gitignore" e vou colocar aqui dentro "node_modules/" e ".env". Isso aqui vai evitar que, quando você coloque o
seu projeto no GitHub, no GitLab ou qualquer outro local de repositório, esses arquivos subam junto com seu código. Ou seja, as informações, as credenciais de banco de dados da sua aplicação, elas vão ficar seguras, assim, ninguém vai acessar o seu banco ali indevidamente. Então, esse aqui é super importante. Com essa variável SQL, o que vou fazer é exportar essa variável daqui de dentro e agora a gente consegue usar essa variável aqui para fazer queries no nosso banco de dados. Mas antes da gente fazer queries no nosso banco de dados, a gente precisa criar a nossa
tabela. Porque se eu vier aqui no Neon e clicar em "tables," eu vou ver que não tem nenhuma tabela criada no meu banco de dados. Como eu acho chato para caramba criar tabela no banco de dados, o que que eu vou fazer? Pedir ajuda para o nosso amigo ChatGPT. Eu tenho só uma aplicaçãozinha aqui que ele é uma interface diferente pro ChatGPT. Mas você pode acessar o ChatGPT na sua máquina ou copiar o meu comando e eu vou pedir para ele o seguinte: a criação da tabela "vídeos." Aguardar aqui um pouquinho e pronto, ele já
traz para a gente o nosso "CREATE TABLE." A única diferença é que ele botou o "varchar" como um intervalo, né? Então, é "varchar(1)" no lugar. Eu já tenho o meu "CREATE TABLE" e agora eu posso fazer de duas formas. Posso vir aqui dentro do Neon SQL Editor e rodar aqui para criar a tabela, ou eu posso criar um arquivo que vai criar a tabela para mim. Então, vou criar "create-table.js". E aí, o que esse arquivo vai fazer? Eu vou importar de dentro do meu arquivo "db.js" aquele SQL que a gente tinha lá. E aí, vou
simplesmente rodar esse SQL. O que ele faz? Ele é basicamente uma função que funciona com uma funcionalidade do JavaScript que se chama "template literals," se eu não me engano. Ah, template strings, né? Basicamente, é uma função que eu não preciso usar os parênteses para chamar ela, eu uso direto uma crase aqui, né, só que tem um funcionamento por baixo. Eu não vou entrar no explicar o que é isso tudo, né, mas você pode procurar depois. Mas basicamente, o que a gente vai fazer: ó, SQL botado depois do SQL, duas crases aqui, né, o acento grave,
como você preferir. E pronto, aqui dentro, escreve o nosso SQL, o que a gente quer executar. E é isso. Se eu salvar isso aqui agora e rodar com "node create-table", e dar um "Ctrl+C", então agora, teoricamente, é para ele ter criado a tabela. Será que ele criou? Vamos voltar aqui no Neon, dar F5 aqui nas tables, e não criou. Provavelmente, ele não criou porque eu não aguardei isso aqui finalizar de executar, né? Isso aqui ele demora um pouquinho para finalizar, talvez se eu botar um "await" aqui, ó, e colocar um console.log("tabela criada"). Talvez assim ele
espere a execução de novo, beleza, rodou "tabela criada." Ele não parou o script aqui, vou dar um "Ctrl+C." Então agora, teoricamente, se eu vier aqui nas tabelas, tá lá nossa tabela de vídeos já tá lá dentro com as colunas. "title," "description," show de bola. Com isso em mãos, a gente já pode agora criar um novo arquivo aqui dentro que vai ser o "database.js." O que esse arquivo vai ser? Exatamente igual ao meu "data," porém, vou até copiar ele aqui, porém agora ele vai fazer as operações direto no banco. Então, vamos lá, vamos apagar tudo que
eu tenho aqui dentro, vou deixar somente os nomes dos métodos, né, e os parâmetros que eles recebem, porque eu não quero alterar isso. Só que a gente vai começar a trocar isso aqui por operações no banco, né, diretamente, né, então vamos lá. O que que a gente vai começar fazendo aqui na listagem? Eu quero listar todos os vídeos. Então, com "vídeos" igual SQL, vamos importar o SQL lá de dentro do nosso "db." E aí, "select *," o nome da tabela é "vídeos," se eu não me engano. E aí, a gente tem uma busca aqui dentro,
certo? Então, a gente pode fazer o seguinte: eu vou criar uma variável aqui. Se eu tiver uma busca, eu vou colocar a busca em si, ou melhor, vou fazer o seguinte: eu vou definir um valor padrão aqui, ó, como sendo uma string vazia. Por que que eu tô fazendo isso? Porque se eu não receber o parâmetro "search," que é a busca, eu não quero que ele venha como "undefined" ou nulo, quero que ele venha como uma string vazia, então tô deixando digamos um valor padrão. Se ele não existir, vem como uma string vazia, isso vai
facilitar porque eu não preciso ficar fazendo if aqui dentro. Ou até poderia, né? Aí vou fazer dessa forma. Então, vou fazer o seguinte: vou criar uma variável, assim, "let vídeos." Pronto, vou criar uma variável sem preencher ela. Vou fazer o seguinte: se eu tiver uma busca, a operação que eu vou fazer vai ser a operação com filtro. Então, SQL "SELECT * FROM vídeos," né, que é o ver se o título contém uma string, porém de forma insensível, né? Case-insensitive, ou seja, ele desconsidera a letra caixa alta da letra caixa baixa, né, minúscula e maiúscula. E
aí, eu passo para ele aqui aspas duplas e boto aqui dois percentuais para indicar que eu quero ver se essa string no título, né, contém essa palavra, independentemente se essa palavra tiver no começo, no final, no meio, tanto faz. E aí, eu passo o termo de busca aqui dentro, para a gente passar parâmetros aqui dentro, basta eu fazer o seguinte: boto um sinal de menor a o sinal de dólar, duas chaves, e bota a sorte aqui dentro. E aí, se eu não tiver uma busca, eu quero simplesmente pegar todos os vídeos. Então, eu faço a
mesma operação sem o "WHERE" aqui dentro. E aí, no final, vídeos. Legal, vamos para o "create," aqui que é o mais importante, para a gente conseguir testar aqui dentro. O que que a gente vai fazer? Eu vou continuar gerando um ID para o vídeo, né, porque eu não pedi lá no meu banco de dados para ele gerar esse ID. E aqui dentro, eu vou fazer o seguinte. Ah, outra coisa super importante que eu acabei esquecendo aqui, tá? Todas essas operações que batem no banco de dados que eu tô fazendo aqui, elas são operações assíncronas, né?
Operações assíncronas dentro do JavaScript, né, significa que é uma ação que ela vai executar, mas ela vai levar um tempo para finalizar, né, ela demora um pouco para fazer, geralmente uns 100 milissegundos, 150 milissegundos. Então, eu preciso usar o "await" do JavaScript, que é para eu aguardar aquilo lá finalizar. Então, aguardo isso aqui finalizar, para continuar o restante do código. Só que eu só posso utilizar o "await" em funções que eu tenho aqui o "async." Então, eu tenho que usar o "async" aqui dentro, fechou? Mesma coisa, a gente vai fazer aqui embaixo assim. E aí,
eu posso usar o "await" aqui embaixo. E aí, eu vou usar o "await SQL" "INSERT INTO vídeos" e aí eu posso, como eu vou estar preenchendo todos os valores, eu poderia falar quais colunas eu quero inserir, tá? Então, "INSERT INTO vídeos (id, title, duration, url)" e aí, mando aqui, né? Então, o "id" vai ser o "video.id," o título, "video.title." A duração e a descrição, elas vêm de dentro do vídeo que eu tô recebendo aqui dentro, então passo aqui também, "video.title," "video.description," e "video.duration." Beleza, e aqui não tem nenhum retorno, é só isso mesmo. E bora
testar se nossa aplicação tá funcionando. Então, volta aqui no meu servidor, tá, e agora, o que que a gente vai fazer? Não vou mais usar o "DatabaseMemory," vou criar uma nova "Database" agora usando o nosso "DatabaseMemory" que vem dentro do arquivo "data," aquele já fez a importação para mim, esse "memory" aqui em cima, eu posso até comentar ele porque a gente não vai estar utilizando. E aí, uma das coisas importantes aqui é que dentro do "database," diferente do "DatabaseMemory," né, como as ações aqui, tanto a listagem quanto o "create," né, são assim, para nós, porque
elas podem levar um tempinho para completar, lá no nosso servidor, eu também vou precisar fazer aquilo que eu falei do "await." Então, aqui ó, antes dos métodos "create," tenho que botar o "await," e no método de listagem também. "Await." E aí, obrigatoriamente, sempre que eu uso o "await" no JavaScript, a função que está por volta precisa ser assim, né, então, bota um "async" que aqui ó, na função do "Fastify." Salvo aqui agora, vamos rodar nossa aplicação, "npm run dev." E agora, torcer para que tudo dê certo. Vamos lá, no "http://localhost:3333/videos," tentar criar um vídeo. Erro
interno de servidor. Collor. Então, vou voltar lá para o meu ChatGPT. Edition. Esqueci. Beleza. Então, a gente vai criar aqui, e aí que a gente vai fazer, só no nosso script aqui, né, antes de eu criar a tabela, eu vou executar um script que ele deleta a tabela. Então, aqui ó, ele vai deletar a tabela, depois criar ela de novo. E aqui, eu vou dar um "await" dentro também, para ele aguardar isso aqui finalizar, né? "Log: Tabela apagada." E aí, eu vou fazer o seguinte e vou copiar um novo script aqui dentro, que bota o
"ID." Vou comentar esse SQL aqui, para eu executar somente o "DROP" por enquanto, e vou executar "node." Tabela apagada, apagou. Venho aqui agora, comento esse aqui e boto o outro para criar a tabela. "Node create-table," tabela criada. Show. Agora vamos executar a nossa aplicação de novo. E agora eu vou lá nas minhas rotas aqui no HTTP, criar o vídeo, e em 2014 deu certo, será? Vamos lá dentro do Neon. A gente vem aqui, dá um F5 na tabela vídeos, clica aqui, e tá lá nosso vídeo, o ID do vídeo novo e a duração. Se eu
vier na listagem de vídeos, deixa eu tirar a busca aqui para ver se está funcionando sem a busca. Tá lá, vídeo novo. E agora, enviando a busca, deu erro. Vamos entender o que aconteceu. Colocou um "LIKE" mas não existe, né? Vamos entender o que que a gente fez de errado lá dentro do nosso Data. Bem, na documentação aqui, nem like. Tá, beleza, provavelmente aqui não precisaria das aspas duplas. Tá. E aí, pelo que eu entendi, a gente tem que botar o sinal de percentual dentro aqui, ó. Então, ele sai daqui, e a gente vai botar
o sinal de percentual dentro aqui com um "+" né, uma concatenação dessa forma. Beleza, cada libreria às vezes ela tem a sua própria sintaxe. Então, você vai ter que ir mudando, né, aprendendo ali, muito com a documentação também. Vou dar um "save" e ainda tá dando sintaxe error. Aqui na nossa API, claro, né, eu deixei um percentual aqui no final sem querer, então, cada coisinha vai dando um erro diferente, a gente tem que descobrir. E agora sim, ele já trouxe o meu vídeo, né. Veja que ele demora um pouquinho para trazer o resultado porque o
nosso banco de dados ali no Neon, ele tá hospedado lá nos Estados Unidos. Se você tiver aqui no Brasil, assim como eu, 200 milissegundos, pelo menos, se não um pouquinho mais às vezes, para retornar a resposta. Falta agora a gente implementar o restante dos métodos. Então, vamos fechar aqui, vamos abrir aqui o Database, Postgres, e implementar o restante dos métodos aqui dentro. Vamos lá. O "update," a gente vai pegar, vai dar, vai pegar também o título, aqui, a descrição e a duração que tá vindo aqui de dentro do vídeo, e vai dar um "update vídeos."
E aqui a gente vai dar um "set title" igual, passando o meu título, "description" igual, passando a minha descrição, "duration" igual, passando a minha duração, "WHERE ID" igual, passando o meu vídeo. Certo? Faz tanto tempo que eu não escrevo um SQL aqui assim na mão. É trocar aqui para assim que né, porque eu sou obrigado a usar o "await." Volto lá no meu servidor, mesma coisa, vem aqui na rota, utilizo o "await" aqui na frente e o "await" aqui na função, salvo, e bora testar. Então, abra aqui minhas rotas. Agora, uma das coisas interessantes é
que, como a gente tá usando o banco de dados online, eu não preciso mais ficar criando um vídeo novo toda vez que eu vou testar. Veja que eu posso buscar os vídeos, e os vídeos continuam assistindo porque eles estão salvos em outro local que não é a memória. Vou pegar o ID do vídeo aqui, ó, venho aqui na parte de atualização, troco o ID aqui em cima na rota, e vou alterar. Pode ser "vídeo 2." Esse é o primeiro vídeo. Vamos trocar o título, né, para "vídeo 2." Vou dar um "send." 204. Se eu voltar,
ilícito. Pensei que tinha sumido o vídeo, mas é porque eu tô fazendo uma busca por "node," e o vídeo não tem "node" no título. Agora, senta aí, o vídeo. Vamos para o último método aqui que é o "delete," é mais fácil, né? A gente faz um SQL "DELETE FROM vídeos" igual e passa o nosso ID que a gente está recebendo aqui em cima novamente. Usa o "await" aqui dentro. Então, voltamos lá no Routes, a gente vem, copia o ID do vídeo aqui dentro, aqui do "update," que a gente né, ou daqui, ó, tanto faz. Joga
aqui embaixo no "delete," executa o "delete," deu 200, vai dar 204, e agora na listagem não vai mais ter vídeo nenhum. Então, agora posso criar um vídeo novo, posso listar, posso editar. A gente já fez a busca. Então, a gente completou aqui a parte do banco de dados e agora a gente vai fazer o Deploy do nosso projeto. E aí, existem muitas formas de você fazer deploy de um projeto Node. Existem formas mais difíceis, mais simples, mais baratas, mais caras. Eu aqui, claro, eu quero te mostrar uma opção gratuita de deploy, mas que também é
uma opção para caso depois você queira escalar sua aplicação, né, receber bastante usuários, ela vai suprir sempre muito bem. Que é uma aplicação incrível para você hospedar código de todo tipo. Não é só para Node, não é só para JavaScript. O que eu quero que você faça aqui no começo é criar sua conta. Lembrando que tem um plano gratuito, sem problemas nenhum. Só vem aqui, cria sua conta. Eu já tenho uma conta aqui que eu criei com o GitHub, por isso eu cliquei aqui em GitHub e pronto. A gente já vai ver que eu tenho
aqui uma aplicação. O que que eu vou fazer é deletar essa aplicação que eu já tinha para a gente criar uma aplicação do total zero juntos. Então, vou dar um "delete" web service aqui dentro, e a gente vai começar a configurar a nossa aplicação. Veja que o Render também tem Postgres aqui dentro e tudo mais, mas eu acho que o principal foco deles aqui é hospedagem de apps. Vou clicar aqui em "New Web Service," e a gente vai começar criando para publicar a nossa aplicação aqui no Render. Existem várias formas. A forma mais simples é
você hospedando essa aplicação, a sua aplicação, no GitHub antes de hospedar a aplicação no Render. A única coisa que eu vou fazer é aqui no meu server.js, lembra que aqui embaixo eu tô ouvindo, né? O nosso servidor está ouvindo a porta 3333. Só que isso aqui é na minha máquina. No Render, quem vai configurar a porta que a minha aplicação vai usar é o próprio Render. Por isso, aqui a gente vai usar, ao invés de uma porta fixa, eu vou usar a variável ambiente "process.env.PORT." Se essa variável não existir, que é o caso de quando
eu tiver rodando a minha aplicação em desenvolvimento, eu vou usar 3333, ou seja, fiz um sinal aqui de "ou," digamos assim, né? Se isso não existir, uso 3333, ou seja, em desenvolvimento vai funcionar normal, sem problemas nenhum. Beleza, vamos colocar nosso projeto no GitHub. Como é que a gente vai fazer isso? Bitub, bora criar um novo repositório. Vou chamar ele aqui de "note-do-zero." Botar aqui dentro do meu repositório. Vou deixar ele privado, tá, mas você pode deixar público. Vou criar o repositório. Aqui, a gente vai copiar a URL. Aqui, eu uso o SSH, mas dependendo
de como você configura o Git anteriormente, você vai usar HTTP. E aqui, a gente vai criar o repositório, "git init," verificar se a gente não deixou aqui vazar nada, né? Então, tem que cuidar, porque o Git Ignora, ele tem que ter o "node_modules." O resto não precisa. E faz o seguinte, "status," conferir os arquivos aqui. Legal, eu vou botar aqui, "servidor." Ou melhor, botar "api/note." E agora, a gente passa o endereço do Origin. E agora, um pouquinho. Beleza, já foi lá dentro. Dá um "F5" aqui dentro, e o meu repositório já tá aqui. O que
faremos agora é aqui no Render, a gente vai dar um "F5," porque ele não vai estar mostrando meu repositório. Como eu conectei com ele, já tem acesso a todos os meus repositórios. Então, teoricamente, ele já vai conseguir visualizar esse repositório novo que eu criei. Tá demorando um pouquinho. Tá aqui, o "note-do-zero." Clica em "Connect." Vamos dar o nome, chamar de "note-do-zero" também. Aqui na região, uma coisa que é importante é, lembra que lá no Neon, quando eu criei meu banco de dados, eu criei ele aqui, ó, na região? Eu criei ele numa região específica. Deixa
eu ver onde é que eu consigo pegar essa região. Eu acho que aqui, na minha conexão. Deixa eu lembrar, "Settings," talvez a "Connection." Talvez aqui, no "Compile." Acho que é, deixa eu lembrar. Mas eu criei ele na região padrão, que é a "us-east." Tá vendo? Ou seja, eu quero que minha aplicação esteja rodando mais próximo possível do meu banco de dados, para ter menos latência. Então, aqui, eu boto na mesma região, o "us-east." Tá vendo? Beleza. Comando aqui seria o comando para a gente executar para fazer a compilação da nossa aplicação. Nesse caso, a gente
não tem um comando para compilar a nossa aplicação. Então, nesse caso, eu não sei se eu posso deixar vazio. O que eu vou fazer aqui é botar um "npm install." O que esse comando vai fazer aqui, ó, fazer a instalação das bibliotecas. E aí, no final, qual que é o comando que eu quero executar para rodar o servidor? Aqui é npm start, beleza. Vamos usar o plano free aqui e aqui em Advanced, clica aqui, eu posso configurar variáveis ambiente. Tá vendo aqui, ó? E aí que que eu vou botar aqui? Vou lá no meu .env
que eu tenho aqui dentro, e cada uma das variáveis, eu vou botar aqui dentro: PGHOST e o valor dela, sem as aspas. Vem aqui, e volto mais uma. PGDATABASE, valor nenhum, beleza. Mais uma: PGUSER. Copio o usuário, colo aqui dentro, e por último, são as conexões do banco de dados. Beleza, já não tem mais o que configurar aqui dentro. E a gente vai dar um "Create web service" e agora torcer para que tudo dê certo no final das contas. Então, bora lá, aguardando aqui. Ele vai mostrar todo log, né, do processo de Deploy do nosso
app. E aqui é só aguardar, tá rodando o npm install, que é para fazer a instalação das dependências. Show, já rodou, fazendo upload da build, tá colocando o nosso projeto no ar, e deu sucesso, fazendo Deploy. E agora, se tudo der certo, a gente vai ter uma URL aqui para acessar o nosso app. Agora, mais um segundinho aqui. E aí, a gente já vai para a última parte aqui do nosso Roadmap, que é falar sobre o Roadmap de estudos, falar um pouquinho sobre o que que se você quer se especializar em Node, eu estudaria, se
fosse você. Show, já tá rodando ali, ó, deu no server aqui, né, para rodar o nosso projeto. E beleza, projeto rodando. Teoricamente, a gente pode vir aqui, em main, mais... Eu acho que tá... Será que é? Será que já tá rodando? Vamos aguardar mais um pouquinho. Ver se ele dá algum tipo de sucesso aqui. Eu esperei, esperei, esperei, nada funcionou. Porque depois eu fui ler a documentação aqui do Render. Uma coisa que eu esqueci é que quando a gente cria uma aplicação aqui dentro do... Além da porta, eu tenho uma outra opção aqui, que se
chama "host." E no caso do Render, eles pedem que eu passe esse host como 0.0.0.0. Tá vendo? Então, isso aqui que a gente vai fazer, ó. Eu vou utilizar essa informação. Teoricamente, só que não deveria atrapalhar em desenvolvimento. Então, se eu rodar, eu devo conseguir usar minhas rotas da aplicação sem problemas nenhum. Vamos testar aqui, ó. Aguarda um pouquinho, funciona. Veja, então, o que que eu vou fazer agora. Eu vou adicionar um novo commit, falando "set host option." E agora, vou enviar esse novo commit lá no... Como a gente configurou. E aí, isso é legal,
o que aconteceu, porque eu já consigo te mostrar algo que a gente configurou automaticamente na nossa aplicação, que é o Deploy automatizado. Toda vez que eu envio um novo commit aqui para o GitHub, o Render, automaticamente, ó, ele vê que ouve um novo commit, ó, set host option, tá vendo? E ele cria um novo Deploy automaticamente. Olha que interessante, ele já começou a fazer o Deploy sozinho, ou seja, toda vez que eu mudar qualquer coisa no GitHub, o deploy vai ser feito automático. A gente chama isso de CI/CD, né, continuous deployment. Isso é bem legal.
E aqui, agora, vamos aguardar um pouquinho para ver se dessa vez vai, né? Show, agora, assim, olha só, ele já mostrou "Your service," agora, né, porque ele já conseguiu fazer o bind da porta. E aqui em cima, eu tenho o endereço, "note-do-zero On Render." E aí, claro, que o seu vai ser diferente. Clicando nele, aqui, abrindo, ó, ele traz um "Not Found," porque realmente a gente não tem uma rota raiz. Mas agora, eu vou copiar esse endereço aqui. A gente vai voltar lá na nossa... Na nossa aplicação aqui no Roads HTTP, lembra? E eu vou
vir aqui, ó, onde tem "localhost:3333," e apertando Ctrl + D, ó, eu vou substituir todos eles pelo endereço da nossa API online. Só cuidar porque ficou duas barras aqui no final. Show. Agora sim, e vamos testar se a API tá funcionando da mesma forma que ela tava funcionando normalmente. Então, vamos lá. Vou criar um vídeo. Show, 201. Quer dizer que deu certo. Vou listar os vídeos, listou os dois porque eu já tinha um vídeo criado antes. Eu tô usando o mesmo banco de dados pra produção e local. Vou editar um vídeo. Então, vou pegar o
ID aqui do vídeo que eu acabei de criar. Vamos botar aqui e trocar o nome dele. Hoje tá "vídeo node," eu vou trocar por "vídeo dois." Então, sempre listo de novo e tá lá, ó, "vídeo dois." Vou deletar esse vídeo que eu acabei de criar, vou listar de novo e pronto, já não temos mais um vídeo ali dentro. E agora sim, a gente finalizou com chave de ouro o Deploy da nossa aplicação dentro aqui do Render. E agora, eu quero te passar uma lista de coisas que você deve estudar daqui para frente, caso você queira
se especializar em Node.js. E logo no final, um presente super especial para você. Fica até o final porque você vai curtir muito, muito, muito, caso você queira realmente estudar Node.js. Vamos lá, Roadmap de estudos. Primeira coisa é super importante que, no Node.js, você estude as APIs nativas do Node. Lembra que aqui na nossa aplicação a gente usou, por exemplo, a API do "crypto" para gerar um ID aleatório, que é o "uuid" e lá no começo também eu usei API Nativa HTTP para criar um servidor HTTP, sem o Fastify, lá no comecinho. Ou seja, existem várias
outras APIs nativas do Node, como FileSystem, que é uma das APIs mais famosas do Node, que ela permite a gente retornar ou ler um conteúdo em partes, otimizando memória. Isso é muito interessante. "Crypto" é bom. Tem várias e várias outras APIs nativas. Isso aqui é algo que você vai ter que aprender, caso você queira se especializar com o Node. Outra coisa que, para mim, é primordial hoje, você aprender é o TypeScript. O TypeScript é uma ferramenta que ela adiciona tipagem estática dentro do JavaScript, que é uma linguagem de tipagem dinâmica. Se você já vem do
Java, C#, ou outras tecnologias, você já está acostumado com essa tipagem estática. Basicamente, quando eu crio uma função que ela recebe um parâmetro, eu preciso especificar exatamente qual é o formato desse parâmetro: se é uma string, se é um número, se seria um objeto, quais informações tem dentro desse objeto. Isso ajuda a gente a evitar vários erros no desenvolvimento durante o futuro do projeto. Então, assim, isso é incrível. Você vai precisar aprender. Outra coisa, autenticação JWT, JSON Web Tokens. Isso aqui é o padrão de autenticação mais comum utilizado nas aplicações web atualmente. Ou seja, é
o formato de autenticação mais comum quando a gente tem um frontend, um backend, e essas duas aplicações precisam se comunicar, mas eu preciso que o usuário esteja logado pra acessar o backend e tudo mais. Hoje, o backend que a gente criou, ele é todo público, qualquer pessoa pode acessar essas rotas. E se eu precisasse adicionar autenticação, provavelmente autenticação JWT. Outra coisa, que isso aqui é primordial para todo mundo que vai estudar programação, principalmente, são os princípios SOLID. O SOLID, né, ele é basicamente uma fórmula que a gente, alguns princípios, né, que determinam uma forma da
gente criar uma aplicação que seja mais testável e que seja mais manutenível. Ou seja, uma aplicação que ela tenha uma longevidade maior. Os princípios SOLID são bem legais e para você que quer se especializar em backend, eles são indispensáveis. Outra coisa, SQL. SQL é algo que você vai precisar aprender de uma maneira mais profunda do que a gente viu aqui hoje. E mais pra frente, quando você for criar projetos mais profissionais, quando você for trabalhar com Node.js, uma coisa que é opcional, mas que eu altamente recomendo, é você estudar pelo menos um ORM. O ORM
é uma ferramenta que ela vai facilitar você trabalhar com coisas dentro do banco de dados que são chatas. Como, por exemplo, essa parte que a gente criou uma tabela no banco de dados, né? Ali, eu fui ali, criei um script, né, "Create table." Só que existem formas melhores de fazer isso, e o ORM ele facilita pra gente várias coisas do banco de dados que são chatas de serem feitas. E um dos ORMs mais famosos hoje para o ecossistema Node é o Prisma. Então, tem vídeo aqui no canal também que você consegue aprender. Outra coisa interessantíssima
é você aprender o Docker. O Docker é uma das ferramentas mais incríveis para fazer containerização. A containerização é uma forma de virtualização, assim como a gente tinha no VirtualBox na era antiga. É uma forma de criar um subsistema para nossa aplicação, que ela não divide recursos com o restante, até divide, mas de uma forma mais isolada. Mas não divide os arquivos, né? Só que, diferente de uma virtualização, dentro dos containers, a gente consegue compartilhar qualquer coisa entre os containers. Então, isso é muito mais rápido. Geralmente, o Docker é utilizado tanto para deploy quanto para criação
de ambientes de desenvolvimento que possuem dependências, como o PostgreSQL. Imagina você rodar uma aplicação local que tem três bancos de dados, mais dois serviços de mensageria, mais um sistema de cache. É muita coisa. Quando entra um funcionário novo na empresa, você tem que falar para ele: "Cara, instala tudo isso na sua máquina." Com Docker, não precisa. Você passa uma receita de bolo ali, e o Docker cria o ambiente para a pessoa. Frameworks, isso aqui você vai ter que aprender caso você queira trabalhar com Node.js no mercado. A gente usou o Fastify aqui, que, para mim,
é um dos melhores frameworks para Node. Mas existe outro framework que também é muito famoso no Node.js, que é o Next.js. O Next.js é um framework que traz muito mais opinião, ou seja, ele meio que dita regras para você. Ele não é tão aberto quanto o Fastify, mas ele é muito usado no mercado de Node. Outra coisa que você vai ter que aprender, com certeza, são testes automatizados. Para mim, uma das principais coisas que definem o sucesso de uma aplicação a longo prazo são testes automatizados. E as ferramentas mais famosas para testes são o Jest,
com certeza, e o Cypress, beleza. Além disso, arquitetura de software. Claro, à medida que você desenvolve projetos maiores, você vai ter que estudar um pouco mais sobre design patterns, sobre arquitetura de software, estudar, quem sabe, uma arquitetura limpa. Isso é imprescindível. E por último, deploy e CI/CD. A gente fez um deploy super simples aqui dentro do Render, que é uma ferramenta que facilita muito pra gente. Mas talvez no dia a dia, dentro da sua empresa, não seja exatamente assim. Você tem que configurar um servidor do zero, usar algum outro tipo de serviço, e vai ter
que configurar toda a parte de integração contínua, que é basicamente toda vez que eu faço uma nova adição no código, conseguir executar testes para validar se nosso código tá funcionando. Se não tá funcionando, eu não faço deploy. Se tá funcionando, eu faço deploy automático. Tudo isso é o que a gente chama de CI/CD, Continuous Deployment, que é esse deploy automático que a gente viu hoje. Tudo isso você vai ter que estudar um pouquinho mais a fundo. E agora chegou a hora do presente especial que eu tava preparando para você. Olha só, agora que você já
deu o seu primeiro passo assistindo esse vídeo, eu tenho um presente para você continuar acelerando o seu aprendizado com o Node.js. Eu preparei um mini curso, um projeto completo do total zero, totalmente gratuito, para você sair dessa aula e já começar a construir o próximo projeto. Vai ser ainda mais completo que esse que a gente preparou, envolvendo muito mais conceitos, boas práticas. A gente vai bem a fundo mesmo dentro do Node.js. É um conteúdo extremamente prático, assim como esse. A gente vai desde a primeira aula já com a mão na massa, criando o nosso app,
mostrando vários conceitos dessa ferramenta. O link está aqui na descrição desse vídeo. Clica lá, se inscreve, começa a estudar agora mesmo, e a gente se vê nas aulas. Valeu!
Related Videos
Cursor AI tutorial for beginners
40:35
Cursor AI tutorial for beginners
Greg Isenberg
76,285 views
EVERYTHING You Need to Know to Use TypeScript with Node/React
1:07:51
EVERYTHING You Need to Know to Use TypeScr...
Rocketseat
37,601 views
The best option for FREE Node.js DEPLOYMENT!
25:53
The best option for FREE Node.js DEPLOYMENT!
Rocketseat
113,992 views
How 3 Phase Power works: why 3 phases?
14:41
How 3 Phase Power works: why 3 phases?
The Engineering Mindset
1,076,132 views
Web Development [17] - Build a Reusable Code Editor in React
1:02:59
Web Development [17] - Build a Reusable Co...
Prashan
403 views
Create components in this way in React (Composition Pattern)
24:47
Create components in this way in React (Co...
Rocketseat
110,061 views
Seu próximo back-end Node com TESTES! (+ SOLID)
1:02:43
Seu próximo back-end Node com TESTES! (+ S...
Rocketseat
93,210 views
TUDO que você deve estudar de JavaScript antes do React
1:25:24
TUDO que você deve estudar de JavaScript a...
Rocketseat
295,558 views
APRENDA ANGULAR DO ZERO - primeiro passos
2:50:55
APRENDA ANGULAR DO ZERO - primeiro passos
Fernanda Kipper | Dev
134,649 views
OpenAI o1 | GPT-5 | Finalmente 🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓🍓
21:17
OpenAI o1 | GPT-5 | Finalmente 🍓🍓🍓🍓🍓�...
Lucas Montano
131,448 views
How to Learn Programming (even if you're stupid)
8:49
How to Learn Programming (even if you're s...
dewoibau
574,290 views
Prisma: o ORM Node.js que você precisa em 2022
1:31:35
Prisma: o ORM Node.js que você precisa em ...
Rocketseat
57,709 views
Princípios SOLID em uma API REST com Node.js e TypeScript | Code/Drops #44
48:29
Princípios SOLID em uma API REST com Node....
Rocketseat
209,818 views
Eu RESUMI o Next.js 14 para você! (Server Components & Actions)
24:10
Eu RESUMI o Next.js 14 para você! (Server ...
Rocketseat
65,512 views
Criando uma API do ZERO com Node.js e Banco de Dados
1:15:42
Criando uma API do ZERO com Node.js e Banc...
DevClub | Programação
66,079 views
Cursor AI Tutorial for Beginners (How I Code 159% Faster)
26:27
Cursor AI Tutorial for Beginners (How I Co...
Volo
131,467 views
A Systems-Minded Approach to Creating a Music Player Application by Andrew Kelley
26:13
A Systems-Minded Approach to Creating a Mu...
TigerBeetle
29,852 views
Recriei a interface do Spotify usando Tailwind
52:36
Recriei a interface do Spotify usando Tail...
Rocketseat
115,880 views
Programa em Node.js? Então conheça esse framework (NestJS do ZERO)
1:00:39
Programa em Node.js? Então conheça esse fr...
Rocketseat
119,229 views
SQL no Node.js com Sequelize | Masterclass #01
1:40:22
SQL no Node.js com Sequelize | Masterclass...
Rocketseat
248,846 views
Copyright © 2024. Made with ♥ in London by YTScribe.com