This repository contains a restaurant reviews platform split into two services:
reviews-api-service: Node.js + TypeScript REST API for users, restaurants, and reviews.sentiment-grpc-service: Python gRPC service that performs sentiment analysis with a Transformers model.
The API service sends review text to the gRPC service, stores reviews in PostgreSQL via Prisma, and maintains review sentiment aggregates/rankings in Redis.
reviews-api-service/: Express API, Prisma schema/migrations, Swagger docs, queue workers, tests.sentiment-grpc-service/: gRPC server and sentiment inference logic.shared-proto/: shared gRPC contract (sentiment.proto).
- Client calls
POST /reviewsorPATCH /reviews/{id}. - API enqueues a BullMQ job and responds immediately with
202andjobId. - BullMQ worker processes the job:
- creates/updates review in PostgreSQL
- calls gRPC NLP service for sentiment prediction
- persists sentiment and confidence
- updates Redis restaurant sentiment stats and ranking sorted set
- API: Express, TypeScript, Zod, Prisma, BullMQ
- Data: PostgreSQL
- Cache/Queue backend: Redis
- NLP service: Python, gRPC, Hugging Face Transformers (
distilbert-base-uncased-finetuned-sst-2-english) - API docs: Swagger
- Tests: Jest
Install and run these dependencies locally:
- Node.js 18+
- Python 3.10+
- PostgreSQL
- Redis
Create a .env file in reviews-api-service/ with:
PORT=3000
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/nlp_restaurant
JWT_SECRET=change_me
# Redis (used by BullMQ and sentiment stats)
REDIS_URL=redis://127.0.0.1:6379
# gRPC NLP service target
NLP_GRPC_HOST=127.0.0.1
NLP_GRPC_PORT=50051
NLP_GRPC_TARGET=127.0.0.1:50051
# Optional override to proto location
# NLP_GRPC_PROTO_PATH=/absolute/path/to/shared-proto/sentiment.protoCreate a .env file in sentiment-grpc-service/ with:
NLP_GRPC_HOST=0.0.0.0
NLP_GRPC_PORT=50051Start PostgreSQL and Redis first.
cd sentiment-grpc-service
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python main.pyThe service listens on 0.0.0.0:50051 by default.
cd reviews-api-service
npm install
npm run prisma:generate
npm run prisma:migrate
npm run devAPI default URL: http://localhost:3000
Swagger UI: http://localhost:3000/api-docs
From reviews-api-service/:
npm run dev
npm test
npm run test:coverage
npm run prisma:generate
npm run prisma:migrate
npm run prisma:studioFrom sentiment-grpc-service/:
python main.py
python test_client.py "The food was amazing"-
Per-restaurant sentiment hash:
-
key:
restaurant:sentiment:{restaurantId} -
fields:
positiveReviews,negativeReviews -
Ranking sorted set:
-
key:
restaurants:ranking:positive-reviews -
score: number of positive reviews
-
member:
restaurantId
- Review create/update API calls are asynchronous by design and return immediately after queueing.
- Worker startup is triggered in API bootstrap.
- If the NLP service is down, jobs will retry according to BullMQ retry settings.