# 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;