React
EmbraceSQL generates support for React using hooks. The hooks:
- Connect to any HTTP/S EmbraceSQL server endpoint
- Create, Read, Update, Delete, and Refresh data (CRUD-R)
Requirements
You are going to need:
- NodeJs >= 18
- PostgreSQL >= 14
These examples assume you are running locally with your shell able to connect to your PostgreSQL with:
psql
Create a new database dvdrental
on your local PostgeSQL server.
curl "https://embracesql.github.io/dvdrental.sql" | psql
Steps
In this example you will end up with read-write data access from a hot loading Vite built application without:
- Writing a line of SQL
- Making a POJO
- Learning a new 'schema language' like in Prisma
- Learning a new 'query language' like GraphQL
- Calling the database manually
Generate an Express Server
Go into a nice blank directory. This is the 'server side'.
npm install @embracesql/vite
npm pkg set type=module
mkdir -p ./src
npx embracesqlcli generate express --database postgres://postgres:postgres@localhost/dvdrental > ./src/dvdrental.ts
Yeah -- that's it, hard to believe I know...
Code up an Express Server
Create two files as shown.
{
"extends": "@embracesql/shared/tsconfig/react.tsconfig.json"
}
import { EmbraceSQLExpressApp } from "./dvdrental";
import { EmbraceViteApp } from "@embracesql/vite";
import express from "express";
const app = express();
export const PORT = Number.parseInt(process.env["PORT"] ?? "4000");
// hook EmbraceSQL middleware first to connect to the database
const embracesql = await EmbraceSQLExpressApp(
"postgres://postgres:postgres@localhost/dvdrental",
);
// mounting the database middleware
app.use("/embracesql", embracesql);
// and then hook in vite middleware to build and run your React
const vite = await EmbraceViteApp();
// server react at the root
app.use("/", vite);
app.listen(PORT, () => console.log(`Server is listening on port ${PORT}...`));
Run Your Server
Make sure the server starts -- this will even hot reload the server -- and web page we're about to build.
npx tsx watch ./src/server/main.ts
At this point, if you are getting data -- it's time to make a react app!
Generate a React Client
Generate the client side, react hook code:
mkdir -p src/client
npx embracesqlcli generate react --database postgres://postgres:postgres@localhost/dvdrental > ./src/client/dvdrental-react.ts
Code up a React App
Here is a super minimal React application to get you a single Actor from the database, and allow saving to the database without you writing a line of SQL, or additional schema, or even a server.
Gonna need an html page entry point.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Checklist</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/client/main.tsx"></script>
</body>
</html>
And attach a react component to #root
.
import {
EmbraceSQLClient,
EmbraceSQLProvider,
Public,
} from "./dvdrental-react";
import "./main.css";
import * as ReactDOM from "react-dom/client";
// connect to where we mounted EmbraceSQL in our server
const client = new EmbraceSQLClient({
url: `${window.location.href}embracesql`,
});
const App = () => {
// this is hooking to an AutoCRUD method to read an actor
const {
loading,
row: actor,
error,
} = Public.Tables.Actor.useActorPkey({ actorId: 100 });
// 🪄 - automatic onChange saving though the hook, with debounce to not smoke your DB!
// notice there is no <form> to post back or additional hooks
if (loading) {
return (
<div>
<p>Loading...</p>
</div>
);
}
if (error) {
return (
<div>
<p>{`{error}`}</p>
</div>
);
}
if (actor) {
return (
<div className="card">
<input value={actor.firstName} onChange={actor.changeFirstName} />
<input value={actor.lastName} onChange={actor.changeLastName} />
</div>
);
}
};
// Supported in React 18+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<EmbraceSQLProvider client={client}>
<App />
</EmbraceSQLProvider>,
);
And just a tiny bit of CSS:
#root {
max-width: 100vw;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
body {
font-family: system-ui;
margin: 0;
display: flex;
place-items: center;
min-width: 100vw;
min-height: 100vh;
}
.card {
padding: 2em;
display: flex;
flex-direction: column;
row-gap: 1rem;
}
OK - the Express server should now be serving both EmbraceSQL and a fine React app connected to it. Check it out.