Full-Stack-Crud, vereinfacht, mit SSOT-Typskriptentitäten
Remuld verwendet Typscript-Entitäten als einzelne Quelle der Wahrheit für: ✅ CRUD + Echtzeit-API, ✅ Frontend-API-Client vom Typ Frontend-Typ und ✅ Backend ORM.
Remult unterstützt alle wichtigen Datenbanken , einschließlich: PostgreSQL, MySQL, SQLite, MongoDB, MSSQL und Oracle.
Remulte ist Agnostic Frontend und Backend Framework und wird mit Adaptern für Express, Fastify, Next.js, Nuxt, Seltekit, SolidStart, Nest, KOA, Hapi und Hono ausgestattet.
Willst du Remulation aus erster Hand erleben? Probieren Sie unser interaktives Online -Tutorial aus.
Remulation fördert eine konsistente Abfragesyntax für Frontend- und Backend -Code :
// Frontend - GET: /api/products?_limit=10&unitPrice.gt=5,_sort=name
// Backend - 'select name, unitPrice from products where unitPrice > 5 order by name limit 10'
await repo ( Product ) . find ( {
limit : 10 ,
orderBy : {
name : 'asc' ,
} ,
where : {
unitPrice : { $gt : 5 } ,
} ,
} )
// Frontend - PUT: '/api/products/product7' (body: { "unitPrice" : 7 })
// Backend - 'update products set unitPrice = 7 where id = product7'
await repo ( Product ) . update ( 'product7' , { unitPrice : 7 } ) // shared/product.ts
import { Entity , Fields } from 'remult'
@ Entity ( 'products' , {
allowApiCrud : true ,
} )
export class Product {
@ Fields . cuid ( )
id = ''
@ Fields . string ( )
name = ''
@ Fields . number ( )
unitPrice = 0
}Magst du keine Dekorateure? Wir haben die volle Unterstützung für die Arbeit ohne Dekorateure
Beispiel:
// backend/index.ts
import express from 'express'
import { remultExpress } from 'remult/remult-express' // adapters for: Fastify,Next.js, Nuxt, SvelteKit, SolidStart, Nest, more...
import { createPostgresDataProvider } from 'remult/postgres' // supported: PostgreSQL, MySQL, SQLite, MongoDB, MSSQL and Oracle
import { Product } from '../shared/product'
const app = express ( )
app . use (
remultExpress ( {
entities : [ Product ] ,
dataProvider : createPostgresDataProvider ( {
connectionString : 'postgres://user:password@host:5432/database"' ,
} ) ,
} ) ,
)
app . listen ( )Remuld fügt Routenhandler für eine voll funktionsfähige REST-API und Echtzeit-Live-Endpunkte hinzu, die optional eine offene API-Spezifikation und einen GraphQL-Endpunkt enthalten
const [ products , setProducts ] = useState < Product [ ] > ( [ ] )
useEffect ( ( ) => {
repo ( Product )
. find ( {
limit : 10 ,
orderBy : {
name : 'asc' ,
} ,
where : {
unitPrice : { $gt : 5 } ,
} ,
} )
. then ( setProducts )
} , [ ] ) useEffect ( ( ) => {
return repo ( Product )
. liveQuery ( {
limit : 10 ,
orderBy : {
name : 'asc' ,
} ,
where : {
unitPrice : { $gt : 5 } ,
} ,
} )
. subscribe ( ( info ) => {
setProducts ( info . applyChanges )
} )
} , [ ] ) import { Entity , Fields , Validators } from 'remult'
@ Entity ( 'products' , {
allowApiCrud : true ,
} )
export class Product {
@ Fields . cuid ( )
id = ''
@ Fields . string ( {
validate : Validators . required ,
} )
name = ''
@ Fields . number < Product > ( {
validate : ( product ) => product . unitPrice > 0 || 'must be greater than 0' ,
} )
unitPrice = 0
} try {
await repo ( Product ) . insert ( { name : '' , unitPrice : - 1 } )
} catch ( e : any ) {
console . error ( e )
/* Detailed error object ->
{
"modelState": {
"name": "Should not be empty",
"unitPrice": "must be greater than 0"
},
"message": "Name: Should not be empty"
}
*/
} // POST '/api/products' BODY: { "name":"", "unitPrice":-1 }
// Response: status 400, body:
{
"modelState" : {
"name" : "Should not be empty" ,
"unitPrice" : "must be greater than 0"
} ,
"message" : "Name: Should not be empty"
}@ Entity < Article > ( 'Articles' , {
allowApiRead : true ,
allowApiInsert : Allow . authenticated ,
allowApiUpdate : ( article ) => article . author == remult . user . id ,
apiPrefilter : ( ) => {
if ( remult . isAllowed ( 'admin' ) ) return { }
return {
author : remult . user . id ,
}
} ,
} )
export class Article {
@ Fields . string ( { allowApiUpdate : false } )
slug = ''
@ Fields . string ( { allowApiUpdate : false } )
authorId = remult . user ! . id
@ Fields . string ( )
content = ''
} await repo ( Categories ) . find ( {
orderBy : {
name : 'asc ' ,
} ,
include : {
products : {
where : {
unitPrice : { $gt : 5 } ,
} ,
} ,
} ,
} )
// Entity Definitions
export class Product {
//...
@ Relations . toOne ( Category )
category ?: Category
}
export class Category {
//...
@ Relations . toMany < Category , Product > ( ( ) => Product , `category` )
products ?: Product [ ]
}
Ein einfaches CRUD sollte zwar keine Backend -Codierung erfordern, bedeutet die Verwendung von Remulationen, die Möglichkeit zu haben, ein komplexes Szenario zu bewältigen, indem das Backend in vielerlei Hinsicht gesteuert wird:
Das Remulationspaket ist ein und das gleiche für das Frontend -Bundle und das Backend. Installieren Sie es einmal für ein Monolith-Projekt oder pro Repo in einem Monorepo.
npm i remultDer beste Weg zum Erlernen von Remulationen besteht darin, ein Tutorial einer einfachen Todo -Web -App mit einem Node.js Express -Backend zu folgen.

