Guia do iniciante para desenvolvimento de servidores Web com Node.js

Durante a maior parte da minha carreira na web, trabalhei exclusivamente no lado do cliente. Projetando layouts adaptáveis, criando visualizações de grandes quantidades de dados, criando painéis de aplicativos etc. Mas nunca tive que lidar diretamente com solicitações de roteamento ou HTTP. Até recentemente.

Esta postagem é uma descrição de como eu aprendi mais sobre o desenvolvimento da Web do lado do servidor usando o Node.js. e uma breve comparação de como escrever um servidor HTTP simples usando 3 ambientes diferentes, Express, Koa.js e Hapi.js.

Nota: se você é um desenvolvedor experiente do Node.js., provavelmente pensará que tudo isso é elementar / simples. ¯ \ _ (ツ) _ / ¯.

Alguns princípios básicos da rede


Quando comecei a trabalhar na indústria da Web há alguns anos, deparei-me com um curso sobre redes de computadores do professor David Veteral no Coursera. Infelizmente, ele não está mais disponível, mas as palestras ainda estão disponíveis no site da Pearson .

Gostei muito deste curso, porque explicava o que estava acontecendo sob o capô de uma maneira compreensível; portanto, se você puder pegar o livro de Computer Networks , leia todos os detalhes sobre as maravilhas da rede.

imagem

Aqui, porém, vou falar apenas brevemente sobre o contexto. HTTP (Hypertext Transfer Protocol) é um protocolo de comunicação usado em redes de computadores. Existem muitos na Internet, como SMTP (Simple Mail Transfer Protocol) , FTP (File Transfer Protocol) , POP3 (Post Office Protocol 3) e assim por diante.

Esses protocolos permitem que dispositivos com hardware / software completamente diferentes se comuniquem, pois fornecem formatos de mensagem, regras, sintaxe e semântica bem definidos, etc. Isso significa que, embora o dispositivo suporte um protocolo específico, ele pode se comunicar com qualquer outro dispositivo. na rede.

imagem
Do TCP / IP vs OSI: qual é a diferença entre os dois modelos?

Os sistemas operacionais geralmente vêm com suporte para protocolos de rede, como HTTP, prontos para uso, o que explica por que não precisamos instalar explicitamente nenhum software adicional para acessar a Internet. A maioria dos protocolos de rede suporta uma conexão aberta entre dois dispositivos, o que lhes permite transferir dados para frente e para trás.

O HTTP no qual a rede é executada é diferente. É conhecido como protocolo sem conexão porque é baseado em um modo de operação de solicitação / resposta. Os navegadores da Web enviam solicitações ao servidor de imagens, fontes, conteúdo etc., mas depois que a solicitação é concluída, a conexão entre o navegador e o servidor é desconectada.

imagem

Servidores e Clientes


O termo servidor pode ser um pouco confuso para as pessoas que são novas na indústria pela primeira vez, pois pode se referir tanto ao hardware (computadores físicos que hospedam todos os arquivos e software exigidos pelos sites) quanto ao software (um programa que permite que os usuários acessem esses arquivos on-line).

Hoje vamos falar sobre o lado do software. Mas primeiro, algumas definições. O URL significa Universal Resource Locator e consiste em 3 partes: protocolo , servidor e o arquivo solicitado .

imagem
Estrutura de URL

O protocolo HTTP define vários métodos que o navegador pode usar para solicitar ao servidor que execute várias ações diferentes, sendo as mais comuns GET e POST. Quando um usuário clica em um link ou insere um URL na barra de endereços, o navegador envia uma solicitação GET ao servidor para recuperar o recurso especificado no URL.

O servidor deve saber como processar essa solicitação HTTP para receber o arquivo correto e enviá-lo de volta ao navegador que a solicitou. O software de servidor Web mais popular que lida com isso é o Apache e o NGINX .

imagem
Servidores da Web processam solicitações recebidas e respondem a elas de acordo

Ambos são pacotes de software de código aberto com todos os recursos que incluem recursos como esquemas de autenticação, reescrita de URL, registro e proxy, para citar apenas alguns. Apache e NGINX são escritos em C. Tecnicamente, você pode escrever um servidor da Web em qualquer idioma. Python , golang.org/pkg/net/http , Ruby , esta lista pode durar bastante tempo. É que alguns idiomas fazem certas coisas melhor que outros.

Criando um servidor HTTP com Node.js


O Node.js é um tempo de execução Javascript criado no mecanismo Javascript do Chrome V8 . Ele vem com um módulo http que fornece um conjunto de funções e classes para a construção de um servidor HTTP.

Para este servidor HTTP básico, também usaremos o sistema de arquivos , o caminho e a URL , que são módulos nativos do Node.js.

Comece importando os módulos necessários.

const http = require('http') //   HTTP-  Node.js const fs = require('fs') //      const path = require('path') //        const url = require('url') //     URL 

Também criaremos um dicionário do tipo MIME para que possamos atribuir o tipo MIME apropriado ao recurso solicitado com base em sua extensão. Uma lista completa dos tipos MIME pode ser encontrada na Internet Assigned Numbers Authority .

 const mimeTypes = { '.html': 'text/html', '.js': 'text/javascript', '.css': 'text/css', '.ico': 'image/x-icon', '.png': 'image/png', '.jpg': 'image/jpeg', '.gif': 'image/gif', '.svg': 'image/svg+xml', '.json': 'application/json', '.woff': 'font/woff', '.woff2': 'font/woff2' } 

Agora podemos criar um servidor HTTP com a função http.createServer() , que retornará uma nova instância do http.Server .

 const server = http.createServer() 

Passaremos a função do manipulador de solicitações para createServer() com os objetos de solicitação e resposta. Essa função é chamada uma vez toda vez que uma solicitação HTTP chega ao servidor.

 server.on('request', (req, res) => { //     }) 

O servidor é iniciado chamando o método de listen do objeto de server com o número da porta que queremos que o servidor escute, por exemplo, 5000 .

 server.listen(5000) 

O objeto de request é uma instância do IncomingMessage e nos permite acessar todas as informações sobre a solicitação, como status de resposta, cabeçalhos e dados.

O objeto de response é uma instância do ServerResponse , que é um fluxo gravável e fornece muitos métodos para enviar dados de volta ao cliente.

No manipulador de consultas, queremos fazer o seguinte:

  • Analise a solicitação recebida e processe-a sem extensões

     const parsedUrl = new URL(req.url, 'https://node-http.glitch.me/') let pathName = parsedUrl.pathname let ext = path.extname(pathName) //   URL    '/',   '/' //      URL    'Location' if (pathName !== '/' && pathName[pathName.length - 1] === '/') { res.writeHead(302, {'Location': pathName.slice(0, -1)}) res.end() return } //     ,  index.html //     «.html»       if (pathName === '/') { ext = '.html' pathName = '/index.html' } else if (!ext) { ext = '.html' pathName += ext } 

  • Execute algumas verificações elementares para determinar se o recurso solicitado existe e responder adequadamente

     //     ,       const filePath = path.join(process.cwd(), '/public', pathName) // ,       fs.exists(filePath, function (exists, err) { //     ,  404 Not Found if (!exists || !mimeTypes[ext]) { console.log('  : ' + pathName) res.writeHead(404, {'Content-Type': 'text/plain'}) res.write('404 Not Found') res.end() return } //        200 OK, //       res.writeHead(200, {'Content-Type': mimeTypes[ext]}) //        const fileStream = fs.createReadStream(filePath) fileStream.pipe(res) }) 


Todo o código está hospedado no Glitch, e você pode remixar o projeto, se desejar.

https://glitch.com/edit/#!/node-http

Criando um servidor HTTP com estruturas Node.js.


As estruturas do Node.js., como Express , Koa.js e Hapi.js, vêm com vários recursos úteis de middleware, além de muitos outros recursos úteis que evitam que os desenvolvedores precisem escrever por si mesmos.

Pessoalmente, sinto que é melhor primeiro aprender o básico sem estruturas, apenas para entender o que está acontecendo sob o capô e depois enlouquecer com qualquer estrutura que você gosta.

O Express tem seu próprio plug-in interno para veicular arquivos estáticos, portanto, o código necessário para executar as mesmas ações que em seu próprio Node.js é muito menor.

 const express = require('express') const app = express() //         app.use(express.static('public')) //  index.html,      //     res.sendFile() app.get('/', (req, res) => { res.sendFile(__dirname + '/public/index.html') }) app.listen(5000) 

O Koa.js não possui um plug-in semelhante em seu núcleo; portanto, qualquer plug-in necessário deve ser instalado separadamente. A versão mais recente do Koa.js usa funções assíncronas em favor dos retornos de chamada. Você pode usar o plugin koa-static para servir arquivos estáticos.

 const serve = require('koa-static') const koa = require('koa') const app = new koa() //         //   koa-static    index.html    app.use(serve(__dirname + '/public')) app.listen(5000) 

O Hapi.js suporta a personalização e gira em torno da personalização do objeto do server . Ele usa plug-ins para estender recursos como roteamento, autenticação e assim por diante. Para servir arquivos estáticos, precisamos de um plugin chamado inert .

 const path = require('path') const hapi = require('hapi') const inert = require('inert') //        const server = new hapi.Server({ port: 5000, routes: { files: { relativeTo: path.join(__dirname, 'public') } } }) const init = async () => { // server.register()      await server.register(inert) // inert     //       server.route({ method: 'GET', path: '/{param*}', handler: { directory: { path: '.', redirectToSlash: true, index: true } } }) await server.start() } init() 

Cada uma dessas plataformas tem seus prós e contras, e serão mais óbvias para aplicativos maiores, e não apenas para servir uma única página HTML. A escolha da estrutura dependerá muito dos requisitos reais do projeto em que você está trabalhando.

Conclusão


Se o lado da rede sempre foi uma caixa preta para você, espero que este artigo possa servir como uma introdução útil ao protocolo que fornece a rede. Também recomendo a leitura da documentação da API do Node.js. , que é muito bem escrita e muito útil para qualquer iniciante no Node.js. em geral.

Source: https://habr.com/ru/post/pt435970/


All Articles