HTTP & REST · 35 min

Consuma uma API REST Pública

Faça requisições HTTP reais contra uma API REST ao vivo com curl: leia status lines e headers, GET com query params, POST/PUT/DELETE e provoque códigos de erro reais. O complemento prático do HTTP & REST Essentials.

Problema

Todo app que você vier a construir conversa com APIs por HTTP. Ler sobre verbos e códigos de status é uma coisa; *ver* um `201 Created` voltar de um `POST` que você escreveu, com os headers que o fizeram funcionar, é o que faz o protocolo fazer sentido. Neste lab você vai bater numa API REST real e pública do seu terminal com `curl`. Vai inspecionar a resposta completa — status line, headers, corpo — enviar dados com `POST`, `PUT` e `DELETE`, e disparar de propósito `400` e `404` para ler o que uma API que falha te diz. Nenhum app para construir, nenhuma chave para gerenciar: só você, o protocolo, e um servidor real respondendo. Você vai terminar capaz de explorar e depurar qualquer API HTTP que encontrar.

Objetivos

Pré-requisitos

O que você vai construir

Não um app — fluência com o protocolo. Você vai rodar uma sequência de requisições curl
contra uma API pública de teste e coletar os resultados num registro requests.md. No fim você terá
exercitado todo verbo HTTP central e lido respostas reais de sucesso e de erro.

A API que você vai usar