Sehen Sie sich die Code -Demo hier auf YouTube an (14 Minuten)
Die Dokumentation deckt die Hauptmerkmale von Remulationen ab. Es ist jedoch immer noch eine Arbeit.
FullStack Todomvc Beispiel mit React und Express. (Quellcode | codesandbox)
CRM-Demo mit einer React + MUI-Front-End- und Postgres-Datenbank.
Remulte ist produktionsbereit und in der Tat seit 2018 in Produktions-Apps verwendet. Wir halten die Hauptversion jedoch bei Null, damit wir das Feedback der Community verwenden können, um die V1-API abzuschließen.
Die Full-Stack-Webentwicklung ist (noch) zu kompliziert. Einfache CRUD, eine häufige Anforderung einer Geschäftsanwendung, sollte einfach zu erstellen, zu warten und zu erweitern, wenn die Notwendigkeit entsteht.
Remulationsabstrahiere sich wiederholt, ein Kesselplatten, fehleranfällige und schlecht gestaltete Code einerseits und ermöglicht die Gesamtflexibilität und Kontrolle andererseits. Remulte hilft beim Erstellen von FullStack -Apps, die Sie nur mit dem TypeScript -Code verwenden können, den Sie problemlos befolgen und sicher refaktorieren können , und passt gut in jedes vorhandene oder neue Projekt ein, indem Sie minimalistisch und völlig unvorhanden in Bezug auf die Auswahl anderer Frameworks und Tools durch den Entwickler sind.
Andere Frameworks tendieren dazu, entweder in zu viel Abstraktion (No-Code, Low-Code, BAAS) oder teilweise Abstraktion (MVC-Frameworks, GraphQL, ORMs, API-Generatoren, Codentraxatoren) zu fallen, und sind in der Regel über die Entwicklungs-Toolkette, die Bereitstellungsumgebung, die Konfiguration/Konventionen oder DSL. Remulationsversuche versucht, ein besseres Gleichgewicht zu erzielen.
Beiträge sind willkommen. Siehe Beitrag.md.
Remulation ist MIT lizenziert.