Servidor HTTP
Rotas, parâmetros, JSON e validação com Arcane.Http.
Montar#
dataforge
adopt Arcane.Http as Http
app := Http.create("API de Tarefas")
Http.cors(app) # libera chamadas de outra origem
Http.logger(app) # registra cada requisiçãoRotas#
dataforge
Http.get(app, "/api/tarefas", listar)
Http.get(app, "/api/tarefas/:id", buscar)
Http.post(app, "/api/tarefas", criar)
Http.put(app, "/api/tarefas/:id", atualizar)
Http.delete(app, "/api/tarefas/:id", remover)
Http.listen(app, 3000)O :id é um parâmetro de caminho, disponível em req["params"]["id"] — como texto, sempre. Converta antes de comparar.
Requisição e resposta#
| Leitura | Contém |
|---|---|
req["params"] | parâmetros do caminho (:id) |
req["query"] | da query string (?pagina=2) |
req["json"] | o corpo, já interpretado |
req["headers"] | os cabeçalhos |
| Escrita | Faz |
|---|---|
res.json(dados) | responde JSON com 200 |
res.json(dados, 404) | com o código que você escolher |
res.html(texto) | responde HTML |
res.send(texto, 200) | texto puro |
Uma rota completa#
dataforge
action buscar(req, res):
id := cast req["params"]["id"] as Integer
achadas := tarefas >> sift t: t["id"] is id
given len(achadas) is 0:
res.json({"erro": "tarefa nao encontrada"}, 404)
otherwise:
res.json(achadas[0])Códigos que importam#
| Código | Quando |
|---|---|
| 200 | deu certo |
| 201 | criou algo novo |
| 400 | o cliente mandou dado inválido |
| 404 | não existe |
| 500 | o servidor quebrou |
Devolver 200 com {"erro": …} no corpo obriga todo cliente a inspecionar o JSON para saber se deu certo. O código HTTP existe justamente para isso.
Validação fora da rota#
dataforge
action validar_tarefa(corpo):
problemas := []
given corpo is void:
problemas.append("corpo ausente")
yield problemas
given "titulo" not in corpo:
problemas.append("titulo e obrigatorio")
orif len(corpo["titulo"].trim()) smaller 3:
problemas.append("titulo precisa de ao menos 3 letras")
yield problemas
action criar(req, res):
problemas := validar_tarefa(req["json"])
given len(problemas) bigger 0:
res.json({"erros": problemas}, 400)
yield void
...Duas vantagens de separar: testável sem servidor, e reutilizável entre POST e PUT. E devolver todos os problemas de uma vez poupa o cliente de descobrir um erro por requisição.
O detalhe do orif#
Repare: sem o orif, o segundo teste rodaria mesmo quando a chave não existe, e corpo["titulo"] estouraria. orif só é avaliado se o given foi falso.
Testar#
bash
curl localhost:3000/api/tarefas
curl -X POST localhost:3000/api/tarefas \
-H 'Content-Type: application/json' \
-d '{"titulo":"Nova tarefa"}'