Skip to content

Build Your First API - Blog REST API

This tutorial will walk you through building a complete blog REST API from scratch using Restura. You’ll create a multi-table database with users and blog posts, along with API endpoints to manage them—all using the Visual Editor.

By the end of this tutorial, you’ll have a complete blog API with:

  • An Express application with Restura integrated
  • A local PostgreSQL database running in Docker
  • The Restura Visual Editor running and connected to your API
  • A user table for blog authors
  • A post table with a foreign key relationship to users
  • REST API endpoints to:
    • List all users
    • List all posts
    • Get posts by a specific author
    • Get a single post with author information (using JOINs)
    • Add a new post
    • Add a new user

This tutorial teaches you the real Restura workflow:

  1. Set up the infrastructure (Express, PostgreSQL, Restura)
  2. Use the Visual Editor to design database tables with relationships
  3. Use the Visual Editor to create API endpoints with JOINs
  4. Let Restura automatically generate SQL, types, and API handlers
  • Node.js 18+ installed
  • Docker Compose installed
  • Git installed
  • A terminal and text editor
  • Basic knowledge of JavaScript/TypeScript

First, let’s create a new Express project.

Run the following commands in your terminal:

Terminal window
mkdir restura-demo
cd restura-demo
npm init -y
npm install express
Section titled “Install TypeScript (Optional but Recommended)”

If you want to use TypeScript, install it now:

Terminal window
npm install -D typescript @types/express @types/node
npx tsc --init

Create a file called server.ts (or server.js if not using TypeScript):

We’ll add content to this file after installing Restura.

Now install the Restura Engine:

Terminal window
npm install @restura/core

Step 3: Initialize Restura in Your Express App

Section titled “Step 3: Initialize Restura in Your Express App”

Open your server.ts (or server.js) file and add the following code:

server.ts
import { PsqlPool, restura, type OnValidAuthenticationCallback, type RsRequest, type RsResponse } from '@restura/core';
import express from 'express';
const app = express();
// Create a PostgreSQL connection pool
// We'll use these credentials with our Docker setup below
const pool = new PsqlPool({
host: "localhost",
port: 5432,
user: "postgres",
password: "postgres",
database: "restura",
});
// Define an authentication handler
// For now, we'll allow all requests as the 'user' role
const authHandler = async (req: RsRequest<unknown>, res: RsResponse<unknown>, onValid: OnValidAuthenticationCallback) => {
onValid({ role: 'user', scopes: [] });
};
// Initialize Restura
await restura.init(app, authHandler, pool);
app.listen(3001, () => {
console.log('Server is running on http://localhost:3001');
});

Update your package.json to add a start script:

package.json
{
"type": "module",
"scripts": {
"start": "node server.ts"
}
}

Restura needs two configuration files to work.

Create a restura.config.mjs file in your project root:

restura.config.mjs
export default {
logger: {
level: "info" // Options: "debug", "info", "warn", "error"
},
restura: {
authToken: "12345" // Used by the Visual Editor to connect to your API
}
}

Create a restura.schema.json file in your project root.

Add the following content to the file:

restura.schema.json
{
"customTypes": [],
"database": [],
"endpoints": [
{
"baseUrl": "/api/v1",
"description": "V1 Endpoints",
"name": "V1",
"routes": []
}
],
"globalParams": ["userId"],
"roles": ["anonymous", "user", "admin"],
"scopes": ["read:user", "write:user"]
}

This creates a minimal schema with an empty database and endpoint structure that the Visual Editor can work with.

For this tutorial, we’ll use Docker Compose to run a local PostgreSQL database.

Create a docker-compose.yml file in the root of your project with the following content:

docker-compose.yml
services:
postgres:
image: postgres:16
ports:
- 5432:5432
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: restura

Then run the following command to start the local PostgreSQL database:

Terminal window
docker compose up -d

The database is now running in the background. The credentials in your server.ts file match this setup, so you’re ready to go!

Now let’s start your API server. Open a terminal and run:

Terminal window
npm start # or pnpm start, yarn start, bun start, etc.

You should see output like:

