# HTTP O que é o protocolo `HTTP`? O protocolo `HTTP`, Hypertext Transfer Protocol, é um protocolo de mensagens que permite primeiramente a obtenção recursos de um servidor, mas é e deve ser utilizado também para alteração e criação de novos recursos de um servidor. Funciona como base da internet hoje e cria uma relação sem estado de cliente-servidor; Surgiu em 1991 com Tim Berners-Lee no CERN, versão 1.1 foi documentada em 1997; Alguns pontos importantes: - Clientes e servidores trocam mensagens individuais e 'sem estado'; - Relação de `requisições` e `respostas`; - Um cliente faz uma requisição de algum recurso e o servidor responde; Como um pedido (requisição) HTTP é anatomicamente? ```bash= GET / HTTP/1.1 Host: github.com Content-Type: text/html . . . ...headers ``` Fomos por cada linha, ```bash= GET / HTTP/1.1 ``` Nesta primeira linha, temos três informações importantes: a primeira delas é o método que estamos utilizando, neste caso `GET`. Existem muitos métodos quando utiliza-se o protocolo, entre eles os mais usuais são: 1. `GET` Método utilizado para solicitação de um recurso específico, como obter o html de uma página ou um documento de um URL, o acesso a qualquer página pelo browser também é um exemplo. 2. `POST` O método POST é utilizado para enviar uma informação a um recurso específico, o que normalmente envolve alteração de estado dentro do servidor. 4. `PUT` O método `PUT` é utilizado para atualizar por inteiro uma entidade dentro do servidor. 6. `PATCH` Enquanto o `PATCH` atualiza parcialmente uma intidade dentro do servidor. 8. `DELETE` `DELETE` remove uma entidade por completo no servidor. A partir segunda linha, temos o início dos headers, que são configurações ou identificadores para serem utilizados de alguma forma pelo servidor. Deles, temos dois importantes: 1. `Host` que é para quem estamos pedindo resposta; 2. `Content-Type` que o tipo de recurso que estamos pedindo resposta, por exemplo; Note que eles possuem uma estrutura similar: ```bash= Header-Name: Valor ``` Se estivessemos criando um servidor `HTTP` apenas sem node, como provavelmente a gente começaria? ```typescript let request = `GET / HTTP/1.1 Host: github.com Content-Type: text/html`; request = request.split("\n"); ``` ```bash= [ 'GET / HTTP/1.1', 'Host: github.com', 'Content-Type: text/html`', ] ``` Depois poderiamos por exemplo: ```typescript const [ head, ...headers ] = request; const [ method, path, version ] = head.split(' '); ``` _Você consegue imaginar o valor dessas variáveis?_ E para uma resposta `HTTP`, como ela é? ``` HTTP/1.1 200 OK Date: Sat, 09 Oct 2010 14:28:02 GMT Server: Apache Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT Accept-Ranges: bytes Content-Length: 29769 Content-Type: text/html <!DOCTYPE html.. ``` No mesmo sentindo, indo por cada linha temos na primeira: ```bash= HTTP/1.1 200 OK ``` Note que a resposta em particular possui a primeira linha diferente, ela descreve algumas coisas: 1. A versão do método que estamos utilizando; 2. O HTTP Code da resposta 3. E a HTTP message associada ao HTTP Code; De um modo geral temos diversos códigos HTTP e eles andam em par com sua mensagens. Para a faixa de sucesso, temos alguns como: | HTTP Code | HTTP Message | | --------- | ------------ | | 200 | OK | | 201 | Created | | 204 | No Content | Para as faixas de erro, temos também alguns como: | HTTP Code | HTTP Message | | --------- | ------------ | | 400 | Bad Request | | 401 | Unauthorized | | 403 | Forbidden | | 404 | Not Found | E as faixas de erros internos de servidor estão nas faixas `500`, como o próprio `500 - Internal Server Error`. Como notado, os únicos pontos de contato entre cliente e servidor estão com as requisições e respostas. Falamos também que elas são sem estado, elas por si só possuem um ciclo de vida até serem recebidas. No entanto, é importante que retornemos as informações suficientes e necessárias para que as ações sejam executadas como queremos no back-end e sejam tratadas pelo clientes. Poderiamos portanto `parsear` sobre todo o conteúdo e nossa tratativa em caso de erro no parser teria como resposta: ``` HTTP/1.1 500 Internal Server Error Date: Sat, 09 Oct 2010 14:28:02 GMT ``` ou até mesmo para quando podemos identificar o erro como: ``` HTTP/1.1 400 Bad Format Date: Sat, 09 Oct 2010 14:28:02 GMT ``` E se voltássemos ao nosso `Hello, World` ```typescript const http = require('http'); const app = (request, response) => { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.write('Hello, World!'); response.end(); }; const server = http.createServer(app); server.listen(8081); ``` O que estamos por trás dos panos dizendo? ``` HTTP/1.1 200 OK Content-Type: text/plain Hello, World! ``` Se fossemos criar um servidor `HTTP` na mão, como a gente poderia fazer isso? Basta notar que tudo dentro dessa responsa também é quebrável em pequenas partes... ```typescript let response = response.split('\n'); ``` ```bash= [ 'HTTP/1.1 200 OK', 'Date: Sat, 09 Oct 2010 14:28:02 GMT', 'Content-Type: text/plain', '', 'Hello, World!' ] ``` Nossa aplicação `cliente` poderia tratar cada um desses pontos porque eles seguem um padrão;