Pular para o conteúdo
.NETConceito e implementação de HATEOAS
Módulo 05Consultas Avançadas

Conceito e implementação de HATEOAS

avancado 55 min de leitura·Atualizado · .NET 9
Resumo

HATEOAS (Hypermedia as the Engine of Application State) é o nível 3 de maturidade REST: a resposta inclui links que dizem ao cliente quais ações são possíveis. Implementamos links com media types customizados.

1. Objetivos de Aprendizagem#

  • Explicar o que é HATEOAS e por que importa.
  • Modelar links (href, rel, method).
  • Implementar HATEOAS condicionado a um media type customizado.

2. Pré-requisitos#

  • Data shaping (Módulo 34) e content negotiation (Módulo 21).

3. Conceito#

Numa API HATEOAS, cada recurso traz hypermedia: links para operações relacionadas (self, próxima página, deletar). O porquê: o cliente navega pela API seguindo links, em vez de codificar URLs — reduzindo acoplamento. Um link tem:

JSON
{ "href": "/api/produtos/1", "rel": "self", "method": "GET" }

Como HATEOAS muda o formato da resposta, ativamos via media type customizado (application/vnd.catalog.hateoas+json), preservando clientes que não o pedem.

4. Mão na Massa#

4.1. Setup#

Registre o media type customizado nas opções do MVC (ver tópico do Root Document, Módulo 36, para o filtro de validação de media type).

4.2. Implementação Passo a Passo#

  1. Modelos de link:
C#
public record Link(string? Href, string Rel, string Method);

public class LinkResourceWrapper<T>
{
    public List<T> Value { get; set; } = new();
    public List<Link> Links { get; set; } = new();
}
  1. Gerador de links (usa LinkGenerator):
C#
public class ProdutoLinks
{
    private readonly LinkGenerator _linkGenerator;
    public ProdutoLinks(LinkGenerator linkGenerator) => _linkGenerator = linkGenerator;

    public List<Link> CreateForProduto(HttpContext http, Guid categoriaId, Guid id) => new()
    {
        new(_linkGenerator.GetUriByAction(http, "GetProduto",
              values: new { categoriaId, id }), "self", "GET"),
        new(_linkGenerator.GetUriByAction(http, "Deletar",
              values: new { categoriaId, id }), "delete_produto", "DELETE"),
    };
}
  1. Ativação condicional pelo Accept:
C#
var incluiLinks = http.Request.Headers.Accept
    .ToString().Contains("vnd.catalog.hateoas", StringComparison.OrdinalIgnoreCase);

4.3. Executando#

Shell
curl -H "Accept: application/vnd.catalog.hateoas+json" \
  http://localhost:5000/api/categorias/{catId}/produtos

A resposta passa a incluir links por item e na coleção.

5. Exemplo Completo#

Resposta típica com HATEOAS:

JSON
{
  "value": [
    { "id": "1", "nome": "Mouse", "links": [
      { "href": "/api/.../produtos/1", "rel": "self", "method": "GET" },
      { "href": "/api/.../produtos/1", "rel": "delete_produto", "method": "DELETE" }
    ]}
  ],
  "links": [
    { "href": "/api/.../produtos", "rel": "self", "method": "GET" }
  ]
}

6. Boas Práticas e Armadilhas#

FaçaEvite
Gerar URLs com LinkGenerator (rotas nomeadas)Concatenar strings para montar links
Ativar HATEOAS por media type customizadoQuebrar clientes existentes forçando o novo formato
Incluir rel e method clarosLinks sem semântica de ação
Atenção

HATEOAS adiciona complexidade e payload. Avalie se seus consumidores realmente navegam por links — muitos clientes ignoram hypermedia. É uma decisão de tradeoff, não obrigatória.

7. Segurança e Produção#

  • Gere apenas links para ações que o usuário pode executar (respeite autorização), evitando expor operações não permitidas.

8. Exercícios#

  • Fácil: adicione um link update_produto (PUT).
  • Médio: inclua links de paginação (next/previous) na coleção.
  • Desafio: condicione os links às permissões do usuário autenticado.

9. Resumo#

HATEOAS enriquece respostas com links de ações, ativado por media type customizado para não quebrar clientes. LinkGenerator produz URLs confiáveis a partir das rotas nomeadas.

10. Próximos Passos#

Módulo 36: métodos OPTIONS e HEAD.

11. Referências#

35-01 — Conceito e implementação de HATEOAS | Curso ASP.NET Core