Full-stack crud, disederhanakan, dengan entitas script SSOT
Remult menggunakan entitas naskah sebagai sumber kebenaran tunggal untuk: ✅ crud + realtime API, ✅ Klien API yang aman tipe frontend, dan ✅ Backend ORM.
Remult mendukung semua database utama , termasuk: PostgreSQL, MySQL, SQLite, MongoDB, MSSQL dan Oracle.
Remult adalah Frontend dan Backend Framework Agnostik dan dilengkapi dengan adaptor untuk Express, Fictify, Next.js, Nuxt, Sveltekit, SolidStart, Nest, Koa, Hapi dan Hono.
Ingin mengalami remult secara langsung? Coba tutorial online interaktif kami.
Remult mempromosikan sintaks kueri yang konsisten untuk kode frontend dan backend :
// 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
}Tidak suka dekorator? Kami memiliki dukungan penuh untuk bekerja tanpa dekorator
Contoh:
// 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 ( )Remult Menambahkan penangan rute untuk API REST yang berfungsi penuh dan titik akhir Query Langsung Realtime, opsional termasuk spesifikasi API terbuka dan titik akhir GraphQL
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 [ ]
}
Sementara CRUD sederhana seharusnya tidak memerlukan pengkodean backend, menggunakan remult berarti memiliki kemampuan untuk menangani skenario kompleks dengan mengendalikan backend dengan berbagai cara:
Paket remult adalah satu dan sama untuk bundel Frontend dan backend. Instal sekali untuk proyek monolit atau per-repo di monorepo.
npm i remultCara terbaik untuk mempelajari Remult adalah dengan mengikuti tutorial aplikasi web TODO sederhana dengan backend Node.js Express.

Demo Watch Code di YouTube di sini (14 menit)
Dokumentasi ini mencakup fitur utama remult. Namun, ini masih merupakan pekerjaan yang sedang berlangsung.
FullStack TODOMVC Contoh dengan React and Express. (Kode Sumber | CodeSandBox)
Demo CRM dengan database front-end dan postgres React + MUI.
Remult siap produksi dan, pada kenyataannya, digunakan dalam aplikasi produksi sejak 2018. Namun, kami menjaga versi utama di nol sehingga kami dapat menggunakan umpan balik komunitas untuk menyelesaikan API V1.
Pengembangan web full-stack (masih) terlalu rumit. CRUD yang sederhana, persyaratan umum dari aplikasi bisnis apa pun, harus mudah dibangun, dipelihara, dan diperluas ketika dibutuhkan.
Remult Abstrak pergi berulang, boilerplate, rawan kesalahan, dan kode yang dirancang dengan buruk di satu sisi, dan memungkinkan fleksibilitas total dan kontrol di sisi lain. Remult membantu membangun aplikasi fullstack hanya menggunakan kode TypeScript yang dapat Anda ikuti dengan mudah dan dengan aman refactor , dan cocok dengan baik ke dalam proyek yang ada atau baru dengan menjadi minimalis dan sama sekali tidak teropini tentang pilihan pengembang dari kerangka kerja dan alat lain.
Kerangka kerja lain cenderung jatuh ke dalam abstraksi yang terlalu banyak (no-kode, kode rendah, BAAS) atau abstraksi parsial (kerangka kerja MVC, GraphQL, ORM, generator API, generator kode), dan cenderung berpendapat tentang pengembangan rantai alat, lingkungan penyebaran, konfigurasi/konvensi atau DSL. Remult upaya untuk mencapai keseimbangan yang lebih baik.
Kontribusi dipersilakan. Lihat Contributing.md.
Remult dilisensikan MIT.