Terminal window
INFO [2026-01-12 04:25:34.373]: Restura loaded (0) endpoint
INFO [2026-01-12 04:25:34.379]: Restura Engine Initialized
INFO [2026-01-12 04:25:34.495]: Successfully connected to database triggers
INFO [2026-01-12 04:25:34.498]: Connected to PostgreSQL database
Server is running on http://localhost:3001

Keep this terminal running. Your API server needs to be running for the Visual Editor to connect to it.

The Visual Editor is a web application that lets you visually design your database tables and API endpoints.

Once you’ve completed the Visual Editor setup and signed in, you should see an empty dashboard with options to create database tables and endpoints.

Step 8: Create Your Database Tables Using the Visual Editor

Section titled “Step 8: Create Your Database Tables Using the Visual Editor”

Now let’s create the database schema for our blog. We’ll create two tables: user (for authors) and post (for blog posts).

First, let’s create a table to store blog authors.

  1. In the Visual Editor, click on “Database” in the left sidebar
  2. Click the ”+ Add Table” button
  3. Name your table user
  4. Click “Create”

Click on your new user table to open the table editor, then add these columns:

  1. firstName column:

    • Click ”+ Add Column”
    • Name: firstName
    • Type: VARCHAR
    • Length: 150
    • Nullable: ✗
  2. lastName column:

    • Click ”+ Add Column”
    • Name: lastName
    • Type: VARCHAR
    • Length: 150
    • Nullable: ✗
  3. email column:

    • Click ”+ Add Column”
    • Name: email
    • Type: VARCHAR
    • Length: 255
    • Nullable: ✗
  4. bio column:

    • Click ”+ Add Column”
    • Name: bio
    • Type: TEXT
    • Nullable: ✓ (bio is optional)
  5. role column:

    • Click ”+ Add Column”
    • Name: role
    • Type: VARCHAR
    • Length: 50
    • Nullable: ✗
  1. In the table editor, scroll to the “Indexes” section
  2. Click ”+ Add Index”
    • Name: user_email_unique_index
    • Columns: Select email
    • Unique: ✓
  3. Click “Save” to save the user table

Now let’s create a table for blog posts that references the user table.

  1. Click ”+ Add Table” again
  2. Name your table post
  3. Click “Create”

Click on your new post table and add these columns:

  1. title column:

    • Click ”+ Add Column”
    • Name: title
    • Type: VARCHAR
    • Length: 200
    • Nullable: ✗
  2. content column:

    • Click ”+ Add Column”
    • Name: content
    • Type: TEXT
    • Nullable: ✗
  3. authorId column (foreign key to user):

    • Click ”+ Add Column”
    • Name: authorId
    • Type: BIGINT
    • Nullable: ✗
  4. published column:

    • Click ”+ Add Column”
    • Name: published
    • Type: BOOLEAN
    • Default: false
    • Nullable: ✗
  1. Scroll to the “Indexes” section
  2. Click ”+ Add Index”
  3. Name: post_author_id_index
  4. Columns: Select authorId
  5. Unique: ✗ (one author can have many posts)
  6. Click “Save”
  1. Click “Save” in the top right of the Visual Editor
  2. The Visual Editor will update your restura.schema.json file automatically
  3. Your Restura API will detect the change and reload
  1. In the Visual Editor, go to “Database”“Generate SQL”
  2. Copy the generated SQL
  3. In your project terminal, create a file called schema.sql and paste the SQL
  4. Run this command to apply it:
Terminal window
docker compose exec -T postgres psql -U postgres -d restura < ./schema.sql

Let’s add a sample user to test with. Run this command:

Terminal window
docker compose exec -T postgres psql -U postgres -d restura -c "
INSERT INTO public.\"user\" (
\"firstName\",
\"lastName\",
email,
role
) VALUES (
'Test',
'User',
'test@restura.io',
'user'
);"

Now let’s add a sample blog post. Run this command:

Terminal window
docker compose exec -T postgres psql -U postgres -d restura -c "
INSERT INTO public.post (
title,
content,
\"authorId\"
) VALUES (
'Welcome to My Blog',
'This is my first blog post using Restura! It''s amazing how easy it is to build APIs without writing SQL queries or endpoint handlers.',
1
);"

Now let’s create an API endpoint to list all users.

  1. In the Visual Editor, click on “API” in the left sidebar
  2. Click “New”

Fill in the route details:

  1. Name: Get Users
  2. Description: Gets all users
  3. Method: GET
  4. Path: /user/list
  5. Type: ARRAY (returns an array of results)
  6. Table: Select user
  7. Roles: Select user and admin (who can access this endpoint)

In the “Response” section, add the fields you want to return:

  1. Click ”+ Add Field” for each column:
    • Field name: id, Selector: user.id
    • Field name: createdOn, Selector: user.createdOn
    • Field name: modifiedOn, Selector: user.modifiedOn
    • Field name: firstName, Selector: user.firstName
    • Field name: lastName, Selector: user.lastName
    • Field name: email, Selector: user.email
    • Field name: role, Selector: user.role
  1. Click “Save” in the top right
  2. The Visual Editor updates your restura.schema.json file
  3. Your Restura API automatically reloads and registers the new endpoint

Check your API server terminal—you should now see:

Terminal window
INFO: Restura loaded (1) endpoint

Let’s take a look at what the Visual Editor created. Open your restura.schema.json file in your text editor.

You’ll see:

  • database array: Contains your user table definition with all columns, indexes, and constraints
  • endpoints array: Contains your V1 endpoint group
  • routes array: Contains your GET /user/list endpoint with response fields
  • roles and scopes: Access control configuration

The Visual Editor generated all of this JSON for you! You never had to write it manually.

Restura also generated TypeScript type definitions in src/@types/:

  • api.d.ts - Types for your API endpoints (including the /user/list endpoint)
  • model.d.ts - Types for your database tables (including the user table)
  • restura.d.ts - General Restura types

Open src/@types/api.d.ts and you’ll see type definitions for your new endpoint!

Congratulations! Your API is now running. Let’s test it.

Open a new terminal and run:

Terminal window
curl -X GET http://localhost:3001/api/v1/user/list

You should receive a JSON response with your user data:

[
{
"id": 1,
"createdOn": "2026-01-12T12:00:00.000Z",
"modifiedOn": "2026-01-12T12:00:00.000Z",
"firstName": "Test",
"lastName": "User",
"email": "test@restura.io",
"role": "user"
}
]

🎉 It works! You just built a complete REST API without writing any SQL queries or endpoint handler code!

When you made the request:

  1. Restura received the GET request at /api/v1/user/list
  2. Your authHandler validated the request and assigned the ‘user’ role
  3. Restura checked that ‘user’ role has permission to access this endpoint (you configured this in the Visual Editor)
  4. Restura automatically generated and executed this SQL query:
    SELECT id, "createdOn", "modifiedOn", "firstName", "lastName", email, role
    FROM "user"
  5. The results were formatted as JSON and returned

Now that you’ve built your first endpoint, try adding these features using the Visual Editor:

  1. Create a GET endpoint at /post/list that returns all posts
  2. Create a GET endpoint at /post/by-author that filters posts by author
  3. Create a GET endpoint at /post/by-id that returns a single post by ID

You’ve just experienced the core Restura workflow:

  1. Design → Use the Visual Editor to design tables and endpoints
  2. Generate → Restura generates schema JSON, SQL, and TypeScript types
  3. Deploy → Apply SQL to database, Restura handles the rest
  4. Use → Your API is ready with full type safety

No manual SQL queries. No endpoint handler code. No type definitions to maintain. Just design and go!

In this tutorial, you:

  • ✅ Set up an Express application with Restura
  • ✅ Created a local PostgreSQL database with Docker
  • ✅ Connected the Visual Editor to Restura
  • Created a database table using the Visual Editor (no manual JSON editing!)
  • Created a REST API endpoint using the Visual Editor (no code required!)
  • ✅ Examined the automatically generated schema and TypeScript types
  • ✅ Tested your endpoint and saw it work