Skip to content

niklioni/jokes

Repository files navigation

Jokes Platform

A distributed, microservices-based jokes platform deployed on Azure. Users can browse jokes by category, submit new ones, and an authenticated moderator reviews submissions before they go live.

Architecture

                         ┌─────────────────────────────────────┐
                         │         Kong API Gateway             │
                         │    (rate limiting, SSL termination)  │
                         └──────┬──────────┬───────────┬───────┘
                                │          │           │
                    ┌───────────┘    ┌─────┘     ┌────┘
                    ▼                ▼            ▼
             ┌────────────┐  ┌────────────┐  ┌───────────┐
             │   jokes    │  │   submit   │  │  moderate │
             │  service   │  │  service   │  │  service  │
             │  :3000     │  │  :3200     │  │  :3100    │
             └─────┬──────┘  └─────┬──────┘  └─────┬─────┘
                   │               │                │
                   │        ┌──────▼────────────────▼──────┐
                   │        │         RabbitMQ              │
                   │        │  submit queue → moderate      │
                   │        │  moderated queue → ETL        │
                   │        │  type_update exchange (fanout)│
                   │        └──────────────┬────────────────┘
                   │                       │
                   ▼                       ▼
             ┌────────────────────────────────┐
             │           ETL service          │
             │  seeds DB · inserts jokes      │
             │  broadcasts type_update events │
             └────────────────────────────────┘
                            │
                            ▼
                  ┌──────────────────┐
                  │  MySQL / MongoDB │
                  │  (switchable via │
                  │   DB_TYPE env)   │
                  └──────────────────┘

Services

Service Port Description
jokes 3000 REST API — serves jokes from the database
submit 3200 Public UI + API — accepts joke submissions via RabbitMQ
moderate 3100 Auth0-protected UI — moderators approve or reject submissions
etl 3001 Consumes approved jokes from queue, writes to DB, broadcasts new types
Kong 80/443 API gateway with rate limiting (100 req/min on jokes API)
RabbitMQ 5672 Message broker between submit → moderate → ETL

Message Flow

  1. User submits a joke via submit → pushed to submit queue
  2. Moderator reviews it via moderate → approved joke pushed to moderated queue
  3. ETL consumes the moderated queue → inserts joke into DB
  4. If a new joke type was created, ETL publishes a type_update fanout event
  5. submit and moderate subscribe to type_update and update their local type caches

Tech Stack

  • Node.js / Express — all services
  • MySQL 8 (default) or MongoDB 7 — switchable via DB_TYPE env var
  • RabbitMQ 3 — message queuing (durable queues, fanout exchange)
  • Kong — API gateway (DB-less declarative config)
  • Auth0 — OIDC authentication for the moderation UI
  • Docker / Docker Compose — local development and production deployment
  • Terraform — Azure infrastructure as code (VNets, NSGs, Linux VMs)
  • Cloudflare — DNS + Let's Encrypt SSL via Terraform

Local Development

Prerequisites

  • Docker and Docker Compose

Setup

# 1. Copy the env example and fill in your values
cp .env.example .env

# 2. Start all services (MySQL + RabbitMQ + all microservices + Kong)
docker compose up

Services will be available at:

URL Service
http://localhost Jokes frontend (via Kong)
http://localhost/submit Submit a joke (via Kong)
http://localhost/moderate Moderation UI (via Kong)
http://localhost:4000 Jokes API (direct)
http://localhost:4200/docs Submit API — Swagger docs
http://localhost:15672 RabbitMQ management UI

Auth0 Setup (for moderation)

  1. Create a Regular Web Application in your Auth0 dashboard
  2. Add http://localhost:4100/callback to Allowed Callback URLs
  3. Add http://localhost:4100 to Allowed Logout URLs
  4. Fill in the AUTH0_* variables in your .env file

Database selection

The jokes and etl services support both MySQL and MongoDB:

# Use MongoDB instead of MySQL
DB_TYPE=mongo docker compose -f compose/docker-compose-local.yml up

API Reference

Jokes API (/)

Method Path Description
GET /types List all joke categories
GET /joke/:type Get a random joke of a given type
GET /joke/:type?count=N Get N random jokes
GET /joke/count/:type Count jokes of a given type

Submit API (/submit)

Full OpenAPI documentation available at http://localhost:4200/docs

Method Path Description
GET /types List all joke categories (cached)
POST /submit Submit a joke { setup, punchline, type }

Moderate API (/moderate) — Auth required

Method Path Description
GET /moderate Fetch next pending joke from queue
POST /moderated Approve and publish a joke
POST /reject Reject a joke

Cloud Deployment (Azure)

Infrastructure is managed with Terraform and deploys one Linux VM per service into separate subnets with NSG rules.

infra/
├── main.tf       # Azure + Cloudflare providers, resource groups
├── network.tf    # VNet, subnets, NSGs, public IPs, NICs
├── vm.tf         # VMs, Docker image build/push, docker compose up
└── variables.tf  # All variable declarations

Deploy

cd infra

# Copy and fill in your variables
cp terraform.tfvars.example terraform.tfvars

# Sensitive values (SSH key, tokens) go in a separate gitignored file
cat > secret.tfvars <<EOF
pub_key            = "$(cat ~/.ssh/id_rsa.pub)"
dockerhub_token    = "YOUR_TOKEN"
cloudflare_token   = "YOUR_TOKEN"
cloudflare_zone_id = "YOUR_ZONE_ID"
EOF

terraform init
terraform apply -var-file="secret.tfvars"

Terraform will:

  1. Create the Azure resource groups, VNet, subnets and NSGs
  2. Build and push Docker images to Docker Hub
  3. Provision the VMs, install Docker, copy compose files
  4. Start all services via docker compose up -d
  5. Obtain a Let's Encrypt certificate via Certbot
  6. Create a Cloudflare DNS A record pointing to the Kong VM

Project Structure

.
├── jokes/          # Jokes REST API service
├── submit/         # Joke submission service + UI
├── moderate/       # Moderation service + UI (Auth0 protected)
├── etl/            # ETL: seeds DB, consumes approved jokes
├── kong/           # Kong declarative config (local + prod)
├── infra/          # Terraform (Azure + Cloudflare)
├── data/           # Initial jokes dataset (JSON)
├── compose/        # Deployment compose files (per-VM + variants)
│   ├── docker-compose-local.yml        # Local dev with MongoDB
│   ├── docker-compose-build.yml        # Build + push images to Docker Hub
│   ├── docker-compose-db.yml           # Prod: DB VM (MySQL + jokes + ETL)
│   ├── docker-compose-rabbitmq.yml     # Prod: RabbitMQ VM
│   ├── docker-compose-submit.yml       # Prod: submit VM
│   └── docker-compose-moderate.yml     # Prod: moderate VM
└── docker-compose.yml              # Local dev (all services)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors