This is how I move fast and break nothing. By having fullstack type-safety from database all the way to the frontend with auto-completion. My current stack: + SvelteKit (could be Next, Nuxt, Solid or any other TypeScript framework) + tRPC (typed calls between frontend and backend, https://trpc.io ) + trpc-sveltekit (glues SvelteKit and tRPC, https://github.com/icflorescu/trpc-sveltekit ) + Prisma (ORM, https://www.pr…
https://github.com/OpenAPITools/openapi-generator
I chuckle every time I read claims about Go (or whatever) being amazingly productive. I don't think it's possible to beat this stack with regards to both productivity and ease of long-term support, at least without going to very niche technologies where you'll have other problems.
Database schema is generated from models described in C# (or reverse-engineered from an existing schema). You don't have to compromise your schema to satisfy the ORM (another claim I often read on HN), as it's very adaptable to your needs.
Migrations are generated automatically — change your models, ask it to generate migration code in C# + a SQL migration script, review the generated SQL, and apply.
The vast majority of database queries (pretty much everything besides reports) is written in type-safe LINQ, which makes it easy to refactor code, and also construct & combine queries at runtime. Unlike that specification abomination JPA expects you to use, LINQ queries look something like this:
var latestOrders = _db.Orders
.Where(ord => ord.CreatedAt >= DateTime.Today)
.Where(ord => !ord.Deleted)
.OrderByDescending(ord => ord.CreatedAt)
.Take(25)
.Select(ord => new {
OrderId = ord.Id,
Customer = ord.Customer.Name,
CreatedAt = ord.CreatedAt,
Products = ord.Products.Select(prod => new {
ProductId = prod.Id,
Title = prod.Title,
})
})
.ToList();
If you change your schema and forget to update one of the queries accordingly (although using an IDE makes this pretty much impossible), your code won't even compile.