GraphQL vs REST em C#: Batalha de titãs ou escolha da ferramenta certa para a tarefa?
\n\nOlá, colegas! Se você programa em C# e cria APIs, a pergunta "REST ou GraphQL?" certamente já surgiu mais de uma vez. É como discutir o que é melhor: martelo ou parafusadeira. Ambos são ferramentas, mas para tarefas diferentes. Neste artigo, não vamos defender fanaticamente uma tecnologia, mas analisar com calma, com exemplos de código em C#, quando o GraphQL vence e quando o bom e velho REST continua sendo o rei.
\n\nSomos a equipe PythonLib, e embora o nome tenha "Python", amamos o ecossistema .NET e C#. Hoje vamos mergulhar no mundo das APIs em C# e entender como não errar na escolha. Vamos lá!
\n\nBreve introdução: REST e GraphQL para desenvolvedores C#
\n\nREST (Representational State Transfer) é um estilo arquitetural que todos conhecemos e amamos. Em C#, você provavelmente usa ASP.NET Core Web API. Você cria controllers, endpoints, e cada endpoint retorna uma estrutura de dados fixa. Quer obter um usuário? Vá para /api/users/1. Quer os pedidos dele? Vá para /api/users/1/orders. Simples, previsível, mas muitas vezes leva a over-fetching (receber dados desnecessários) ou under-fetching (precisar fazer várias requisições).
GraphQL é uma linguagem de consulta desenvolvida pelo Facebook. No mundo C#, é implementado através das bibliotecas Hot Chocolate (a mais popular) ou GraphQL.NET. Você tem um único endpoint (geralmente /graphql), e o cliente decide quais campos precisa. Quer o nome do usuário e apenas o primeiro pedido? Sim! Sem over-fetching.
Comparação na prática: Código C#
\n\nVamos da teoria ao código. Imagine que temos um modelo simples: User e Order.
// Modelos de dados\npublic class User\n{\n public int Id { get; set; }\n public string Name { get; set; }\n public string Email { get; set; }\n public string Phone { get; set; }\n public List<Order> Orders { get; set; }\n}\n\npublic class Order\n{\n public int Id { get; set; }\n public string ProductName { get; set; }\n public decimal Price { get; set; }\n public DateTime CreatedAt { get; set; }\n}\n\n\nExemplo de API REST com ASP.NET Core
\n\n[ApiController]\n[Route("api/[controller]")]\npublic class UsersController : ControllerBase\n{\n [HttpGet("{id}")]\n public async Task<ActionResult<User>> GetUser(int id)\n {\n // Suponha que os dados vêm do banco\n var user = await _dbContext.Users.FindAsync(id);\n if (user == null) return NotFound();\n return Ok(user); // Retorna TODOS os campos: Id, Name, Email, Phone, Orders\n }\n}\n\n\nProblema? Se o cliente precisa apenas do nome e email, ele ainda receberá Phone e Orders. E se precisar dos pedidos, terá que fazer uma requisição separada para /api/users/1/orders.
Exemplo de API GraphQL com Hot Chocolate
\n\npublic class Query\n{\n public async Task<User> GetUser(int id, [Service] AppDbContext dbContext)\n {\n return await dbContext.Users.FindAsync(id);\n }\n}\n\n// Registro em Program.cs\nbuilder.Services\n .AddGraphQLServer()\n .AddQueryType<Query>();\n\n\nAgora o cliente pode solicitar exatamente o que precisa:
\n\n// Consulta GraphQL\n{\n user(id: 1) {\n name\n email\n orders {\n productName\n price\n }\n }\n}\n\n\nA resposta conterá apenas name, email e um array orders com os campos productName e price. Nenhum dado desnecessário. Lindo!
Quando o REST em C# vence (e isso é normal)
\n\n1. Simplicidade e cache. APIs REST são fáceis de armazenar em cache no nível HTTP (CDN, proxies). Uma requisição GET para /api/products pode ser armazenada em cache, e tudo b