През последните 5 години GraphQL се установи като "modern" начин за изграждане на API-та. Apollo, Relay, schema-first подходи — цяла екосистема, която обещава елегантност и гъвкавост за всеки проект. Реалността при повечето SaaS и e-commerce продукти обаче е по-скромна: GraphQL добавя complexity, който рядко се отплаща.
В тази статия ще обясня защо в повечето нови проекти използваме tRPC вместо GraphQL — и кога GraphQL остава правилният избор.
Какво обещава GraphQL
- Един endpoint, който връща точно това, което клиентът поиска (no over-fetching)
- Strongly typed schema, споделена между frontend и backend
- Стандартизиран начин за фронтенд тулинг (Apollo, urql, codegen)
- Federation за микросървис архитектури
Това звучи отлично на хартия. На практика, при single-team monolith проект (което е 90% от SaaS startup-ите), повечето от тези предимства не се използват или носят повече разходи отколкото полза.
Какво боли при GraphQL
Codegen pipeline
Schema-first GraphQL означава, че всяка промяна на API-то изисква regenerate на типовете. Това е допълнителен build step, който трябва да се поддържа в CI, при всеки PR. При tRPC типовете идват директно от TypeScript inference — нула generation, нула CI complexity.
N+1 проблемът
GraphQL улеснява клиента да поиска nested данни ("users { posts { comments { author } } }"). Без careful resolver implementation с DataLoader, тези заявки могат да трият бази данни. Решението — DataLoader + batching layer — добавя още един layer от complexity, който junior разработчик често пропуска.
Authorization сложност
В REST/tRPC контекста, авторизацията е в endpoint level — ясно и понятно. В GraphQL, authorization трябва да е field-level и да обмисля nested resolvers. Това е възможно, но изисква библиотеки като GraphQL Shield и значително повече usable code.
Какво дава tRPC
tRPC е TypeScript-first библиотека за изграждане на end-to-end type-safe API-та без code generation. Дефинираш функции на сървъра, директно ги извикваш на клиента, и типовете идват автоматично.
- End-to-end type safety без codegen step
- IDE autocomplete от backend procedures на frontend
- Refactoring е trivial — преименувай procedure на сървъра, TypeScript показва всички места на клиента
- No bundle bloat от GraphQL client (Apollo е ~30KB gzip)
- Standard HTTP transport — лесно cache-ване с CDN, REST inspection tools работят
- Validation чрез Zod — same schema за input + types
Реален пример
В Frizmo Platform използваме tRPC за всички server-client комуникации. Имаме около 80 procedure-а, organized в routers. Time от "Имам идея за нова функционалност" до "PR е merged" обикновено е под 2 часа за CRUD операции.
Когато започнахме проекта, обмислихме GraphQL. Калкулирахме допълнителните часове за codegen setup, DataLoader implementations, resolver-level auth, Apollo Client configuration — около 30-40 часа за initial setup и още 5-10 часа на месец maintenance. С tRPC тези часове отиват директно в нови features.
Кога GraphQL остава правилният избор
- Имате multiple front-end clients (web, iOS, Android, partners) с различни data needs
- API-то е публично, използвано от външни разработчици
- Имате микросървис архитектура с federation needs
- Работите в team от 50+ души, където contract-first development е necessary
- Имате complex data graph, където клиентите наистина имат нужда да query-ват arbitrary nested структури
Ако нито една от тези точки не описва вашия проект, GraphQL вероятно е over-engineering.
Когато не е tRPC, нито GraphQL
За много проекти стандартни REST endpoint-и в Next.js API routes или server actions са достатъчни. Особено за прости CRUD операции с малко state. Не всеки проект има нужда от RPC или query layer.
Заключение
GraphQL е мощен инструмент, проектиран за конкретни сложни сценарии. tRPC е pragmatic решение за TypeScript-heavy продукти, които не се нуждаят от complex query needs.
Грешката, която виждам най-често е, че екипи избират GraphQL по подразбиране, защото е модерно. Резултатът — седмици в build infrastructure вместо в shipping features. За 90% от новите проекти tRPC е по-бързият път до production без compromise в developer experience.