A equipe do Couchbase DevRel tem trabalhado com o Clube do site ruim em freeCodeCamp materiais.
O freeCodeCamp é uma organização sem fins lucrativos que consiste em uma plataforma interativa de aprendizado na Web, um fórum de comunidade on-line, salas de bate-papo, publicações on-line e organizações locais que pretendem tornar o aprendizado de desenvolvimento de software acessível a qualquer pessoa.
O Bad Website Club é uma comunidade on-line que ajuda novos alunos em sua jornada de programação.
Fizemos um streaming para mostrar aos alunos de fCC o que poderia acontecer com seus projetos em condições mais "reais". Começamos com o curso Responsive Web Design, pegamos alguns exemplos, como o formulário Survey (Pesquisa), os completamos e os colocamos em produção. Toda a série foi transmitida no YouTube, LinkedIn, Twitter e Twitch, e as gravações estão disponíveis nesta lista de reprodução do YouTube, se você quiser conferir: Novos fluxos do Couchbase: A partir de 31 de julho!
Eu estava transmitindo pessoalmente no Projeto de pesquisa. Nesta série de publicações do blog, mostrarei todas as etapas adicionais que você pode fazer: publicar o código no GitHub, implantar o Survey on-line com o Netlify e armazenar seu conteúdo no Couchbase Capella.
Etapa 1 - Criar um formulário HTML
Inspirando-me bastante no exemplo de pesquisa do FreeCodeCamp (copiar, colar e aparar), obtive o seguinte formulário HTML. Ele é um pouco mais simples do que o original.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="./styles.css" /> </head> <body> <div class="container"> <header class="header"> <h1 id="title" class="text-center">Survey Form</h1> <p id="description" class="description text-center"> Thank you for taking the time to help us improve the platform </p> </header> <form id="survey-form"> <div class="form-group"> <label id="name-label" for="name">Name</label> <input type="text" name="name" id="name" class="form-control" placeholder="Enter your name" required /> </div> <div class="form-group"> <label id="number-label" for="number" >Age<span class="clue">(optional)</span></label > <input type="number" name="age" id="number" min="10" max="99" class="form-control" placeholder="Age" /> </div> <div class="form-group"> <p> Would you recommend this awesome survey to a Friend ? </p> <label ><input name="recommend" value="recommend" type="checkbox" class="input-checkbox" />yes</label > </div> <div class="form-group"> <button type="submit" id="submit" class="submit-button"> Submit </button> </div> </form> </div> </body> </html> |
O styles.css é exatamente o mesmo que o original. Abra aqui para ver o formulário de pesquisa em ação. Você pode abrir o em seu navegador, clique com o botão direito do mouse na página e você verá algo como Exibir fonte da página ou inspecionar. Clique nele e isso abrirá um painel que mostra o código da página. Enquanto estiver nessa exibição, você poderá clicar em um link como style.css ou clique no ícone estilos para visualizar o CSS aplicado a determinados elementos também.
Para testar esse exemplo de código, você pode primeiro clonar esse repositório no seu computador local usando o terminal ou pode baixá-lo como um arquivo zip.)

Acesse seu navegador e, na barra superior, selecione arquivo, abertoe, em seguida, selecione a opção index.html da pasta (ou pasta zip) que foi baixada. Dê uma olhada no URL do seu navegador, que mostra um caminho para um arquivo local. E você deve ver algo como isto, que não faz nada quando você clica em enviar.

