Onde o GraphQL Machuca em Sistemas Legados
O problema não é o GraphQL em si. O problema é tentar enfiar um modelo declarativo, orientado a esquema e altamente introspectivo em um backend que foi crescendo na base do “funciona, não mexe”. Sistemas legados não possuem fronteiras bem definidas, não têm contratos estáveis e muitas vezes carregam regras de negócio espalhadas em lugares onde ninguém lembra de ter colocado.
Quando você adiciona GraphQL nessa mistura, cria mais uma camada para esconder a bagunça, não para resolvê-la. **É over-engineering com selo premium**: elegante no PowerPoint, caótico no deploy.
O pior? A equipe acredita que ao colocar um schema bonitinho na frente do legado, magicamente o domínio vira algo limpo. Spoiler: não vira.
Como Resolver Sem Gastar Energia à Toa
Não precisa de fetiche arquitetural. Precisa de adaptação. A saída pragmática é simples: **criar adaptadores finos que isolam o legado** e expõem somente o necessário ao GraphQL, evitando que o schema vire um mapa das gambiarras internas.
A lógica é a mesma citada por desenvolvedores experientes: embrulhe o legado em interfaces mais estáveis e só depois exponha protocolos modernos. Não é reinventar a roda — é impedir que ela exploda.
Implementação Sênior (Sem Gourmetizar)
Se for usar GraphQL em legado, faça do jeito certo: coloque um Bounded Context artificial na frente e exponha somente operações necessárias. Aqui vai um exemplo realista em Node.js com Apollo Server, usando um adapter simples para não vazar complexidade do sistema antigo.
const { ApolloServer, gql } = require('apollo-server');
// Adapter isolando o legado
class LegacyUserAdapter {
constructor(legacyService) {
this.legacy = legacyService;
}
async getUser(id) {
const raw = await this.legacy.fetchUserById(id);
return {
id: raw.uid,
name: raw.full_name,
email: raw.mail
};
}
}
// Schema GraphQL enxuto
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
}
type Query {
user(id: ID!): User
}
`;
// Resolvers desacoplados
const resolvers = {
Query: {
user: (_, { id }, { adapters }) => adapters.user.getUser(id)
}
};
// Montagem da aplicação
const legacyService = require('./legacy/system');
const adapters = {
user: new LegacyUserAdapter(legacyService)
};
const server = new ApolloServer({ typeDefs, resolvers, context: () => ({ adapters }) });
server.listen();
Isso não transforma o legado em algo moderno. Só impede que ele contamine tudo ao redor.
O Preço da Decisão: Quando GraphQL Vale (ou Não Vale) a Pena
Escolher GraphQL em ambiente legado não é só questão técnica — é estratégica. Aqui estão os trade-offs que realmente importam:
Custo oculto de manutenção: qualquer mudança no legado pode quebrar o schema, e vice-versa.
Modelagem excessiva: schemas ricos demais criam um acoplamento ainda maior com estruturas antigas.
Expectativa irreal: o time acredita que GraphQL vai organizar o domínio; na prática, ele só reorganiza o caos.
Mas vale a pena quando existe necessidade real de agregação de dados entre fontes heterogêneas e o legado é estável o suficiente para não chacoalhar a cada sprint.
Direto das Trincheiras
Três aprendizados que só vêm depois de alguns tombos:
- Não exponha o modelo do legado no schema — nunca. Todo tipo deve ser pensado como API pública.
- Evite mutations complexas: elas são onde o legado mais sangra e onde a modelagem quebra.
- Use adapters pequenos e descartáveis. O objetivo é isolar, não salvar o sistema antigo.
Fontes
Quais padrões de projeto você está usando? : r/dotnet – Reddit, Strapi vs Directus vs Payload: O Showdown dos CMS Headless, Qual o código mais complicado que você já encontrou? – Reddit
Obrigado por acompanhar essa reflexão até o fim!
Espero que esses pontos ajudem você a tomar decisões mais lúcidas no seu próximo projeto. Não deixe de conferir outros artigos no reymaster.dev.br, onde desmontamos hypes com coragem e pé no chão.
Valeu e até a próxima! 😉


