Typesafe backend stack

Having a hard time deciding on a backend stack. Happy with where things are going, but nothing’s quite there yet. Looking for decent scalability and type safety. I’ve done NestJS, Typegoose, and openapi generator. Works reasonably well, single source of truth (ish, because you’re still writing DTOs). Ditching Mongo though so I’m looking at TypeORM or prisma now. Not sure if I’ll keep using NestJS. It is a godsend for organization and scalability, and the batteries included nature means it’s reasonably easy to integrate any semi popular tech, but it is also a bit inflexible as a result. Not a huge OO fan, but the Spring bootiness of it does scale nicely. I’ve never properly scaled a purely Express backend and there really isn’t a well documented pattern to follow here. I can manage it, but it’s additional mental overhead. tRPC is really cool and would give the best DX, but we do also need OpenAPI for external consumers, and although there’s an unofficial plug-in for it, I’m a bit hesitant. Lots of decisions to make here, and I’m curious if anyone has any input when it comes to scalability across multiple apps and micro services. Main decisions to make: Nest vs. pure Express tRPC vs monorepo shared types vs codegen
19 Replies
Neto
Neto2y ago
you can create a monorepo with something + fastify not nest nor express like this https://github.com/STNeto1/turbo-trpc-example
cje
cje2y ago
Definitely Fastify over Express, it's similar but better in almost every way, Express is basically abandonware and most of the old Express team have moved on to either Fastify or Koa and if you know from the start that you need OpenAPI then I would not recommend tRPC, or at least not for that part of it I prefer Fastify over Nest by far but I can also see why some teams might prefer Nest, I think that decision is up to you
Neto
Neto2y ago
OpenAPI is a spec Not a hard communication rule Just because the spec says this shape will return, doesn't mean that will be the return If you need typesafe communication, but plain http/trpc isn't enough Gql is the way
exodus
exodus2y ago
I can manage something type safe with Nest and its CLI tool...generates the spec based off of the actual controller implementation, then I take that through OpenAPI Generator and generate my types or frontend client. But it does add some mild complexity to the chain. It does work fairly nicely though. Just add it to the build step or maybe a pre-lint step, since you can generate and then tsc your projects. Not nearly the real-time DX of tRPC, but pretty decent. And backend agnostic if you have a reliable OpenAPI spec. But you are right, OpenAPI has no guarantees. I've tried taking the same approach with existing Springboot projects and found their specs to be unreliable. I am gonna look into a fastify solution and see if I can scaffold something up that I'm happy with Gql may be an option...I'll need to see if they specifically want REST for this thing One thing I could consider is just doing tRPC for the front end and then worry about REST later. I’d have to write reasonably restful endpoints, but as long as I decouple the actual request handling I’m not sure why it wouldn’t be feasible
exodus
exodus2y ago
This is the nest openapi plugin btw…killer feature tbh: https://docs.nestjs.com/openapi/cli-plugin
Documentation | NestJS - A progressive Node.js framework
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reactive Programming).
exodus
exodus2y ago
Hmmmm....how about: DBs <--Prisma--> Microservices <--gRPC--> tRPC, REST gateway Decouple tRPC and REST from the actual services. Seems like it'd probably be more prudent. And microservices is probably a good thing for us, since we have a lot of very loosely connected domains. We'll be deploying container updates manually (and physically), so small containers is gonna be a good thing.
stanisław
stanisław2y ago
Why trpc isn't the way there? Doesn't trpc by default let me know what a return type will be? It's even clear by the first example in their docs when you change smth on the backend, the client gets instant error
cje
cje2y ago
its typesafe yes the person youre replying to meant that some projects need more than trpc and in that cases gql is often a good choice
Neto
Neto2y ago
trpc with a bad serializer is bad as example if you see a clip about next default serialization and infering types you see why
kwargs
kwargs2y ago
@exodus I think http://www.zodios.org/ will fit your use case very good. It supports generating an openapi spec out of the box
Zodios | Zodios
End-to-end typesafe REST API toolbox
exodus
exodus2y ago
Hmmm not bad
kwargs
kwargs2y ago
Only thing is that it's still pretty with a smaller community then trpc. The author is already careful not to have big breaking changes though. Also, in case of problems ejecting from it shouldn't be too hard, probably easier then with trpc.
stanisław
stanisław2y ago
Zodios is amazing Highly recommend it But if your backend is in ts I still would go for trpc
kwargs
kwargs2y ago
OP needs to provide an Rest api though
stanisław
stanisław2y ago
Well the zodios will work just fine I wish IT gets more attention because its a really great project
Want results from more Discord servers?
Add your server