Você vai usar o JSONPlaceholder (https://jsonplaceholder.typicode.com), uma API REST falsa e
gratuita para testes. Ela expõe recursos padrão — /posts, /users, /comments — e aceita
escritas (POST/PUT/DELETE) que ela simula: retorna uma resposta realista como se tivesse
salvado seus dados, sem de fato persistir. É perfeita para aprender o formato requisição/resposta
com segurança.

O modelo mental: requisição → resposta

Toda troca HTTP tem o mesmo esqueleto, e o curl te deixa ver tudo:

Parte Requisição Resposta
Linha inicial GET /posts/1 HTTP/1.1 HTTP/1.1 200 OK
Headers Accept: application/json Content-Type: application/json
Corpo (JSON que você envia no POST/PUT) (JSON que o servidor retorna)

O código de status na linha inicial da resposta é o veredito de uma palavra do servidor: 2xx
sucesso, 3xx redirecionamento, 4xx você errou, 5xx o servidor errou. Aprender a lê-lo primeiro
é o jeito mais rápido de depurar qualquer chamada de API.

Como trabalhar neste lab

Rode cada requisição você mesmo e leia a saída real. Salve o comando e uma nota do que voltou no
requests.md à medida que avança — esse é seu entregável do Passo 6.

Passos

  1. Sua primeira requisição: leia a resposta completa

    Comece vendo cada parte de uma resposta HTTP, não só o corpo.

    Um GET simples

    curl https://jsonplaceholder.typicode.com/posts/1
    

    Você recebe um objeto JSON — um único "post" com userId, id, title, body. Mas o curl
    escondeu o status e os headers por padrão. Vamos revelá-los.

    Veja os headers com -i

    curl -i https://jsonplaceholder.typicode.com/posts/1
    

    -i inclui os headers da resposta acima do corpo. Leia o topo:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    ...
    
    • HTTP/1.1 200 OK é a status line — versão do protocolo, código de status, frase de motivo.
    • Content-Type: application/json te diz que o corpo é JSON, então você sabe como fazer o parse.

    Veja tudo com -v

    curl -v https://jsonplaceholder.typicode.com/posts/1
    

    -v (verbose) mostra também a requisição. Linhas começando com > são o que o curl
    enviou; linhas com < são o que o servidor retornou. Essa é sua flag de depuração mais útil
    — quando uma chamada se comporta mal, o -v mostra a requisição e a resposta exatas no fio.

    Entregável deste passo: a status line e o header Content-Type da requisição com -i.

  2. GET de uma coleção e uso de query parameters

    Um recurso único é /posts/1. A coleção inteira é /posts. Query params a filtram.

    Pegue a coleção

    curl -s https://jsonplaceholder.typicode.com/posts | head -c 300
    
    • -s (silent) esconde o medidor de progresso do curl, dando saída limpa para pipe.
    • head -c 300 mostra só os primeiros 300 caracteres para um array de 100 itens não inundar seu terminal.

    Você recebe um array JSON de posts. Coleções retornam arrays; recursos únicos retornam
    objetos — uma convenção REST que vale internalizar.

    Filtre com query parameters

    APIs REST deixam você filtrar uma coleção via ?chave=valor na URL:

    curl -s "https://jsonplaceholder.typicode.com/posts?userId=1"
    

    Isso retorna só posts onde userId é 1. Repare nas aspas ao redor da URL — o ? e o & são
    especiais na maioria dos shells, e as aspas impedem o shell de estragá-los. Adicione mais params com &:

    curl -s "https://jsonplaceholder.typicode.com/comments?postId=1&_limit=2"
    
    • postId=1 filtra os comentários para o post 1; _limit=2 limita o resultado a 2 itens.
    • Tudo depois do ? é a query string — modifica como você lê o recurso, sem mudar o path.

    Formate o JSON (opcional)

    Se você tem jq, faça pipe para ele para um JSON legível:

    curl -s "https://jsonplaceholder.typicode.com/posts/1" | jq
    

    Entregável deste passo: o resultado filtrado da requisição ?userId=1 (ou seu primeiro item).

  3. Envie dados: POST e PUT com corpo JSON

    Ler é GET. Para criar e atualizar, você envia um corpo com POST e PUT.

    Crie com POST

    curl -i -X POST https://jsonplaceholder.typicode.com/posts \
      -H "Content-Type: application/json" \
      -d '{"title": "Meu primeiro post", "body": "Olá REST", "userId": 1}'
    

    Cada flag importa:

    • -X POST define o método como POST (criar).
    • -H "Content-Type: application/json" declara que o corpo que você envia é JSON. Omita isso
      e o servidor pode não fazer o parse dos seus dados — uma das principais causas de "por que meu POST está vazio?".
    • -d '{...}' é o corpo da requisição, os dados que você está criando.

    Leia a resposta com -i: o status é 201 Created (não 200), e o corpo ecoa seu objeto com
    um novo "id": 101. 201 é o código de sucesso correto para "um novo recurso foi criado" —
    distinto do 200 OK de uma leitura simples.

    Atualize com PUT

    curl -i -X PUT https://jsonplaceholder.typicode.com/posts/1 \
      -H "Content-Type: application/json" \
      -d '{"id": 1, "title": "Título atualizado", "body": "Novo corpo", "userId": 1}'
    
    • PUT /posts/1 substitui o recurso naquele id pelo corpo que você envia.
    • O status é 200 OK e o corpo reflete sua atualização.
    • Semântica para lembrar: POST numa coleção cria; PUT num id específico substitui.

    (O JSONPlaceholder simula isso — retorna a resposta correta sem de fato salvar. A mecânica de
    requisição/resposta é exatamente o que uma API real espera.)

    Entregável deste passo: a status line 201 Created e o id retornado no POST.

  4. DELETE e ler códigos de status de propósito

    O último verbo central, e então um tour pelo que a falha parece.

    Delete um recurso

    curl -i -X DELETE https://jsonplaceholder.typicode.com/posts/1
    

    DELETE /posts/1 remove o recurso. A resposta é 200 OK (algumas APIs usam 204 No Content,
    que significa "feito, nada a retornar"). Repare que o corpo é um {} vazio — um delete confirma
    via código de status, não pelo corpo. É por isso que ler o status primeiro importa.

    Pegue só o código de status

    Para capturar só o código (útil em scripts), use -o /dev/null -w:

    curl -s -o /dev/null -w "%{http_code}\n" https://jsonplaceholder.typicode.com/posts/1
    
    • -o /dev/null joga o corpo fora.
    • -w "%{http_code}\n" escreve só o status numérico. Você verá 200.

    Provoque erros reais

    Agora quebre as coisas de propósito e leia o que o servidor diz:

    # 404 Not Found — o recurso não existe
    curl -s -o /dev/null -w "%{http_code}\n" https://jsonplaceholder.typicode.com/posts/99999
    
    # 404 num path ruim
    curl -i https://jsonplaceholder.typicode.com/nonsense
    

    As famílias de código de status, que você deveria saber recitar:

    Faixa Significado Exemplo
    2xx Sucesso 200 OK, 201 Created, 204 No Content
    3xx Redirecionamento 301 Moved Permanently
    4xx Sua requisição estava errada 400 Bad Request, 401 Unauthorized, 404 Not Found
    5xx O servidor falhou 500 Internal Server Error, 503 Service Unavailable

    Quando uma chamada falha, o código te diz de quem é a culpa — 4xx significa conserte sua
    requisição, 5xx significa que o servidor quebrou. Essa única distinção economiza horas de depuração.

    Entregável deste passo: os códigos de status que você capturou para o DELETE, o GET válido e a requisição 99999 (não encontrado).

  5. Headers que importam: Accept, Content-Type e autenticação

    Headers são os metadados que fazem uma requisição funcionar. Três que você vai usar o tempo todo.

    Content-Type — o que você está enviando

    Você já o usou no POST. Content-Type descreve o corpo que você envia para o servidor fazer
    o parse corretamente. Envie JSON → application/json. Envie um formulário →
    application/x-www-form-urlencoded. Erre isso e o servidor pode rejeitar ou ler errado seus dados.

    Accept — o que você quer de volta

    Accept diz ao servidor o formato que você gostaria na resposta:

    curl -s -H "Accept: application/json" https://jsonplaceholder.typicode.com/posts/1
    

    Uma API bem-comportada usa o Accept para decidir se retorna JSON, XML, etc. (negociação de
    conteúdo). Para APIs JSON costuma ser o padrão, mas enviá-lo explicitamente é boa higiene.

    Authorization — provar quem você é

    A maioria das APIs reais exige um token. Você o envia no header Authorization, tipicamente como um Bearer token:

    curl -s -H "Authorization: Bearer <seu-token>" https://api.example.com/me
    
    • O servidor lê o token, verifica, e serve a requisição ou retorna 401 Unauthorized (sem token/inválido) ou 403 Forbidden (token válido, sem permissão).
    • O JSONPlaceholder não precisa de auth, então este é o padrão a reconhecer — toda API real que
      você integrar (GitHub, Stripe, OpenAI) usa exatamente esse formato de header.

    Nota de segurança: um token é uma credencial. Nunca cole tokens reais em terminais
    compartilhados, comite-os no git, ou os coloque numa query string de URL — eles pertencem ao
    header Authorization (ou a uma variável de ambiente), nunca no path.

    Entregável deste passo: a saída da requisição com header Accept, e nas suas palavras o que 401 vs 403 significam.

  6. Entregue: seu registro de requisições

    Junte suas requisições e o que voltou num único arquivo e entregue.

    Monte sua entrega

    Crie o requests.md documentando cada chamada com o comando e o resultado-chave (status + um
    trecho da resposta):

    # Lab de API REST — <seu nome>
    
    ## 1. GET único + headers
    $ curl -i .../posts/1
    Status: 200 OK  · Content-Type: application/json
    
    ## 2. GET de coleção com query params
    $ curl -s ".../posts?userId=1"
    <primeiro item retornado>
    
    ## 3. POST (criar)
    $ curl -i -X POST .../posts -H "Content-Type: application/json" -d '{...}'
    Status: 201 Created · id retornado: 101
    
    ## 4. PUT (atualizar) e DELETE
    Status do PUT: 200 · Status do DELETE: 200
    
    ## 5. Códigos de status de propósito
    GET /posts/1     -> 200
    GET /posts/99999 -> 404
    GET /nonsense    -> 404
    
    ## 6. Headers
    Resultado da requisição com Accept + minha explicação de 401 vs 403.
    
    ## Reflexão (2-3 frases)
    Nas minhas palavras: a diferença entre 4xx e 5xx, e por que o Content-Type
    importa num POST.
    

    Entregue

    git init
    git add requests.md
    git commit -m "Lab de API REST — registro de requisições"
    # faça push para um repo público ou gist, depois entregue essa URL
    

    Critério de submissão (autoverificação)

    • Você capturou uma resposta completa (status line + headers) com -i ou -v
    • Você filtrou uma coleção usando query parameters (?chave=valor)
    • Você criou um recurso com POST e leu o status 201 Created
    • Você atualizou com PUT e deletou com DELETE, lendo cada código de status
    • Você provocou um 404 e sabe explicar as famílias 2xx/4xx/5xx
    • Você explicou Content-Type vs Accept e onde um token pertence
    • Cada entrada mostra o comando real e o status/resposta reais

    O que vem a seguir

    Você já consegue explorar e depurar qualquer API HTTP do terminal. No Backend Developer Path
    você vira o lado: em vez de chamar uma API, você vai construir uma — desenhando os mesmos
    endpoints, códigos de status e corpos JSON que você acabou de consumir aqui.