A questão então é: como implantá-lo na Internet, como fazer com que ele faça alguma coisa? Precisamos de algum código de backend para ser executado após o clique. E, em seguida, fazer com que esse código armazene o conteúdo do formulário no banco de dados.
Etapa 2 - Git, Github, Netlify
Vamos começar implantando esse formulário ao vivo na Internet. Para isso, usaremos o Netlify. A primeira coisa a fazer é verificar se temos o arquivo CLI da Netlify disponível e que estamos conectados. Se ele não estiver instalado, o caminho mais rápido é digitar em seu terminal:
|
1 |
npm install netlify-cli -g |
Você encontrará mais detalhes na seção Documentos de introdução à Netlify.
Digitação versão netlify em meu terminal atualmente me dá netlify-cli/15.6.0 win32-x64 node-v18.5.0. Portanto, sei que ele está instalado e pronto.
Em seguida, a próxima coisa a fazer é digitar login na netlify em seu terminal. Você será direcionado para o formulário de login do Netflify.
Agora tudo deve estar pronto para passar para a fase de implementação. Mas só para ter certeza, vamos testar as coisas localmente. Porque é isso que a maioria dos desenvolvedores faz. Para isso, digite desenvolvimento da netlify em seu terminal.
Ele deve exibir o seguinte no terminal e abrir o formulário no navegador.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
◈ Netlify Dev ◈ ◈ Ignored general context env var: LANG (defined in process) ◈ No app server detected. Using simple static server ◈ Unable to determine public folder to serve files from. Using current working directory ◈ Setup a netlify.toml file with a [dev] section to specify your dev server settings. ◈ See docs at: https://cli.netlify.com/netlify-dev#project-detection ◈ Running static server from "freecodecamp-survey" ◈ Setting up local development server ◈ Static server listening to 3999 Adding local .netlify folder to .gitignore file... ┌─────────────────────────────────────────────────┐ │ │ │ ◈ Server now ready on https://localhost:8888 │ │ │ └─────────────────────────────────────────────────┘ |
Se você der uma olhada na barra de URL do navegador novamente, verá que ela é diferente. Parece um endereço de site da Web, não um arquivo local. Parabéns, você acabou de executar seu primeiro servidor local, servindo seu arquivo HTML e CSS, usando Netlify dev! Você tem um site em execução em sua máquina. Agora vamos torná-lo acessível a todos na Internet, tanto o código-fonte quanto o próprio site.
Vá para o GitHub (ou GitLab, ou Heptapod, ou qualquer outra solução de hospedagem de código-fonte, existem outras por aí! Acesse https://github.com/new para o Github. Agora você está no assistente de criação do repositório. Eu só configurei minha organização, o nome do meu repositório e uma descrição, depois cliquei no botão Criar repositório botão.


Ele fornecerá todas as instruções necessárias para converter sua pasta de trabalho em uma pasta git e vincule-o ao seu projeto do GitHub. Foi isso que digitei no terminal (você pode copiar e colar o texto abaixo no terminal ou pressionar Enter após cada linha do texto abaixo para executá-lo. Observe que será necessário alterar a linha 6 para que seja o URL do repositório do projeto) Observe que você terá que alterar a linha 6 para que seja o URL do repositório do projeto):
|
1 2 3 4 5 6 7 |
echo "# myproject" >> README.md git init git add README.md git commit -m "first commit" git branch -M main git remote add origin https://github.com/ldoguin/myproject.git git push -u origin main |
Esta é a saída do terminal resultante:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
[C:\Code\Couchbase\myproject] $ echo "# myproject" >> README.md [C:\Code\Couchbase\myproject] $ ls Directory: C:\Code\Couchbase\myproject Mode LastWriteTime Length Name ---- ------------- ------ ---- -a---- 8/4/2023 12:11 PM 28 README.md [C:\Code\Couchbase\myproject] $ git init hint: Using 'master' as the name for the initial branch. This default branch name hint: is subject to change. To configure the initial branch name to use in all hint: of your new repositories, which will suppress this warning, call: hint: hint: git config --global init.defaultBranch <name> hint: hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and hint: 'development'. The just-created branch can be renamed via this command: hint: hint: git branch -m <name> Initialized empty Git repository in C:/Users/Laurent Doguin/Documents/Couchbase/myproject/.git/ [C:\Code\Couchbase\myproject] $ git config --global init.defaultBranch main [C:\Code\Couchbase\myproject] $ git branch -m main [C:\Code\Couchbase\myproject] $ git add .\README.md .\index.html .\styles.css [C:\Code\Couchbase\myproject] $ git commit -m "first commit" [main (root-commit) 356ece7] first commit 3 files changed, 245 insertions(+) create mode 100644 README.md create mode 100644 index.html create mode 100644 styles.css [C:\Code\Couchbase\myproject] $ git remote add origin https://github.com/ldoguin/myproject.git [C:\Code\Couchbase\myproject] $ git push -u origin main Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 8 threads Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 1.95 KiB | 999.00 KiB/s, done. Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/ldoguin/myproject.git * [new branch] main -> main branch 'main' set up to track 'origin/main'. [C:\Code\Couchbase\myproject] $ |
Agora, se eu voltar à página do Github e recarregá-la, verei o seguinte:

Parabéns, seu código agora está disponível no Github, para que todos possam ver, aprender e contribuir. Agora é hora da produção! Vamos colocar esse site no ar 💪
Vá em frente e visite https://app.netlify.com/start/deploy. Isso o levará ao novo assistente de projeto do Netify. Você verá vários botões para ajudá-lo a começar, GitHub, GitLab, Bitbucket, AzureDevops. Vamos clicar no GitHub.

Você verá algumas janelas solicitando que você vincule seu perfil do GitHub ao Netlify. Vá em frente e prossiga, e você será levado à página a seguir.

O Netlify está me dizendo que não tenho nenhum aplicativo Netlify instalado em nenhuma organização do GitHub. Clique em Configurar o Netlify no GitHubEle abrirá uma janela pop-up solicitando que você selecione a organização do GitHub na qual deseja instalar o Netlify e o repositório ao qual deseja dar acesso.

Deixo o padrão e prossigo para a próxima etapa. De agora em diante, você deverá ver todos os repositórios em sua conta do GitHub.

Deixarei o padrão e clicarei em Implementar meu projeto:

Você verá um link para seu site recém-implantado na Internet, que para mim é https://jolly-sfogliatella-3e6c07.netlify.app/. A Netlify fornece um ambiente de sandboxes sob o netlify.app para que você possa implementar coisas sem ter seu próprio nome de domínio.

