Skip to main content
Version: Next

Generate Front-end Code to Consume Platformatic REST API

By default, a Platformatic app exposes REST API that provide CRUD (Create, Read, Update, Delete) functionality for each entity (see the Introduction to the REST API documentation for more information on the REST API).

Platformatic CLI allows to auto-generate the front-end code to import in your front-end application to consume the Platformatic REST API.

This guide

  • Explains how to create a new Platformatic app.
  • Explains how to configure the new Platformatic app.
  • Explains how to create a new React or Vue.js front-end application.
  • Explains how to generate the front-end TypeScript code to consume the Platformatic app REST API.
  • Provide some React and Vue.js components (either of them written in TypeScript) that read, create, and update an entity.
  • Explains how to import the new component in your front-end application.

Create a new Platformatic app

To start the Platformatic creator wizard, run the appropriate command for your package manager in your terminal:

npm create platformatic@latest

This interactive command-line tool will guide you through setting up a new Platformatic project. For this guide, please choose the following options:

- Where would you like to create your project?  => quick-start
- Which kind of project do you want to create? => @platformatic/db
- What is the name of the service? => (generated-randomly), e.g. legal-soup
- What is the connection string? => sqlite://./db.sqlite
- Do you want to create default migrations? => Yes
- Do you want to create another service? => No
- Do you want to use TypeScript? => No
- What port do you want to use? => 3042
- Do you want to init the git repository? => No

After completing the wizard, your Platformatic application will be ready in the quick-start folder. This includes example migration files, plugin scripts, routes, and tests within your service directory.

note

If the wizard does not handle dependency installation, ensure to run npm/yarn/pnpm install command manually:

Configure the new Platformatic app

Every Platformatic app uses the "Movie" demo entity and includes the corresponding table, migrations, and REST API to create, read, update, and delete movies.

Once the new Platformatic app is ready:

  • Define a PLT_SERVER_CORS_ORIGIN env variable as a valid regexp (f.e. "^http://localhost.*" or "^https://your.awesome.service/*")
  • Pass it to platformatic.db.json
{
"$schema": "https://schemas.platformatic.dev/@platformatic/db/1.52.0.json",
"server": {
"hostname": "{PLT_SERVER_HOSTNAME}",
"port": "{PORT}",
"logger": {
"level": "{PLT_SERVER_LOGGER_LEVEL}"
},
+ "cors": {
+ "origin": {
+ "regexp": "{PLT_SERVER_CORS_ORIGIN}"
+ }
+ }
},
...
}

You can find more details about the cors configuration here.

  • launch Platformatic through npm start. Then, the Platformatic app should be available at the http://127.0.0.1:3042/ URL.

Create a new Front-end Application

Refer to the Scaffolding Your First Vite Project documentation to create a new front-end application, and call it "rest-api-frontend".

info

Please note Vite is suggested only for practical reasons, but the bundler of choice does not make any difference.

If you are using npm 7+ you should run

npm create vite@latest rest-api-frontend -- --template react-ts

and then follow the Vite's instructions

Scaffolding project in /Users/noriste/Sites/temp/platformatic/rest-api-frontend...

Done. Now run:

cd rest-api-frontend
npm install
npm run dev

Once done, the front-end application is available at http://localhost:5174/.

Generate the front-end code to consume the Platformatic app REST API

Now that either the Platformatic app and the front-end app are running, go to the front-end codebase and run the Platformatic CLI

cd rest-api-frontend/src
npx platformatic client http://127.0.0.1:3042 --frontend --language ts

Refer to the Platformatic CLI frontend command documentation to know about the available options.

The Platformatic CLI generates

  • api.d.ts: A TypeScript module that includes all the OpenAPI-related types. Here is part of the generated code
interface GetMoviesRequest {
'limit'?: number;
'offset'?: number;
// ... etc.
}

interface GetMoviesResponseOK {
'id'?: number;
'title': string;
}


