Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Node.js Express Full-Text Search with Typesense

A production-ready RESTful search API built with Node.js, Express, PostgreSQL (Prisma), and Typesense. Features full-text search, CRUD operations, real-time async indexing, and background sync workers.

Tech Stack

  • Node.js
  • Express
  • PostgreSQL with Prisma ORM
  • Typesense
  • TypeScript
  • Docker

Prerequisites

  • Node.js v18+ installed
  • Docker (for Typesense and PostgreSQL)
  • Basic knowledge of REST APIs and SQL

Quick Start

1. Clone the repository

git clone https://github.com/typesense/code-samples.git
cd typesense-node-prisma-full-text-search

2. Install dependencies

npm install

3. Start Typesense and PostgreSQL

Run Typesense and PostgreSQL using Docker:

# Start Typesense (replace TYPESENSE_VERSION with the latest from https://typesense.org/docs/guide/install-typesense.html)
docker run -d \
  -p 8108:8108 \
  -v typesense-data:/data \
  typesense/typesense:27.1 \
  --data-dir /data \
  --api-key=xyz \
  --enable-cors

# Start PostgreSQL
docker run -d \
  -p 5432:5432 \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=typesense_books \
  -v postgres-data:/var/lib/postgresql/data \
  postgres:15

4. Set up environment variables

Create a .env file in the project root by copying .env.example:

cp .env.example .env

5. Project Structure

├── prisma/
│   └── schema.prisma        # Prisma schema and model definitions
├── src/
│   ├── config/
│   │   ├── database.ts      # Prisma Client instantiation
│   │   └── env.ts           # Environment variable validation
│   ├── routes/
│   │   ├── books.ts         # CRUD endpoints for books
│   │   └── search.ts        # Search and sync endpoints
│   ├── search/
│   │   ├── client.ts        # Typesense client initialization
│   │   ├── collections.ts   # Typesense collection schema
│   │   ├── sync.ts          # Sync logic (incremental, full, soft delete)
│   │   └── worker.ts        # Background sync worker
│   └── server.ts            # Main application entry point
├── package.json
├── tsconfig.json
└── .env

6. Database Migrations

Development Environment: When building out your schema or making changes during development, use the db push command. It pushes your schema state directly to the database without generating history:

npx prisma db push

Production Environment: For production, you should use Prisma Migrate to generate and apply consistent database migrations. Generate a migration (run this in dev when ready):

npx prisma migrate dev --name init_books

Apply migrations safely in production (e.g., during your CI/CD pipeline):

npx prisma migrate deploy

7. Start the development server

npm run dev

The server will automatically restart when you make changes to any TypeScript file.

Open http://localhost:3000 in your browser.

8. API Endpoints

Search

GET /search?q=<query>

Example:

curl "http://localhost:3000/search?q=harry"

CRUD Operations

Create a book:

POST /books
Content-Type: application/json

{
  "title": "The Go Programming Language",
  "authors": ["Alan Donovan", "Brian Kernighan"],
  "publication_year": 2015,
  "average_rating": 4.5,
  "image_url": "https://example.com/image.jpg",
  "ratings_count": 1000
}

Get a book:

GET /books/:id

Get all books (with pagination):

GET /books?page=1&limit=10

Update a book:

PUT /books/:id
Content-Type: application/json

{
  "title": "Updated Title",
  "authors": ["Author Name"],
  "publication_year": 2024,
  "average_rating": 4.8,
  "image_url": "https://example.com/updated.jpg",
  "ratings_count": 1500
}

Delete a book (soft delete):

DELETE /books/:id

Sync Operations

Trigger manual sync:

POST /sync

Check sync status:

GET /sync/status

9. How It Works

Architecture

User Request
    ↓
Express API (CRUD)
    ↓
PostgreSQL (Source of Truth)
    ↓
Async Sync → Typesense (Search Index)
    ↑
Background Worker (Every 60s)

Sync Strategies

1. Startup Sync (Smart)

On every server start, the sync worker checks whether the Typesense collection already has documents. If empty, it seeds lastSyncTime to zero and runs a full sync. If it has data, it runs an incremental sync since MAX(updated_at) of PostgreSQL books table.

2. Real-time Sync (Async)

Triggered on Create, Update, Delete operations in the background.

3. Background Periodic Sync

Runs every 60 seconds automatically, doing incremental sync.

4. Manual Sync

Endpoint: POST /sync