Parabéns, seu site agora está no ar na Internet. Reserve um minuto para comemorar 🎉.
Agora, podemos vincular esse projeto Netlify digitando link netlify no terminal. Será oferecida uma lista de opções. Selecione a opção padrão, que deve ser Usar a origem remota atual do git (https://github.com/yourOrg/yourProject). Como você fez a implantação por meio do GitHub, o Netlify tem as informações do git do seu repositório e pode inferir qual projeto usar (e também, nesse ponto, você provavelmente tem apenas um projeto). Esta é a aparência do resultado para mim:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[C:\Code\Couchbase\myproject] $ netlify link netlify link will connect this folder to a site on Netlify ? How do you want to link this folder to a site? Use current git remote origin (https://github.com/ldoguin/myproject) Looking for sites connected to 'https://github.com/ldoguin/myproject'... Directory Linked Admin url: https://app.netlify.com/sites/jolly-sfogliatella-3e6c07 Site url: https://jolly-sfogliatella-3e6c07.netlify.app You can now run other `netlify` cli commands in this directory [C:\Code\Couchbase\myproject] $ |
Podemos tentar algumas coisas agora. Vou adicionar um emoji 🐼 ao meu formulário, porque não. Em index.htmlEstou modificando a linha 9 a partir disso: <h1 id="”title”" class="”text-center”">Formulário de pesquisa</h1> para isso <h1 id="”title”" class="”text-center”">Formulário de pesquisa 🐼</h1>
Em seguida, salvo o arquivo e envio essas alterações para o Github. Em seguida, no terminal, digito netlify open:site:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[C:\Code\Couchbase\myproject] $ git add .\index.html [C:\Code\Couchbase\myproject] $ git commit -m"Panda" [main caa6f87] Panda 1 file changed, 1 insertion(+), 1 deletion(-) [C:\Code\Couchbase\myproject] $ git push Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 8 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 360 bytes | 180.00 KiB/s, done. Total 3 (delta 1), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (1/1), completed with 1 local object. To https://github.com/ldoguin/myproject.git 356ece7..8a2ebe2 main -> main [C:\Code\Couchbase\myproject] $ netlify open:site Opening "jolly-sfogliatella-3e6c07" site url: > https://jolly-sfogliatella-3e6c07.netlify.app |
Algo muito legal está acontecendo. Como seu repositório do GitHub está vinculado ao Netlify, uma nova implantação será feita automaticamente pelo Netlify. Portanto, ao abrir o site, você verá o Panda <3.
Nesse ponto, temos um repositório do Github que contém nosso código, que é integrado ao Netlify, que criará automaticamente uma nova implantação quando você enviar um novo código. E também temos um repositório netlify CLI em nossa pasta de trabalho. Estamos prontos para escrever o código de backend!
Etapa 3 - Backend
Neste capítulo, responderemos à seguinte pergunta: O que acontece quando alguém preenche o formulário e clica em enviar ?
A resposta neste momento é: Nada. Vamos mudar isso. Escrevendo um pouco de JavaScript. Vamos exibir um alerta pop-up quando alguém inserir informações válidas e clicar em Enviar. Em seu index.html você colocará o seguinte <script> código entre a última tag div de fechamento </div> e antes da tag de fechamento do corpo </body>.
|
1 2 3 4 5 6 7 8 9 10 |
<script> const form = document.getElementById('survey-form'); <1> form.addEventListener('submit', handleForm); <2> async function handleForm(e) { e.preventDefault() <3> alert("Form Submission !") <4> } </script> |
|
1 2 3 4 |
<1> Get the Dom element representing the form by using its id <2> Each time the submit event occurs, run the handleForm function <3> The natural behavior of a form submission is to reload the page, we don't need that, hence we prevent the default behavior to happen <4> The alert function display a popup with a message |
Se você salvar seu código e recarregar a página, preencha o formulário e clique em enviarvocê verá algo parecido com isto:

Agora que temos algo acontecendo quando um usuário envia o formulário, vamos avançar um pouco mais. Queremos examinar o conteúdo do formulário e nos certificar de que podemos obter os dados corretos no JSON. Queremos uma string para o nome, um número inteiro para a idade e um booleano para a recomendação.
E acontece que a caixa de seleção HTML não está funcionando bem. O valor que ela fornece por padrão é nenhum valor e, quando marcada, fornece o conteúdo do campo de valor. Vamos adicionar outro campo de entrada, oculto, para garantir que o valor padrão seja False.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<label> <input id="hiddenRecommend" name="recommend" value="false" type="hidden" /> <input id="recommend" name="recommend" value="true" type="checkbox" class="input-checkbox" />yes</label> |
Agora, com relação ao código JavaScript, há algumas novas linhas interessantes a serem analisadas.
|
1 2 3 4 5 6 7 8 9 10 11 |
const form = document.getElementById('survey-form'); form.addEventListener('submit', handleForm); async function handleForm(e) { <1> e.preventDefault() const data = new FormData(e.target); <1> const value = Object.fromEntries(data.entries()); <2> const details = `name: ${value.name}\nage: ${value.age}\nrecommend: ${value.recommend}`; <3> console.log(details); <4> } |
|
1 2 3 4 |
<1> The parameter of the handleForm function is an object(e) with a field called target. This target can be transform into a FormData object. <2> The FormData object can be transformed into a JSON object. <3> Now that we have a JSON object we can print out the values we are interested in. <4> This time instead of displaying an alert box, we are logging the details string to the console. The console can be accessed through your browser's dev tools. It is great for debugging. |
Com isso resolvido, vamos levar a sério e começar a criar uma função Netlify. Entrar função netlify:create em seu terminal. Você deverá ver algo como:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[C:\Code\Couchbase\myproject] $ netlify function:create ? Select the type of function you'd like to create Serverless function (Node/Go) ◈ functions directory not specified in netlify.toml or UI settings ? Enter the path, relative to your site’s base directory in your repository, where your functions should live: netlify/functions ◈ updating site settings with netlify/functions ◈ functions directory netlify/functions updated in site settings ◈ functions directory netlify/functions does not exist yet, creating it... ◈ functions directory netlify/functions created ? Select the language of your function JavaScript ? Pick a template javascript-hello-world ? Name your function: saveform ◈ Creating function saveform ◈ Created netlify\functions\saveform\saveform.js [C:\Code\Couchbase\myproject] $ |
Selecione Sem servidor deixa o padrão para a próxima pergunta sobre o caminho, mantém o JavaScript como a linguagem, mantém o padrão mundo do inferno e, em seguida, dê um nome à sua função. A minha se chama salvar formulário. Isso gerará novos arquivos na pasta netlify. Se você executar desenvolvimento da netlify agora, você verá novas linhas nos registros:
|
1 2 |
Loaded function saveform https://localhost:8888/.netlify/functions/saveform. ◈ Functions server is listening on 62431 |
Isso significa que nosso servidor de desenvolvimento netlify também está atendendo à nossa função recém-criada. Dê uma olhada no arquivo recém-gerado ./netlify/functions/saveform/saveform.js.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Docs on event and context https://docs.netlify.com/functions/build/#code-your-function-2 const handler = async (event) => { <1> try { const subject = event.queryStringParameters.name || 'World' <2> return { statusCode: 200, body: JSON.stringify({ message: `Hello ${subject}` }), <3> // // more keys you can return: // headers: { "headerName": "headerValue", ... }, // isBase64Encoded: true, } } catch (error) { return { statusCode: 500, body: error.toString() } <4> } } module.exports = { handler } |
|
1 2 3 4 |
<1> the signature of the function is aysynchronous (the async keyword),and has an event parameter. Asynchronous means some code inside the function can be asynchronous and we can wait for the code to be executed with the await keyword, instead of managing the JavaScript Promess object traditionally returned by async functions. <2> the `event` object has some properties and methods, like `queryStringParameters` that allows us to get the name query param <3> this function must return a JSON object with an HTTP status code and an Object body. If everything worked well, we return a JSON body containing a message field and the code 200. Code starting with 2 means things went well. <4> If things went wrong, we return the status code 500. Code starting with 5 means something went wrong on the server. And the body field will contain the error. |
Vamos testá-lo chamando essa função quando o usuário clicar em enviar. Basta adicionar o seguinte código após o último console.log ligar:
|
1 2 3 4 5 6 7 8 9 10 11 |
console.log(details); const response = await fetch("/.netlify/functions/saveform", { <1> method: 'GET', <2> headers: { <3> 'Content-Type': 'application/json', }, }) if (response.status == 200) { <4> console.log(await response.text()); } |
|
1 2 3 4 |
<1> fetch is the method you can call to send an HTTP request to a server. Here we are sending a request to `/.netlify/functions/saveform`. Notice the await keyword that means this method usually returns a promess. Here we are just assign the result of the promess to the field response. <2> HTTP request have methods, sometime also known as HTTP verbs. Here we are not modifying anything on the server, we are retrieving information, so we are using the method GET <3> HTTP requests have [headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type). They provide additional metadata like the Content-type, here set to `application/json`. What it means is that we are manipulating JSON. `application/text` would mean we are manipulating any form of text. These are called [Mime types or Media type](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type). <4> We are testing the status code returned by the server. If it's 200, it means everything went well. We have a message to display in the console. |
Adicionar, confirmar e enviar. netlify open:admin


Neste ponto, você tem um frontend e um backend implantados na Internet. Mas tudo o que estamos fazendo é chamar a função padrão criada pelo assistente do Netlify. A próxima etapa é enviar o conteúdo do formulário para essa função e armazená-lo em um banco de dados.
Etapa 4 - Banco de dados
A primeira coisa a fazer é descobrir como enviar os detalhes do formulário para a função. Para isso, precisamos alterar nosso método GET para um método POST. Essas coisas são chamadas de métodos de solicitação HTTP, às vezes chamados de verbos HTTP. Você pode dar uma olhada na lista completa em MDN. Uma solicitação do método Get é usada apenas para recuperar dados. Uma solicitação de método Post é usada para criar ou alterar dados. É exatamente isso que queremos. Queremos criar uma nova entrada em nosso banco de dados quando alguém enviar um formulário. Uma solicitação HTTP tem um método, alguns cabeçalhos (metadados sobre suas solicitações, aqui estamos dizendo que a solicitação terá conteúdo JSON com o cabeçalho Content-Typ) e um corpo. O corpo da nossa solicitação será um texto JSON.
|
1 2 3 4 5 6 7 |
const response = await fetch("/.netlify/functions/saveform", { method: 'POST', <1> headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(value), <2> }) |
|
1 2 |
<1> We change the HTTP method to POST because we want to change something instead of just retrieving information. <2> A request can also have a body. Here we are sending a text version of our JSON object. |
Nossa solicitação HTTP do frontend para o backend foi alterada, agora precisamos adaptar o código do backend.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
const handler = async (event) => { try { var data = JSON.parse(event.body); <1> return { statusCode: 200, body: JSON.stringify({ name: data.name }) <2> } } catch (error) { return { statusCode: 500, body: error.toString() } } } module.exports = { handler } |
|
1 2 |
<1> The event object allows us to get the body of the request. It's text, we can parse this text into a JSON object and assign it to the field called `data`. <2> To make sure we did receive our JSON object, we change the returned message and use the field `data.name`. |
Você deverá ver uma mensagem diferente no console de desenvolvimento da Web, ou seja, deverá ver {"name": "yourName"}.
Enviamos os dados do formulário para o backend e nos certificamos disso. Agora vamos para o lado do banco de dados. Trabalhando no Couchbase, esse é o banco de dados que vou usar. Uma maneira simples de tentar, vá para https://cloud.couchbase.com/sign-upSe você criar uma conta, terá uma avaliação de 30 dias, sem necessidade de cartão de crédito.

Você pode deixar o padrão ativado ou escolher seu provedor de nuvem favorito e a região mais próxima. Clique em Implantar agora e aguarde a implantação do seu banco de dados.

Duas coisas que queremos fazer a partir daí. Garantir que possamos nos conectar a esse banco de dados a partir do nosso código de backend e garantir que possamos gravar os dados em algum lugar. Vá em frente e clique no botão Conectar guia.
No Couchbase, armazenamos dados em Buckets. Por padrão, a avaliação vem com um bucket de amostra de viagem pré-importado. Não vamos usá-lo. Em vez disso, vamos criar nosso próprio bucket. Clique em Configurações no menu de nível superior, do que em Baldes no menu à esquerda.

Agora, clique em + Criar baldedê um nome a ele e deixe o restante com as configurações padrão. Criar balde.

Temos um novo Bucket, agora precisamos criar as credenciais associadas. Clique no botão Acesso ao banco de dados do que Criar acesso ao banco de dados botão.


Certifique-se de lembrar o nome de usuário e a senha e clique em Criar banco de dados. Uma última coisa a fazer é permitir que esse banco de dados possa ser acessado publicamente. No momento, ele está oculto. Clique em Endereços IP permitidosdo que Adicionar IP permitido. Clique em Permitir acesso De qualquer lugare siga as instruções. O formulário deverá ser preenchido previamente e, em seguida, clique no botão Adicionar IP permitido botão. Você pode achar que isso é um pouco complicado. Por que ele não é o padrão?


Agora, clique no ícone Conectar guia. Você verá a guia Cadeia de conexãoselecione as credenciais do banco de dados, altere o idioma para Node e ele nos dará as instruções corretas para nos conectarmos ao banco de dados a partir do nosso código de backend.

Podemos copiar e colar isso em nosso código de função e adicionar mais algumas coisas:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
const crypto = require("crypto"); <1> const couchbase = require("couchbase"); <2> const handler = async (event) => { try { const clusterConnStr = "couchbases://cb.ar0qqwli6cczm1u.cloud.couchbase.com"; // Replace this with Connection String <3> const username = "Adminstrator"; // Replace this with username from database access credentials <3> const password = "Couch#123"; // Replace this with password from database access credentials <3> // Get a reference to the cluster const cluster = await couchbase.connect(clusterConnStr, { <4> username: username, password: password, // Use the pre-configured profile below to avoid latency issues with your connection. configProfile: "wanDevelopment", }); const bucket = cluster.bucket("surveyform"); <5> const collection = bucket.defaultCollection(); <6> var data = JSON.parse(event.body); let result = await collection.insert(crypto.randomUUID(), data); <7> return { statusCode: 200, body: JSON.stringify({ name: data.name }) } } catch (error) { console.log(error); return { statusCode: 500, body: error.toString() } } } module.exports = { handler } |
|
1 2 |
<1> You can see we have two new dependencies to our project. The 'crypto' package is provided by node. It allows us to generate a random identifier for our document <2> The 'couchbase' package is the Couchbase NodeJS SDK. It's every bit of code you need to connect to a Couchbase database. This projects are also often called drivers for other databases, or clients. |
Para o Couchbase, você precisa instalá-lo. Em execução npm i couchbase@4.2.4 será suficiente. No momento, a compatibilidade Netlify/Couchbase é garantida para o Couchbase versão 4.2.4 ou inferior. Isso se deve à natureza do nosso SDK. Trata-se de uma interface JavaScript sobre o nosso SDK em C. E as dependências C esperam encontrar suas dependências de sistema na versão correta. No momento, o Couchbase 4.2.5 está esperando encontrar GLIBC_29 mas ele não está disponível no sistema Ubuntu que executa nosso código de back-end do Netlify.
Agora que temos dependências, vamos ser explícitos em como criá-las. Você pode adicionar um netlify.toml na raiz do repositório com o seguinte conteúdo:
|
1 2 3 |
[build] command = "npm install && strip --strip-debug ./node_modules/couchbase/build/Release/couchbase_impl.node" publish = "." |
Ele está fazendo algumas coisas. Instalar as dependências e remover a tabela de símbolos de depuração de couchbase_impl.node. Esse arquivo é a biblioteca C usada pelo nosso Node SDK. E ele é muito grande para o Netlify no momento. Portanto, estamos removendo a bagunça desnecessária proveniente do processo de compilação.
|
1 2 3 4 5 |
<3> This variables are the informations needed for the SDK to connect to the cluster. A connections string, a username and a password. <4> `couchbase.connect` takes the connection string as first parameter, than a JSON object with username, password and other options. Here we also give the `wanDevelopment` config profiles. It will increase the default timeout values of all Couchbase operations. Basically if your connection is slow it won't scream at you. <5> From the Cluster object we get a Bucket. A bucket is where we store Scopes and Collections. Here we get the `surveyform` bucket. It already has a default scope and a default collection. <6> From the bucket we can get the default Collection. A Collection is where we store Document, or key/value pairs. Think of the key as the identifier of the document, and the value as your JSON data. But it could be anything else. <7> From the collection object, we call the insert method. It takes two parameters, the key and the value. So we call the randomUUID() method from the crypto package, to generate a random identifier. And we pass the data object as value. It contains our JSON. This function is asynchronous, it's making a request to the Couchbase Capella cluster. We await for the cluster's response. |
Agora você poderia adicionar os novos arquivos, fazer o commit e enviar para o GitHub. Mas isso enviaria sua senha para o GitHub. Não queremos isso. Em vez disso, você pode testá-lo executando desenvolvimento da netlify. Continue e reenvie o formulário.
Se tudo correu bem, você gravou dados em seu banco de dados! Você pode verificar isso facilmente acessando a interface do usuário do Couchbase Capella. Clique em Ferramentas de dadosSelecione seu Bucket, Scope e collection, e você verá sua pesquisa no documento.
Isso é ótimo, você acabou de escrever um código para conectar seu banco de dados!
Etapa 5 - Gerenciamento de configuração
Para evitar o envio de nossas credenciais para o GitHub, usaremos variáveis de ambiente. As variáveis de ambiente são comuns a todos os sistemas operacionais e são a melhor maneira de gerenciar a configuração em diferentes ambientes (diferentes sistemas operacionais, nuvens, testes, preparação, pré-produção, produção, o que for adequado ao seu fluxo de trabalho).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.... const ENDPOINT = process.env.COUCHBASE_ENDPOINT || "couchbase://localhost"; <1> const USERNAME = process.env.COUCHBASE_USERNAME || "Administrator";<1> const PASSWORD = process.env.COUCHBASE_PASSWORD || "password";<1> const BUCKET = process.env.COUCHBASE_BUCKET || "surveyform"<1> const handler = async (event) => { try { const clusterConnStr = ENDPOINT; // Replace this with Connection String const username = USERNAME; // Replace this with username from database access credentials const password = PASSWORD; // Replace this with password from database access credentials // Get a reference to the cluster const cluster = await couchbase.connect(clusterConnStr, { usernme: username, password: password, // Use the pre-configured profile below to avoid latency issues with your connection. configProfile: "wanDevelopment", }); const bucket = cluster.bucket(BUCKET); ... |
|
1 |
<1> The process object is always available with node so no need for a specific library import. Using || allows to provide a default value for each variable if they are not defined. |
No Mac ou Linux, você pode executar export MYVARIABLE="value" em seu terminal. No Windows, você pode executar $Env:MYVARIABLE="value"
Para defini-los no contexto da Netlify, você pode acessar a interface do usuário e fazer isso manualmente ou usar a CLI:
|
1 2 3 4 |
netlify env:set COUCHBASE_ENDPOINT couchbases://cb.ar0qqwli6cczm1u.cloud.couchbase.com netlify env:set COUCHBASE_USERNAME Administrator netlify env:set COUCHBASE_PASSWORD password netlify env:set COUCHBASE_BUCKET surveyform |
Agora você pode adicionar seus arquivos, confirmar e enviar seu código. Parabéns, você fez o fullstack. Back-end, front-end e banco de dados. E implantou tudo ao vivo! Mas nosso trabalho ainda não terminou. Ainda há algumas coisas que podemos fazer para tornar isso mais profissional.
Etapa 6 - Feedback do usuário
No momento, não há muita coisa acontecendo quando o usuário clica no botão Enviar do nosso formulário. Precisamos alterar isso para que eles saibam que foram registrados com sucesso ou não. A primeira etapa é verificar se há um erro no lado do desenvolvimento. O código de status HTTP é bem feito, qualquer coisa igual ou superior a 400 geralmente é um erro, portanto, podemos fazer algo assim:
|
1 2 3 4 5 |
if (response.status >= 400) { <1> console.log("Something when wrong"); <2> console.log(await response.text()); <3> return false; } |
|
1 2 3 |
<1> Status code that starts with 4 usually means something went wrong on the client side. The wrong data was sent, the client does not have the right permission, the page does not exist etc... Here we test if the code is equals or higher than 400. <2> If it is, we log a message in the console <3> We also log the error message returned by the server |
Para testá-lo, basta cometer um erro de digitação em algum lugar da cadeia de conexão ou das credenciais do Couchbase. Você deverá ver erros no console da Web ao clicar em Enviar. Mas o console da Web é apenas para nós, precisamos adicionar uma mensagem de erro ou de sucesso adequada ao nosso usuário.
Adicionei alguns elementos HTML de extensão com mensagens de erro e sucesso logo antes do final do formulário. Observe o esconder Classe CSS que os torna invisíveis por enquanto.
|
1 2 3 4 5 6 7 8 |
... </div> <span id="form-error" class="error-message hide"></span> <span id="thank-you-message" class="hide"> Your participation has been recorded, thank you!. </span> </form> ... |
E aqui está o CSS correspondente. Exibindo o erro em vermelho, ocultando ou exibindo um elemento, e uma bela animação de fade-out, porque eu sou chique assim.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
.container .error-message { color: red; } .hide { display: none; } .show { display: block; } .fade-out { animation: fadeOut ease 8s; -webkit-animation: fadeOut ease 8s; -moz-animation: fadeOut ease 8s; -o-animation: fadeOut ease 8s; -ms-animation: fadeOut ease 8s; }@keyframes fadeOut { 0% { opacity:1; } 100% { opacity:0; } } @-moz-keyframes fadeOut { 0% { opacity:1; } 100% { opacity:0; } } @-webkit-keyframes fadeOut { 0% { opacity:1; } 100% { opacity:0; } } @-o-keyframes fadeOut { 0% { opacity:1; } 100% { opacity:0; } } @-ms-keyframes fadeOut { 0% { opacity:1; } 100% { opacity:0; display: none; } |
Agora vamos juntar tudo. As duas primeiras linhas obtêm os novos elementos de extensão que acabaram de ser adicionados. A chamada para form.reset() está limpando todos os valores do formulário quando o código de status da resposta retornada é 200. Depois, o resto é brincar com as classes CSS para fazer com que a mensagem apareça, depois desaparecer com a adição da classe fade-out, depois uma função de tempo limite de 7000 ms removerá todas as classes e ocultará o elemento novamente. É praticamente a mesma coisa quando há um erro.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
const thankYouMessage = document.getElementById('thank-you-message'); <1> const formError = document.getElementById("form-error"); <1> if (response.status == 200) { form.reset(); <2> thankYouMessage.classList.add('show'); <3> thankYouMessage.classList.add('fade-out'); <3> setTimeout(function(){thankYouMessage.classList.remove('fade-out');thankYouMessage.classList.remove('show');}, 7000); <3> console.log(await response.text()); return false; } if (response.status >= 400) { console.log("Something when wrong"); console.log(await response.text()); formError.textContent = "Something went wrong while recording your contact."; <4> formError.classList.toggle('show'); <4> formError.classList.toggle('fade-out'); <4> setTimeout(function(){formError.classList.toggle('fade-out');formError.classList.toggle('show');}, 7000); <4> return false; } |
|
1 2 3 4 |
<1> We assign our new spans to variables <2> If things went well, we reset the form's data, it shows to the user that it worked. <3> We first add a CSS class that shows the error message, than apply the fade-out CSS class, than call the timeout function. In 7000 ms, the fade-out and show CSS class will be removed, hiding the success message again. <4> We do the same thing when there is an error, using the formError HTML element instead. |
Agora você pode testar o envio de um formulário novamente e ver a mensagem de sucesso ou de erro diferente, dependendo do que você decidiu fazer. Quando estiver satisfeito, você poderá adicionar, confirmar e enviar esse código.
Parabéns, você chegou até o final deste guia! Você usou o git, o GitHub, o Netlify e o Couchbase Capella para implantar um formulário HTML na Web e certificou-se de que o conteúdo fosse armazenado em um banco de dados sempre que os usuários enviassem o formulário.
Pronto para mais?
-
- Confira Recursos para desenvolvedores do Couchbase: aplicativos de amostra, código e tutoriais.
- Participe de nossa Centro Comunitário para usar o Discord, os fóruns e muito mais.