// ... etc.

export interface Api {
setBaseUrl(baseUrl: string): void;
setDefaultHeaders(headers: Object): void;
getMovies(req: GetMoviesRequest): Promise<Array<GetMoviesResponseOK>>;
createMovie(req: CreateMovieRequest): Promise<CreateMovieResponseOK>;
// ... etc.
}
  • api.ts: A TypeScript module that includes a typed function for every single OpenAPI endpoint. Here is part of the generated code
import type { Api } from './api-types'

let baseUrl = ''
let defaultHeaders = {}

export const setBaseUrl = (newUrl: string) { baseUrl = newUrl };

export const setDefaultHeaders = (headers: Object): void => { defaultHeaders = headers }

export const createMovie: Api['createMovie'] = async (request) => {
const response = await fetch(`${baseUrl}/movies/`, {
method:'post',
body: JSON.stringify(request),
headers: {
'Content-Type': 'application/json'
}
})

if (!response.ok) {
throw new Error(await response.text())
}

return await response.json()
}

// etc.

You can add a --name option to the command line to provide a custom name for the generated files.

cd rest-api-frontend/src
npx platformatic client http://127.0.0.1:3042 --frontend --name foobar --language ts

This will generate foobar.ts and foobar-types.d.ts

React and Vue.js components that read, create, and update an entity

You can copy/paste the following React or Vue.js components that import the code the Platformatic CLI generated.

Create a new file src/PlatformaticPlayground.tsx and copy/paste the following code.

import { useEffect, useState } from 'react'

// getMovies, createMovie, and updateMovie are all functions automatically generated by Platformatic
// in the `api.ts` module.
import {
getMovies,
createMovie,
updateMovie,
setBaseUrl,
type GetMoviesResponseOK,
type CreateMovieResponseOK
} from './api'

setBaseUrl('http://127.0.0.1:3042') // configure this according to your needs

export function PlatformaticPlayground() {
const [movies, setMovies] = useState<GetMoviesResponseOK>([])
const [newMovie, setNewMovie] = useState<CreateMovieResponseOK>()

async function onCreateMovie() {
const newMovie = await createMovie({ title: 'Harry Potter' })
setNewMovie(newMovie)
}

async function onUpdateMovie() {
if (!newMovie || !newMovie.id) return

const updatedMovie = await updateMovie({ id: newMovie.id, title: 'The Lord of the Rings' })
setNewMovie(updatedMovie)
}

useEffect(() => {
async function fetchMovies() {
const movies = await getMovies({})
setMovies(movies)
}

fetchMovies()
}, [])

return (
<>
<h2>Movies</h2>

{movies.length === 0 ? (
<div>No movies yet</div>
) : (
<ul>
{movies.map((movie) => (
<li key={movie.id}>{movie.title}</li>
))}
</ul>
)}

<button onClick={onCreateMovie}>Create movie</button>
<button onClick={onUpdateMovie}>Update movie</button>

{newMovie && <div>Title: {newMovie.title}</div>}
</>
)
}

Import the new component in your front-end application

You need to import and render the new component in the front-end application.

Change the App.tsx as follows

import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'

+import { PlatformaticPlayground } from './PlatformaticPlayground'

function App() {
const [count, setCount] = useState(0)

return (
<>
+ <PlatformaticPlayground />
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>count is {count}</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">Click on the Vite and React logos to learn more</p>
</>
)
}

export default App

Have fun

Art the top of the front-end application the new component requests the movies to the Platformatic app and list them.

Platformatic frontend guide: listing the movies

Click on "Create movie" to create a new movie called "Harry Potter".

Platformatic frontend guide: creating a movie

Click on "Update movie" to rename "Harry Potter" into "Lord of the Rings".

Platformatic frontend guide: editing a movie

Reload the front-end application to see the new "Lord of the Rings" movie listed.

Platformatic frontend guide: listing the movies .