feat: add 'back/front end' in curriculum (#42596)

* chore: rename APIs and Microservices to include "Backend" (#42515)

* fix typo

* fix typo

* undo change

* Corrected grammar mistake

Corrected a grammar mistake by removing a comma.

* change APIs and Microservices cert title

* update title

* Change APIs and Microservices certi title

* Update translations.json

* update title

* feat(curriculum): rename apis and microservices cert

* rename folder structure

* rename certificate

* rename learn Markdown

* apis-and-microservices -> back-end-development-and-apis

* update backend meta

* update i18n langs and cypress test

Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>

* fix: add development to front-end libraries (#42512)

* fix: added-the-word-Development-to-front-end-libraries

* fix/added-the-word-Development-to-front-end-libraries

* fix/added-word-development-to-front-end-libraries-in-other-related-files

* fix/added-the-word-Development-to-front-end-and-all-related-files

* fix/removed-typos-from-last-commit-in-index.md

* fix/reverted-changes-that-i-made-to-dependecies

* fix/removed xvfg

* fix/reverted changes that i made to package.json

* remove unwanted changes

* front-end-development-libraries changes

* rename backend certSlug and README

* update i18n folder names and keys

* test: add legacy path redirect tests

This uses serve.json from the client-config repo, since we currently use
that in production

* fix: create public dir before moving serve.json

* fix: add missing script

* refactor: collect redirect tests

* test: convert to cy.location for stricter tests

* rename certificate folder to 00-certificates

* change crowdin config to recognise new certificates location

* allow translations to be used

Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>

* add forwards slashes to path redirects

* fix cypress path tests again

* plese cypress

* fix: test different challenge

Okay so I literally have no idea why this one particular challenge
fails in Cypress Firefox ONLY. Tom and I paired and spun a full build
instance and confirmed in Firefox the page loads and redirects as
expected. Changing to another bootstrap challenge passes Cypress firefox
locally. Absolutely boggled by this.

AAAAAAAAAAAAAAA

* fix: separate the test

Okay apparently the test does not work unless we separate it into
a different `it` statement.

>:( >:( >:( >:(

Co-authored-by: Sujal Gupta <55016909+heysujal@users.noreply.github.com>
Co-authored-by: Noor Fakhry <65724923+NoorFakhry@users.noreply.github.com>
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
This commit is contained in:
Shaun Hamilton
2021-08-14 03:57:13 +01:00
committed by GitHub
parent 4df2a0c542
commit c2a11ad00d
1215 changed files with 790 additions and 449 deletions

View File

@ -0,0 +1,79 @@
---
id: 587d7fb1367417b2b2512bf4
title: Encadear middleware para criar um servidor de tempo
challengeType: 2
forumTopicId: 301510
dashedName: chain-middleware-to-create-a-time-server
---
# --description--
O middleware pode ser montado em uma rota específica usando `app.METHOD(path, middlewareFunction)`. O middleware também pode ser encadeado nas definições de rota.
Observe o exemplo abaixo:
```js
app.get('/user', function(req, res, next) {
req.user = getTheUserSync(); // Hypothetical synchronous operation
next();
}, function(req, res) {
res.send(req.user);
});
```
Esse método é útil para separar as operações de servidor em pedaços menores. Isso fornece uma melhor estrutura de aplicativo, além da possibilidade de reusar código em partes diferentes. Esse método também pode ser usado para realizar algumas validações de dados. Em cada ponto da pilha de middleware, você poderá bloquear a execução da cadeia atual e passar o controle para funções específicas criadas especificamente para gerenciar erros. Você também pode passar o controle para a próxima rota correspondente, para gerenciar casos especiais. Veremos como fazer isso na seção avançada do Express.
# --instructions--
Na rota `app.get('/now', ...)`, encadeie uma função middleware e o handler final. Na função middleware, você deverá adicionar o tempo atual no objeto de requisição na chave `req.time`. Você pode usar `new Date().toString()`. No gerenciador, responda com um objeto JSON, pegando a estrutura `{time: req.time}`.
**Observação:** o teste não vai passar se você não encadear o middleware. Se você montar a função em algum outro lugar, o teste vai falhar, mesmo que o resultado final esteja correto.
# --hints--
O endpoint (URL) /now deve ter o middleware montado
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
(data) => {
assert.equal(
data.stackLength,
2,
'"/now" route has no mounted middleware'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
O endpoint (URL) /now deve retornar um horário que possui margem de erro de +/- 20 segundos a partir de agora
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/chain-middleware-time').then(
(data) => {
var now = new Date();
assert.isAtMost(
Math.abs(new Date(data.time) - now),
20000,
'the returned time is not between +- 20 secs from now'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,78 @@
---
id: 587d7fb2367417b2b2512bf8
title: Obter dados de solicitações de POST
challengeType: 2
forumTopicId: 301511
dashedName: get-data-from-post-requests
---
# --description--
Monte um handler POST no caminho `/name`. É o mesmo caminho de antes. Nós preparamos um formulário na página inicial html. Ele vai enviar os mesmos dados do exercício 10 (string de consulta). Se o body-parser estiver configurado corretamente, você deverá encontrar os parâmetros do objeto `req.body`. Dê uma olhada no exemplo habitual da biblioteca:
<blockquote>route: POST '/library'<br>urlencoded_body: userId=546&#x26;bookId=6754 <br>req.body: {userId: '546', bookId: '6754'}</blockquote>
Responda com o mesmo objeto JSON usado antes: `{name: 'firstname lastname'}`. Teste se seu endpoint (URL) funciona usando o formulário html que fornecemos na página inicial do aplicativo.
Dica: existem vários outros métodos http além de GET e POST. Por convenção, existem correspondências entre o verbo http e a operação que você vai executar no servidor. O mapeamento convencional é:
POST (às vezes, PUT) Cria um novo recurso usando a informação enviada com a requisição,
GET - Lê um recurso existente sem modificá-lo,
PUT ou PATCH (às vezes, POST) Atualiza um recurso usando os dados enviados,
DELETE=> Exclui um recurso.
Existem também alguns outros métodos que são usados para estabelecer uma conexão com o servidor. Com a exceção de GET, todos os outros métodos listados acima podem ter uma payload(carga) (exemplo: os dados enviados no corpo da requisição). O middleware body-parser também funciona com esses métodos.
# --hints--
Teste 1 : O endpoint (URL) da API deve responder com o nome correto
```js
(getUserInput) =>
$.post(getUserInput('url') + '/name', { first: 'Mick', last: 'Jagger' }).then(
(data) => {
assert.equal(
data.name,
'Mick Jagger',
'Test 1: "POST /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Teste 2: O endpoint da API deve responder com o nome correto
```js
(getUserInput) =>
$.post(getUserInput('url') + '/name', {
first: 'Keith',
last: 'Richards'
}).then(
(data) => {
assert.equal(
data.name,
'Keith Richards',
'Test 2: "POST /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,67 @@
---
id: 587d7fb2367417b2b2512bf6
title: Obter a entrada do parâmetro da consulta do client
challengeType: 2
forumTopicId: 301512
dashedName: get-query-parameter-input-from-the-client
---
# --description--
Outro jeito usual de obter a entrada do client é ao codificar os dados após o caminho da rota, usando uma string de consulta. A string de consulta é delimitada por um símbolo de interrogação (?) e inclui pares campo=valor. Cada par é separado por um e comercial(&). O Express pode analisar os dados da string de consulta e preencher o objeto `req.query`. Alguns caracteres, como o de porcentagem (%), não podem estar nos URLs e tem de ser codificados em um formato diferente antes que você os envie. Se você usa a API do JavaScript, você pode usar métodos específicos para codificar/decodificar esses caracteres.
<blockquote>route_path: '/library'<br>actual_request_URL: '/library?userId=546&#x26;bookId=6754' <br>req.query: {userId: '546', bookId: '6754'}</blockquote>
# --instructions--
Faça uma API de endpoint (URL), montada em `GET /name`. Responda com um documento JSON, pegando a estrutura `{ name: 'firstname lastname'}`. O parâmetros primeiro e último nome devem ser codificados em uma string de consulta como, por exemplo: `?first=firstname&last=lastname`.
**Observação:** no exercício seguinte, você vai receber dados de uma requisição POST, no mesmo caminho de rota `/name`. Se você quiser, poderá usar o método `app.route(path).get(handler).post(handler)`. Essa sintaxe permite a você encadear diferentes manipuladores do tipo verb no mesmo caminho de rota. Você vai economizar na digitação e ter um código mais limpo.
# --hints--
Teste 1: O endpoint (URL) da API deverá responder com o nome correto
```js
(getUserInput) =>
$.get(getUserInput('url') + '/name?first=Mick&last=Jagger').then(
(data) => {
assert.equal(
data.name,
'Mick Jagger',
'Test 1: "GET /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Teste 2 : O endpoint (URL) da API deve responder com o nome correto
```js
(getUserInput) =>
$.get(getUserInput('url') + '/name?last=Richards&first=Keith').then(
(data) => {
assert.equal(
data.name,
'Keith Richards',
'Test 2: "GET /name" route does not behave as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,65 @@
---
id: 587d7fb2367417b2b2512bf5
title: Obter a entrada do parâmetro de roteamento do client
challengeType: 2
forumTopicId: 301513
dashedName: get-route-parameter-input-from-the-client
---
# --description--
Ao construir uma API, temos que permitir que os usuários nos comuniquem o que querem obter com o nosso serviço. Por exemplo, se o client estiver solicitando informações sobre um usuário armazenado no banco de dados, ele precisa de um modo de nos informar em qual usuário ele está interessado. Uma maneira possível de alcançar este resultado é utilizando parâmetros de roteamento. Parâmetros de roteamento são segmentos nomeados do URL, delimitados por barras (/). Cada segmento captura o valor da parte do URL que corresponde à sua posição. Os valores capturados podem ser encontrados no objeto `req.params`.
<blockquote>route_path: '/user/:userId/book/:bookId'<br>actual_request_URL: '/user/546/book/6754' <br>req.params: {userId: '546', bookId: '6754'}</blockquote>
# --instructions--
Crie um servidor de eco, montado na rota `GET /:word/echo`. Responda com um documento JSON, pegando a estrutura `{echo: word}`. Você pode encontrar a palavra a ser repetida em `req.params.word`. Você pode testar sua rota através da barra de endereços do seu navegador, visitando algumas rotas correspondentes, como, por exemplo, `your-app-rootpath/freecodecamp/echo`.
# --hints--
Teste 1: o servidor de eco deve repetir palavras corretamente
```js
(getUserInput) =>
$.get(getUserInput('url') + '/eChOtEsT/echo').then(
(data) => {
assert.equal(
data.echo,
'eChOtEsT',
'Test 1: the echo server is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
Teste 2: o servidor de eco deve repetir palavras corretamente
```js
(getUserInput) =>
$.get(getUserInput('url') + '/ech0-t3st/echo').then(
(data) => {
assert.equal(
data.echo,
'ech0-t3st',
'Test 2: the echo server is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,57 @@
---
id: 587d7fb1367417b2b2512bf3
title: Implementar um middleware de solicitação ao nível de root
challengeType: 2
forumTopicId: 301514
dashedName: implement-a-root-level-request-logger-middleware
---
# --description--
Anteriormente, você apresentamos a você a função de middleware `express.static()`. Agora é hora de ver o que é o middleware, em mais detalhes. As funções de middleware são funções que recebem 3 argumentos: o objeto de solicitação, o objeto de resposta e a próxima função no ciclo de solicitação e resposta do aplicativo. Estas funções executam algum código que pode ter efeitos colaterais no aplicativo. Geralmente, elas adicionam informações aos objetos de solicitação ou resposta. Elas também podem acabar com o ciclo enviando uma resposta quando alguma condição é satisfeita. Se elas não enviarem a resposta quando terminarem, iniciam a execução da próxima função na pilha. Isso dispara o chamado do terceiro argumento, `next()`.
Observe o exemplo abaixo:
```js
function(req, res, next) {
console.log("I'm a middleware...");
next();
}
```
Vamos supor que você montou esta função em uma rota. Quando uma solicitação corresponde à rota, ela exibe a string "I'm a middleware…" e então executa a próxima função na pilha. Neste exercício, você vai criar um middleware ao nível de root. Como você viu no desafio 4, para montar uma função de middleware no nível de root, você pode usar o método `app.use(<mware-function>)`. Neste caso, a função será executada para todas as solicitações, mas você também pode definir condições mais específicas. Por exemplo, se você quiser que uma função seja executada somente para solicitações de POST, você poderia usar `app.post(<mware-function>)`. Existem métodos análogos para todos os verbos de HTTP (GET, DELETE, PUT, …).
# --instructions--
Crie um registrador simples. Para cada solicitação, ele deve registrar no console uma string com o seguinte formato: `method path - ip`. Um exemplo ficaria assim: `GET /json - ::ffff:127.0.0.1`. Note que há um espaço entre `method` e `path` e que o traço separando o `path` e `ip` está cercado por um espaço de ambos os lados. Você pode obter o método de solicitação (verbo do http), o caminho da rota relativo e o IP de quem fez a chamada a partir do objeto de solicitação usando `req.method`, `req.path` e `req.ip`. Lembre-se de chamar `next()` quando você estiver pronto, ou o servidor ficará travado para sempre. Certifique-se de que os 'Logs' estejam abertos e veja o que acontece quando algumas solicitações chegarem.
**Observação:** o Express avalia as funções na ordem em que elas aparecem no código. Isto se aplica também ao middleware. Se você quer que ele funcione para todas as rotas, é preciso montá-lo antes delas.
# --hints--
O middleware do registrador de root deve estar ativo
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/root-middleware-logger').then(
(data) => {
assert.isTrue(
data.passed,
'root-level logger is not working as expected'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,53 @@
---
id: 587d7fb0367417b2b2512bed
title: Conhecer o console do Node
challengeType: 2
forumTopicId: 301515
dashedName: meet-the-node-console
---
# --description--
Trabalhar nesses desafios vai fazer com que você escreva seu código usando um dos seguintes métodos:
- Clone [este repositório do GitHub](https://github.com/freeCodeCamp/boilerplate-express/) e complete esses desafios localmente.
- Use [nosso projeto inicial do Replit](https://replit.com/github/freeCodeCamp/boilerplate-express) para completar esses desafios.
- Use um construtor de site de sua escolha para completar o projeto. Certifique-se de incorporar todos os arquivos do nosso repositório no GitHub.
Quando terminar, certifique-se de que uma demonstração funcional do seu projeto está hospedada em algum lugar público. Em seguida, envie o URL para ela no campo `Solution Link`.
Durante o processo de desenvolvimento, é importante poder verificar o que está acontecendo no código.
O Node é apenas um ambiente JavaScript. Como o JavaScript lado do client, você pode usar o console para exibir informações úteis de depuração. Em sua máquina local, você veria a saída do console em um terminal. No Replit, um terminal está aberto no painel direito por padrão.
Recomendamos que o terminal continue aberto enquanto você trabalha nesses desafios. Ao ler a saída no terminal, você poderá ver os erros que podem ocorrer.
# --instructions--
Modifique o arquivo `myApp.js` para registrar "Hello World" no console.
# --hints--
`"Hello World"` deve estar no console
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/hello-console').then(
(data) => {
assert.isTrue(data.passed, '"Hello World" is not in the server console');
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,51 @@
---
id: 587d7fb0367417b2b2512bef
title: Servir um arquivo HTML
challengeType: 2
forumTopicId: 301516
dashedName: serve-an-html-file
---
# --description--
Você pode responder às solicitações com um arquivo usando o método `res.sendFile(path)`. Você pode colocá-lo dentro do manipulador de rota `app.get('/', ...)`. Nos bastidores, este método definirá os cabeçalhos apropriados para instruir o navegador sobre como lidar com o arquivo que você deseja enviar, de acordo com o tipo. Então, ele lerá e enviará o arquivo. Este método precisa de um caminho de arquivo absoluto. Recomendamos que use a variável global `__dirname` do Node para calcular o caminho assim:
```js
absolutePath = __dirname + relativePath/file.ext
```
# --instructions--
Envie o arquivo `/views/index.html` como uma resposta para solicitações de GET para o caminho `/`. Ao ver sua aplicação ao vivo, você deverá perceber um grande título em HTML (e um formulário, que usaremos mais tarde…), sem nenhum estilo aplicado.
**Observação:** você pode editar a solução do desafio anterior ou criar uma nova. Se você criar uma nova solução, tenha em mente que o Express avalia rotas de cima para baixo e executa o manipulador para a primeira correspondência. Você tem que deixar comentada a solução anterior, ou o servidor continuará respondendo com uma string.
# --hints--
O aplicativo deve servir o arquivo views/index.html
```js
(getUserInput) =>
$.get(getUserInput('url')).then(
(data) => {
assert.match(
data,
/<h1>.*<\/h1>/,
'Your app does not serve the expected HTML'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,47 @@
---
id: 587d7fb1367417b2b2512bf1
title: Servir JSON em uma rota específica
challengeType: 2
forumTopicId: 301517
dashedName: serve-json-on-a-specific-route
---
# --description--
Enquanto um servidor HTML serve arquivos em HTML, uma API serve dados. Uma API <dfn>REST</dfn> (Transferência de Estado Representacional) permite a troca de dados de uma maneira simples sem a necessidade de os clients saberem qualquer detalhe sobre o servidor. O client só precisa saber onde o recurso está (qual o seu URL) e a ação que quer realizar nele (o verbo). O verbo GET é usado quando você busca algumas informações, sem modificar nada. Hoje em dia, o formato de dados preferencial para mover informações pela web é o JSON. Simplificando, JSON é uma maneira conveniente de representar um objeto JavaScript como uma string, que então pode ser facilmente transmitido.
Vamos criar uma API simples, gerando uma rota que responda com JSON no caminho `/json`. Você pode fazer isso como de costume, com o método `app.get()`. Dentro do manipulador de rota, use o método `res.json()`, passando um objeto como um argumento. Este método fecha o loop de solicitação-resposta, retornando os dados. Nos bastidores, ele converte um objeto JavaScript válido em uma string. Em seguida, define os cabeçalhos apropriados para dizer ao navegador que você está servindo JSON e envia os dados de volta. Um objeto válido tem a estrutura usual `{key: data}`. `data` pode ser um número, uma string, um objeto aninhado ou um array. `data` também podem ser uma variável ou o resultado de uma chamada de função. Nesse caso, ele será avaliado antes de ser convertido em uma string.
# --instructions--
Sirva o objeto `{"message": "Hello json"}` como uma resposta, no formato JSON, para solicitações de GET feitas à rota `/json`. Em seguida, aponte o navegador para `your-app-url/json`. Você deverá ver a mensagem na tela.
# --hints--
O `/json` do endpoint deve servir o objeto json `{"message": "Hello json"}`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/json').then(
(data) => {
assert.equal(
data.message,
'Hello json',
"The '/json' endpoint does not serve the right data"
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,51 @@
---
id: 587d7fb0367417b2b2512bf0
title: Servir ativos estáticos
challengeType: 2
forumTopicId: 301518
dashedName: serve-static-assets
---
# --description--
Um servidor HTML geralmente tem um ou mais diretórios acessíveis pelo usuário. Você pode colocar lá os recursos estáticos necessários para a aplicação (folhas de estilos, scripts e imagens).
No Express, você pode colocar esta funcionalidade usando o middleware `express.static(path)`, onde o parâmetro `path` é o caminho absoluto da pasta que contém os arquivos.
Se você não sabe o que é um middleware... não se preocupe. Discutiremos isso em detalhes mais tarde. Basicamente, middleware são funções que interceptam manipuladores da rota, adicionando algum tipo de informação. Um middleware precisa ser montado usando o método `app.use(path, middlewareFunction)`. O primeiro argumento, `path`, é opcional. Se você não passar esse argumento, o middleware será executado em todas as solicitações.
# --instructions--
Monte o middleware `express.static()` para o caminho `/public` com `app.use()`. O caminho absoluto para a pasta de arquivos é `__dirname + /public`.
Agora, seu aplicativo deve ser capaz de servir uma folha de estilos de CSS. Observe que o arquivo `/public/style.css` é referenciado em `/views/index.html` no boilerplate do projeto. A página inicial deve estar um pouco melhor agora!
# --hints--
Seu aplicativo deve servir arquivos de ativos do diretório `/public` no caminho `/public`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/public/style.css').then(
(data) => {
assert.match(
data,
/body\s*\{[^\}]*\}/,
'Your app does not serve static assets'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,57 @@
---
id: 587d7fb0367417b2b2512bee
title: Iniciar um servidor de Express funcional
challengeType: 2
forumTopicId: 301519
dashedName: start-a-working-express-server
---
# --description--
Nas duas primeiras linhas do arquivo `myApp.js`, você pode ver como é fácil criar um objeto do aplicativo Express. Este objeto tem vários métodos e você aprenderá muitos deles nestes desafios. Um método fundamental é o `app.listen(port)`. Ele diz ao servidor para que escute em uma determinada porta, colocando-o em estado de execução. Para fins de teste, precisamos que o aplicativo esteja sendo executado em segundo plano para que adicionemos este método no arquivo `server.js` para você.
Vamos servir nossa primeira string! No Express, as rotas têm a seguinte estrutura: `app.METHOD(PATH, HANDLER)`. METHOD é um método http em letras minúsculas. PATH é um caminho relativo no servidor (pode ser uma string ou até mesmo uma expressão regular). HANDLER é uma função que o Express chama quando a rota tem correspondência. Os manipuladores têm o formato `function(req, res) {...}`, onde req é o objeto solicitado, e res é o objeto de resposta. Por exemplo, o manipulador
```js
function(req, res) {
res.send('Response String');
}
```
servirá a string 'Response String'.
# --instructions--
Use o método `app.get()` para servir a string "Hello Express" para solicitações de GET que correspondam ao caminho `/` (root). Certifique-se de que seu código funciona olhando os logs e, em seguida, veja os resultados na pré-visualização se você estiver usando o Replit.
**Observação:** todo o código para estas lições deve ser adicionado entre as poucas linhas de código que fornecemos para você no início.
# --hints--
Seu aplicativo deve servir a string 'Hello Express'
```js
(getUserInput) =>
$.get(getUserInput('url')).then(
(data) => {
assert.equal(
data,
'Hello Express',
'Your app does not serve the text "Hello Express"'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,63 @@
---
id: 587d7fb2367417b2b2512bf7
title: Usar o body-parser para analisar solicitações de POST
challengeType: 2
forumTopicId: 301520
dashedName: use-body-parser-to-parse-post-requests
---
# --description--
Além do GET, existe um outro verbo comum de HTTP, o POST. POST é o método padrão usado para enviar dados do client com formulários HTML. Na convenção de REST, POST é usado para enviar dados para criar novos itens no banco de dados (um novo usuário, ou um nova publicação no blog). Você não tem um banco de dados neste projeto, mas vai aprender como lidar com solicitações de POST, mesmo assim.
Nesse tipo de solicitação, os dados não aparecem no URL. Eles estão ocultos no corpo da solicitação. O corpo (body) é uma parte da solicitação do HTTP, também chamada de payload. Mesmo que os dados não sejam visíveis no URL, isso não significa que sejam privados. Para saber o porquê, consulte o conteúdo bruto de uma solicitação de POST de HTTP:
```http
POST /path/subpath HTTP/1.0
From: john@example.com
User-Agent: someBrowser/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
name=John+Doe&age=25
```
Como você pode ver, o body é codificado como a string de consulta. Este é o formato padrão usado pelos formulários de HTML. Com o Ajax, você também pode usar JSON para tratar os dados tendo uma estrutura mais complexa. Existe também um outro tipo de codificação: multipart/form-data. Esta é usada para enviar arquivos binários. Neste exercício, você usará um body urlencoded. Para analisar os dados provenientes de solicitações de POST, você deve instalar o pacote `body-parser`. Este pacote permite que você use uma série de middleware, que pode decodificar os dados em diferentes formatos.
# --instructions--
Instale o módulo `body-parser` no `package.json`. Em seguida, faça o `require` dele no topo do arquivo. Armazene-o em uma variável chamada `bodyParser`. O middleware para manipular dados urlencoded é retornado por `bodyParser.urlencoded({extended: false})`. Passe a função retornada pela chamada do método anterior para `app.use()`. Como sempre, o middleware deve ser montado antes de todas as rotas que dependem dele.
**Observação:** `extended` é uma opção de configuração que informa ao `body-parser` que a análise (parsing) precisa ser usada. Quando `extended=false` ele usa a biblioteca clássica de codificação, `querystring`. Quando `extended=true` ele usa a biblioteca `qs` para a análise.
Ao usar `extended=false`, os valores podem ser apenas strings ou arrays. O objeto retornado ao usar `querystring` não herda prototipicamente do `Object` de JavaScript padrão, o que significa que funções como `hasOwnProperty` e `toString` não estarão disponíveis. A versão estendida permite mais flexibilidade aos dados, mas é superada por JSON.
# --hints--
O middleware 'body-parser' deve estar montado
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/add-body-parser').then(
(data) => {
assert.isAbove(
data.mountedAt,
0,
'"body-parser" is not mounted correctly'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```

View File

@ -0,0 +1,52 @@
---
id: 587d7fb1367417b2b2512bf2
title: Usar o arquivo .env
challengeType: 2
forumTopicId: 301521
dashedName: use-the--env-file
---
# --description--
O arquivo `.env` é um arquivo oculto que é usado para passar variáveis de ambiente para seu aplicativo. Este arquivo é secreto, ninguém além de você pode acessá-lo. Ele pode ser usado para armazenar dados que você deseja manter privados ou ocultos. Por exemplo, você pode armazenar chaves da API de serviços externos ou o URI do seu banco de dados. Você também pode usá-lo para armazenar as opções de configuração. Ao definir as opções de configuração, você pode alterar o comportamento de sua aplicação sem a necessidade de reescrever algum código.
As variáveis de ambiente podem ser acessadas pelo aplicativo usando `process.env.VAR_NAME`. O objeto `process.env` é um objeto global do Node e suas variáveis são passadas como strings. Por convenção, os nomes de variáveis ficam todos em letras maiúsculas, com palavras separadas por um sublinhado. O `.env` é um arquivo shell. Assim, você não precisa encapsular nomes ou valores entre aspas. Também é importante notar que não pode haver espaço em torno do sinal de igual quando você estiver atribuindo valores às suas variáveis, como, por exemplo, `VAR_NAME=value`. Normalmente, você colocará cada definição de variável em uma linha separada.
# --instructions--
Vamos adicionar uma variável de ambiente como uma opção de configuração.
Crie um arquivo `.env` na raiz do diretório do seu projeto e armazene a variável `MESSAGE_STYLE=uppercase` nele.
Em seguida, no manipulador de rota `/json` do GET que você criou no último desafio, transforme a mensagem do objeto de resposta em letras maiúsculas com `process.env.MESSAGE_STYLE` é igual a `uppercase`. O objeto de resposta deve ser `{"message": "Hello json"}` ou `{"message": "HELLO JSON"}`, dependendo do valor de `MESSAGE_STYLE`.
**Observação:** se você estiver usando o Replit, você não poderá criar um arquivo `.env`. Em vez disso, use a aba embutida <dfn>SECRETS</dfn> para adicionar a variável.
# --hints--
A resposta do endpoint `/json` deve ser alterada de acordo com a variável de ambiente `MESSAGE_STYLE`
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/use-env-vars').then(
(data) => {
assert.isTrue(
data.passed,
'The response of "/json" does not change according to MESSAGE_STYLE'
);
},
(xhr) => {
throw new Error(xhr.responseText);
}
);
```
# --solutions--
```js
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
```