Show HN: Remult – a CRUD framework for full-stack TypeScript
github.com
github.com
export class Product {
@Fields.string<Product>({
validate: product => {
if (product.name.trim().length == 0)
throw 'required';
}
})
name = '';Exceptions are a really bad match for marking validation (even ignoring the arsefest that is debugging exceptions during keyboard input events - ugggh).
The DOM has onInvalid events[1] that are fired on form submit (not blur), and there is an :invalid[2] pseudo class for highlighting input errors. Not a perfect API, but certainly relevantly interesting.
[1] https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputEl...
[2] https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid
Personally I hold the errors in an array which is useful when validating a form when you want to show multiple errors from a save attempt.
However I do throw an exception if the model is somehow incorrectly configured. Like a validator method being expected but not defined.
I use tsoa and am happy with it but often choose NestJS these days as it’s much more structured.
I do like the quick bootstrapping Remult offers via "JSON db" if one hasn't set up a DB yet. And entity classes defined as a .ts file is nice, as opposed to Prisma's DSL (e.g. schema.prisma file).
It does seem feasible one could use Remult + Prisma + NextJS, with Prisma as Source of Truth of DB schema and Remult Source of Truth for Client side data model (although, that might go against the "define once, use anywhere" pattern laid out here).
Really like the project though, great docs and tutorial.
Can anyone provide a succinct summary?
- [0] https://github.com/tc39/proposal-decorators - [1] https://tc39.es/process-document/
My project is a game, the client/server uses WebSocket rather than a normal REST API.
I have used Prisma, Knex, TypeORM. Seems to me that ideally, we would write types in TypeScript and have a DB schema generated from those, including automatic migrations based on schema diffing like Prisma. Then we only need to know TS, not another DSL.
We don't want to generate TS types from the DB because then we have no way of versioning the DB schema (except by writing SQL or DSL migrations).
I ended up finding https://deepkit.io/library/orm and I'm going to try it out. (Not associated with project)
https://remult-crm-demo.herokuapp.com/
Username: Velva
Password: password
Front end of the demo is functional but a little rough on my iPhone with Safari.
Also, pressing enter to log in doesn't work.
https://docs.digitalocean.com/products/app-platform/how-to/a...
I will note the MSSQL version of Hasura seems to be slightly behind in documentation, not sure about features though
Surely swagger isn’t a better tool than Hasura and GraphQL-codegen
It just works great, covers just every use case I throw at it (business apps or side projects), has the right balance of versatility and openness, and doesn't try to do more than backend.
I really love it.
Having spent more time using typescript and picked up functional programming similar to Haskell (via fp-ts), I wouldn't touch nest despite its popularity.
MarbleJS looks interesting. But I'd also be inclined to use express with supporting libraries.
Despite that, I quite like NestJS, but I am a bit concerned about their — and Remult’s — reliance on decorators, a standard that appears to be in flux.
[0]: https://docs.nestjs.com [1]: https://docs.nestjs.com/graphql/quick-start
You end up with large blocks of config in ugly decorators but what they're doing is trying to supply that config to the underlying libs.
I consider Nestjs docs to be among the best written docs in the node community. Virtually everything you need is in there.
https://github.com/eropple/nestjs-auth
https://github.com/eropple/nestjs-openapi3
I was pretty excited by NestJS when I ran into it because, well--I don't mind magic, when it's done right. I quite like Spring Boot, for example. But NestJS's magic is...incorrect, in a lot of ways. The DI container is a little bit scary, with oddly hardcoded ways to register interceptors into request scope (itself necessary because NestJS's logging facilities aren't--or weren't at the time--decorating requests with X-Request-Id or similar, so you had to register your own) and no way to then define interceptor order.
It also has a lot of really overlapping nouns; guards are interceptors but less capable (and @eropple/nestjs-auth didn't use them at all) and the "pipe" concept for validation was itself inscrutable. To make it usable, I ended up just doing everything with decorators and interceptors, all living in request scope. And once I'd gotten it going, it was pretty nice. But it also meant broad incompatibilities with much of the NestJS ecosystem. It was mostly just my magic, instead.
These days I use Fastify, and, well--some things never change:
For me, if I wanted what Koa does, Express does 90% of it and I already know it off the top of my head. And I don't really want Express because I'll have to reinvent a lot of wheels or stack a lot of sorta-compatible middleware on top of one another (Fastify's ecosystem is smaller but generally pretty cohesive).
Nothing at all wrong with Koa, to be clear--I just don't have a use for it.