Construindo uma API de Descoberta de Vídeos com GraphQL
Quando nosso banco de dados de vídeos cresceu para centenas de milhares de registros, nossa API tornou-se o gargalo.
Uma única tela precisava de cinco chamadas REST diferentes para mostrar vídeos em alta, detalhes do canal, tags, contagem de visualizações e recomendações. Usuários de dispositivos móveis em conexões lentas precisavam enviar 30 requisições apenas para carregar uma página.
O GraphQL resolve isso. O cliente solicita exatamente o que precisa em uma única requisição.
Eu construí uma API de descoberta de vídeos para produção usando Strawberry e FastAPI. Aqui está como eu fiz.
Por que o Strawberry?
Eu testei o Graphene e o Ariadne, mas o Strawberry venceu por estes motivos:
• Type hints são o esquema. Você escreve código Python e o Strawberry constrói os tipos GraphQL. Não é necessário sincronismo manual. • É nativamente assíncrono (async-native). Isso permite que a API lide com muitas requisições sem bloquear o event loop. • A integração com FastAPI é perfeita. O endpoint GraphQL reside logo ao lado das rotas REST existentes. • DataLoader integrado. Esta ferramenta resolve o problema N+1 de forma nativa.
A Stack de Dados
Os dados residem em um banco de dados SQLite gerenciado por um site em PHP. Eu uso SQLite FTS5 para busca rápida de texto completo (full-text search).
O serviço Python lê este banco de dados como uma camada de apenas leitura. Isso garante que haja apenas uma única fonte da verdade.
Para tornar a busca agradável, eu misturo pontuações de relevância do FTS5 com um sinal de popularidade. Isso evita que um único vídeo viral abafe todos os outros resultados de busca.
Resolvendo o Problema N+1
Uma armadilha comum no GraphQL é o problema N+1. Se você busca 20 vídeos e depois busca o canal de cada um deles, uma API ingênua executará 21 consultas ao banco de dados.
O DataLoader resolve isso por meio de batching (agrupamento). Ele coleta todos os IDs de canal em um único ciclo e executa uma única consulta para buscá-los todos. Isso reduziu nosso tempo de consulta de 40ms para menos de 5ms.
Principais Escolhas de Design
• IDs Opacos: Eu uso strings para os IDs. Isso permite mudanças futuras sem quebrar os aplicativos clientes. • Nullability Intencional: Eu defino quais campos podem estar vazios. Isso ajuda os clientes a lidar com dados ausentes sem travar. • Esquema de Apenas Leitura: A API GraphQL não lida com escritas. Isso remove muitas dores de cabeça de segurança. • Edge Caching: O GraphQL usa POST por padrão, o que é difícil de fazer cache. Eu uso Automatic Persisted Queries (APQ) para permitir o cache via Cloudflare.
Se você tem dificuldades com muitos endpoints personalizados ou parâmetros de consulta complexos, esta stack é uma excelente opção.
