Programação para Web 3

Comunicação HTTP

Prof. Me. Danilo Bueno

Agenda

  1. Métodos HTTP: GET e POST
  2. Parâmetros da requisição
  3. Cabeçalhos HTTP
  4. Códigos de status sob controle
  5. Formulários HTML

Métodos HTTP

GET e POST

  • GET: expressa a intenção de leitura. Deve ser seguro (não altera o estado do servidor) e idempotente (repetições produzem o mesmo resultado)
  • POST: expressa uma ação a ser executada. Não é seguro nem idempotente

Duas requisições POST idênticas podem criar dois registros distintos; uma requisição GET, repetida, não deveria alterar nada.

Segurança e idempotência

Navegadores e robôs de busca assumem que todo GET é seguro e podem repeti-lo automaticamente (por exemplo, ao pré-carregar um link).

  • Uma ação que altera dados não deve depender apenas do método GET
  • Por esse motivo, o navegador exibe uma advertência ao recarregar uma página originada de um POST

Declaração da rota

@RestControllerpublic class CardapioController {    @GetMapping("/cardapio")    public String cardapio() {        return "Espresso - R$ 6";    }    @PostMapping("/pedidos")    public String novoPedido() {        return "Pedido registrado!";    }}

Uma mesma URL pode ter um método para cada verbo: o que identifica a rota é o par caminho e método.

Verbo não suportado

GET /pedidos HTTP/1.1

Se existir apenas @PostMapping("/pedidos"), a resposta é 405 Method Not Allowed: o caminho existe, mas não está disponível para esse verbo (diferente do 404, em que o caminho não existe).

Parâmetros

Onde os parâmetros viajam

  • Query string: na própria URL, após ?. Visível, compartilhável e registrada no histórico
  • Corpo de formulário: fora da URL, dentro de uma requisição POST
GET /cardapio/busca?nome=espresso&decaf=false
POST /pedidos HTTP/1.1
Content-Type: application/x-www-form-urlencoded

bebida=espresso&quantidade=2

Leitura de um parâmetro

@GetMapping("/cardapio/busca")public String buscar(@RequestParam String nome) {    return "Buscando por: " + nome;}

@RequestParam lê o valor pelo nome, independentemente de vir da query string ou do corpo de um formulário.

Parâmetro opcional

Por padrão, @RequestParam é obrigatório: sem ele na requisição, o Spring responde 400 Bad Request antes da execução do método.

@GetMapping("/cardapio/busca")public String buscar(@RequestParam(defaultValue = "") String nome) {    return nome.isEmpty()        ? "Informe um nome para buscar"        : "Buscando por: " + nome;}

defaultValue torna o parâmetro opcional. O tipo declarado também é validado automaticamente pelo Spring.

Cabeçalhos HTTP

Metadados da mensagem

Cabeçalhos descrevem a mensagem sem fazer parte do seu conteúdo.

Cabeçalho Aparece em Descrição
Host requisição servidor de destino
User-Agent requisição navegador ou programa cliente
Content-Type requisição/resposta formato do corpo
Content-Length resposta tamanho do corpo, em bytes

Leitura de um cabeçalho

@GetMapping("/quem-acessa")public String quemAcessa(@RequestHeader("User-Agent") String userAgent) {    return "Requisição recebida de: " + userAgent;}

Assim como @RequestParam, @RequestHeader também aceita defaultValue para cabeçalhos opcionais.

Status sob controle

Status sempre 200

// sempre 200, independentemente do resultado@GetMapping("/cardapio/busca")public String buscar(@RequestParam String nome) {    return "Bebida não encontrada: " + nome;}

O corpo indica um erro, mas o status indica sucesso. Um consumidor que interpreta apenas o status recebe uma informação incorreta.

ResponseEntity

Corpo, status e cabeçalhos reunidos no mesmo objeto de retorno.

@GetMapping("/cardapio/busca")public ResponseEntity<String> buscar(@RequestParam(defaultValue = "") String nome) {    if (nome.isEmpty()) {        return ResponseEntity.status(HttpStatus.BAD_REQUEST)            .body("Informe um nome para buscar");    }    if (!nome.equalsIgnoreCase("espresso")) {        return ResponseEntity.status(HttpStatus.NOT_FOUND)            .body("Bebida não encontrada: " + nome);    }    return ResponseEntity.ok()        .header("X-Origem", "cardapio-busca")        .body("Espresso - R$ 6");}

Escolha do status

  • 200 OK: sucesso, resposta padrão
  • 201 Created: recurso criado com sucesso (típico após um POST)
  • 400 Bad Request: dado inválido ou incompleto enviado pelo cliente
  • 404 Not Found: recurso solicitado não existe

Formulários HTML

A tag <form>

<form method="post" action="/pedidos">    <label>Bebida: <input type="text" name="bebida"></label>    <label>Quantidade: <input type="number" name="quantidade"></label>    <button type="submit">Enviar pedido</button></form>

O navegador constrói e envia a requisição de forma nativa, sem necessidade de JavaScript.

GET versus POST

<!-- get: navega para /busca?termo=... --><form method="get" action="/busca">
<!-- post: envia termo=... no corpo, a URL permanece /busca --><form method="post" action="/busca">

Na ausência do atributo method, o navegador utiliza GET por padrão.

Campos do formulário

@PostMapping("/pedidos")public String novoPedido(@RequestParam String bebida, @RequestParam int quantidade) {    return "Pedido registrado: " + quantidade + "x " + bebida;}

Os nomes dos atributos name dos campos <input> devem corresponder aos nomes declarados em @RequestParam.

Referência rápida

Item Papel
GET / POST Leitura (seguro/idempotente) / ação (não idempotente)
405 Method Not Allowed Caminho existente, verbo não suportado
@RequestParam Lê valor por nome (query string ou formulário)
defaultValue Torna o parâmetro/cabeçalho opcional
@RequestHeader Lê um cabeçalho de entrada
ResponseEntity Corpo, status e cabeçalhos reunidos
<form method action> Constrói e envia a requisição automaticamente

Obrigado!

Prof. Me. Danilo Bueno
[email protected]