Building Type-Safe Full-Stack Apps with Remult

What is Remult?

Remult is a CRUD (Create, Read, Update, Delete) framework that uses TypeScript entities for data modeling. It provides a type-safe API client and an ORM (Object-Relational Mapping) system for backend database operations. Remult abstracts away boilerplate code, making it easier to build full-stack applications.

Setting up the Project

To get started, create a new React project using Create React App and select the TypeScript template. Next, install the required dependencies, including Remult and MongoDB.

npx create-react-app my-app --template typescript
npm install remult mongodb

Initializing Remult

Initialize Remult on the frontend by creating a remult object and configuring it to use the axios HTTP client. On the backend, create a remultExpress middleware instance and configure it to use the MongoDB database.

// frontend
import { remult } from 'remult';

const api = remult.api({
  url: '/api',
  httpClient: axios
});

// backend
import express, { Request, Response } from 'express';
import { remultExpress } from 'remult/remult-express';

const app = express();
app.use(remultExpress({
  db: 'mongodb://localhost/mydb'
}));

Defining Entities

In Remult, entities represent the data models for our application. Define two entities: Booking and Slot. Each entity will have its own set of properties and validation rules.

@Entity('bookings')
export class Booking {
  @Fields.string({ validate: Validators.required })
  name: string;

  @Fields.date()
  date: Date;
}

@Entity('slots')
export class Slot {
  @Fields.string({ validate: Validators.required })
  time: string;

  @Fields.boolean()
  available: boolean;
}

Generating API Endpoints

Remult automatically generates API endpoints for each entity based on the entity’s properties and validation rules. Use these endpoints to perform CRUD operations on our data.

Building the Frontend

Build a simple booking form application using React and the react-hook-form library. The form will allow users to submit booking requests, which will be saved to the Bookings collection in our MongoDB database.

import React from 'react';
import { useForm } from 'react-hook-form';
import { Booking } from './Booking';

const BookingForm = () => {
  const { register, handleSubmit } = useForm();

  const onSubmit = async (data) => {
    await api.insert(Booking, data);
  };

  return (



  );
};

Adding Backend-Only Methods

In some cases, we may need to perform complex logic or multiple database operations on the backend. Remult provides a way to define backend-only methods using the @BackendMethod decorator.

@BackendMethod({ allowed: true })
async getAvailableDates() {
  // complex logic here
  return [];
}

@BackendMethod({ allowed: true })
async getAvailableSlots() {
  // complex logic here
  return [];
}

Using Remult in the Frontend

To use Remult in our frontend code, import the remult object and call the backend methods directly. Remult will automatically make the API calls for us using the axios HTTP client.

import React from 'react';
import { remult } from 'remult';

const MyComponent = () => {
  const availableDates = remult.getAvailableDates();
  const availableSlots = remult.getAvailableSlots();

  return (

Available Dates

    {availableDates.map((date) => (

  • {date}
  • ))}

Available Slots

    {availableSlots.map((slot) => (

  • {slot}
  • ))}

  );
};

Leave a Reply

Your email address will not be published. Required fields are marked *