Skip to content

YorberR/Microservices

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌐 Social Network Microservices API

A robust, scalable RESTful API built with a microservices architecture for a social networking platform. This project demonstrates advanced skills in distributed systems, Serverless deployment, and CI/CD pipelines.

Architecture: Microservices Deployment: Render Database: Neon PostgreSQL CI/CD: GitHub Actions Container Registry: Docker Hub


πŸ“‹ Overview

This system implements the core backend logic for a social network. Instead of a traditional monolith, the application is divided into 3 containerized services that communicate via HTTP. It features centralized JWT authentication and a fully automated deployment pipeline to Docker Hub.

✨ Key Features

  • Distributed Architecture: Services for Users, Posts, Follows, and Likes.
  • Multi-Process Container: Multiple Node.js processes running in a single container with shell script.
  • Automated CI/CD: GitHub Actions workflow automatically builds Docker images and pushes to Docker Hub on every push to the main branch.
  • Cloud Database: Powered by Neon's free permanent PostgreSQL.
  • Centralized Auth: Secure endpoints protected by JWT validation.
  • API Gateway Pattern: API Service acts as the single entry point for all client requests.

πŸ—οΈ System Architecture

The application uses an API Gateway pattern where the API Service is the single entry point, with a shell script managing multiple processes within a container.

graph TD
    Client([Client / App / Postman])
    
    subgraph "Render Cloud"
        API[API Gateway\n:3000]
        CONTENT[Content Service\n:3001,3003,3004]
        DB_SVC[DB Service\n:3002]
    end
    
    subgraph "External"
        NEON[(Neon PostgreSQL)]
    end

    Client -- HTTP / Bearer JWT --> API
    
    API -- HTTP --> CONTENT
    CONTENT -- HTTP --> DB_SVC
    
    DB_SVC -- SSL Connection --> NEON
Loading

API Gateway Pattern

The API Service (port 3000) functions as the API Gateway:

  • Receives all client requests
  • Handles JWT authentication
  • Routes requests to internal services

Service Distribution

Service Container Ports Description
api-service Docker 3000 Auth + Users + Routing
content-service Docker (shell script) 3001, 3003, 3004 Posts + Follows + Likes
db-service Docker 3002 Database access layer

πŸš€ Tech Stack

Category Technologies Used
Backend Core Node.js, Express.js, TypeScript
Architecture Microservices, API Gateway Pattern
Database PostgreSQL (Neon Free Tier)
Security JWT (JSON Web Tokens), bcrypt
DevOps & CI/CD Docker, GitHub Actions
Cloud Provider Render (Web Services) + Neon (PostgreSQL)
Container Registry Docker Hub

πŸ“¦ Prerequisites

Before running the project, ensure you have:

  • Node.js 18+ installed
  • Docker Desktop installed and running
  • npm or yarn package manager
  • Docker Hub account (for container registry)
  • Render account (for web services hosting)
  • Neon account (for cloud database)

πŸš€ Quick Start

1. Clone the Repository

git clone https://github.com/YorberR/Microservices.git
cd Microservices

2. Install Dependencies

npm install

3. Configure Environment Variables

Create a .env file in the root directory:

API_PORT=3000
JWT_SECRET=your-secret-key

DB_HOST=localhost
DB_PORT=5432
DB_NAME=microservices
DB_USER=postgres
DB_PASSWORD=postgres

POST_SERVICE_PORT=3001
FOLLOW_SERVICE_PORT=3003
LIKE_SERVICE_PORT=3004
PG_SERVICE_PORT=3002

4. Set Up Database

Option A: Local PostgreSQL

  1. Create a database named microservices
  2. Run the SQL commands in the Database Schema section below

Option B: Neon PostgreSQL (Recommended for Cloud)

  1. Create a project at neon.tech
  2. Create a new PostgreSQL database
  3. Run the SQL commands in the Database Schema section below
  4. Update .env with your Neon PostgreSQL connection string
  5. Add DB_SSL=true to enable SSL connection

5. Run Locally

With Docker (Recommended)

docker-compose up --build

Without Docker (Individual Services)

# Terminal 1 - PostgreSQL Service
npm run dev:postgres

# Terminal 2 - Main API
npm run dev

# Terminal 3 - Post Service
npm run dev:post

# Terminal 4 - Follow Service
npm run dev:follow

# Terminal 5 - Like Service
npm run dev:like

πŸ“š API Endpoints

Authentication

Endpoint Method Description
/api/auth/login POST Login and get JWT token
/api/auth/verify POST Verify JWT token

Users

Endpoint Method Description
/api/user GET List all users
/api/user POST Create new user
/api/user/:id GET Get user by ID
/api/user/:id PUT Update user
/api/user/:id DELETE Delete user

Posts

Endpoint Method Description
/api/posts GET List all posts
/api/posts POST Create new post
/api/posts/:uuid GET Get post by UUID
/api/posts/:uuid PUT Update post
/api/posts/:uuid DELETE Delete post
/api/posts/user/:userId GET Get posts by user

Follows

Endpoint Method Description
/api/follows POST Follow a user
/api/follows/:followerId/:followingId DELETE Unfollow
/api/follows/followers/:userId GET Get followers
/api/follows/following/:userId GET Get following
/api/follows/check/:followerId/:followingId GET Check follow status

Likes

Endpoint Method Description
/api/likes POST Like a post
/api/likes/:userId/:postId DELETE Unlike
/api/likes/post/:postId GET Get likes on post
/api/likes/user/:userId GET Get user likes
/api/likes/check/:userId/:postId GET Check like status
/api/likes/count/:postId GET Get like count

πŸ” Authentication

Test Credentials

  • Username: user1
  • Password: pass123

Authentication Flow

  1. Login: Send username and password to /api/auth/login

    POST /api/auth/login
    {
      "username": "user1",
      "password": "pass123"
    }
  2. Get Token: Receive JWT in response

    {
      "error": false,
      "status": 200,
      "body": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
  3. Use Token: Include JWT in headers for protected endpoints

    Authorization: Bearer <your-jwt-token>
    
  4. Authorization Check: Other services verify JWT via /api/auth/verify

    POST /api/auth/verify
    {
      "token": "eyJ...",
      "action": "create",
      "resource": "post",
      "ownerId": 1
    }

🐳 Docker

Build Docker Images

# Build all services
docker-compose build

Run with Docker Compose

docker-compose up -d

Stop Services

docker-compose down

☁️ Deployment (Render + Docker Hub + Neon)

Prerequisites

  1. Create a Render account (for web services)
  2. Create a Neon account (for PostgreSQL)
  3. Create a Docker Hub account
  4. Create an Access Token in Docker Hub (if logging in via GitHub)

Configure GitHub Secrets

In your GitHub repository, add these secrets:

  • DOCKER_USERNAME: Your Docker Hub username
  • DOCKER_PASSWORD: Your Docker Hub password or access token

Deploy

Simply push to the main branch:

git add .
git commit -m "Deploy to production"
git push origin main

GitHub Actions will automatically build and push Docker images to Docker Hub.

Render Setup

After images are pushed to Docker Hub:

  1. Create Web Services in Render:

    • db-service: docker.io/your-username/db-service:latest, port 3002
    • api-service: docker.io/your-username/api-service:latest, port 3000
    • content-service: docker.io/your-username/content-service:latest, port 3001
  2. Create Neon PostgreSQL:

    • Go to neon.tech
    • Create a new project
    • Note the connection details (host, port, user, password, database)
  3. Configure Environment Variables for each service:

    DB_HOST: your-postgres-host.neon.tech
    DB_PORT: 5432
    DB_NAME: your_database_name
    DB_USER: your_username
    DB_PASSWORD: your_password
    DB_SSL: true
    

Cost Optimization

The deployment is designed to be free:

  • Render: 750 hours/month across all web services (free tier)
  • Neon: Always free PostgreSQL (no expiration)
  • Docker Hub: Free container registry
  • Services sleep after 15 minutes of inactivity

Estimated Cost: $0/month for typical portfolio traffic


πŸ“‚ Project Structure

microservices/
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── deploy.yml              # CI/CD for Docker Hub
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ api/                       # Main API service
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ auth/              # Authentication
β”‚   β”‚   β”‚   └── user/              # User management
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── Dockerfile             # β†’ api-service
β”‚   β”‚
β”‚   β”œβ”€β”€ content-service/           # Multi-service container (Post + Follow + Like)
β”‚   β”‚   β”œβ”€β”€ Dockerfile             # β†’ content-service
β”‚   β”‚   β”œβ”€β”€ start.sh              # Shell script to start all services
β”‚   β”‚   └── (references post/follow/like services)
β”‚   β”‚
β”‚   β”œβ”€β”€ post-service/              # Posts microservice
β”‚   β”‚   β”œβ”€β”€ components/post/
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── swagger.json
β”‚   β”‚
β”‚   β”œβ”€β”€ follow-service/             # Follows microservice
β”‚   β”‚   β”œβ”€β”€ components/follow/
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── swagger.json
β”‚   β”‚
β”‚   β”œβ”€β”€ like-service/              # Likes microservice
β”‚   β”‚   β”œβ”€β”€ components/like/
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── swagger.json
β”‚   β”‚
β”‚   β”œβ”€β”€ postgres-service/          # Database access layer
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   β”œβ”€β”€ network.ts
β”‚   β”‚   β”œβ”€β”€ swagger.json
β”‚   β”‚   └── Dockerfile             # β†’ db-service
β”‚   β”‚
β”‚   β”œβ”€β”€ store/                     # Database clients
β”‚   β”‚   β”œβ”€β”€ postgres.ts            # PostgreSQL client
β”‚   β”‚   └── remote.ts              # HTTP client
β”‚   β”‚
β”‚   β”œβ”€β”€ auth/                      # JWT utilities
β”‚   β”œβ”€β”€ network/                   # Response helpers
β”‚   β”œβ”€β”€ utils/                     # Error handling
β”‚   └── config.ts                  # Configuration
β”‚
β”œβ”€β”€ .dockerignore
β”œβ”€β”€ .env                           # Environment variables
β”œβ”€β”€ docker-compose.yml             # Docker Compose (local)
β”œβ”€β”€ package.json
└── tsconfig.json

πŸ—„οΈ Database Schema

Create these tables in your PostgreSQL database:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    uuid VARCHAR(50) UNIQUE NOT NULL,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE posts (
    id SERIAL PRIMARY KEY,
    uuid VARCHAR(50) UNIQUE NOT NULL,
    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    content TEXT NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE follows (
    id SERIAL PRIMARY KEY,
    follower_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    following_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(follower_id, following_id)
);

CREATE TABLE likes (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(user_id, post_id)
);

πŸ“ Available Scripts

Command Description
npm run dev Start API service
npm run dev:postgres Start PostgreSQL service
npm run dev:post Start post service
npm run dev:follow Start follow service
npm run dev:like Start like service
npm run build Compile TypeScript

πŸ”— Service URLs (Local Development)

Service URL
API http://localhost:3000
API Docs http://localhost:3000/api-docs
Post Service http://localhost:3001
Follow Service http://localhost:3003
Like Service http://localhost:3004
Postgres Service http://localhost:3002

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ’‘ Inspiration & Architectural Evolution

This project was originally inspired by the architectural concepts taught in a microservices course at [Platzi]. However, to challenge myself and align the system with modern enterprise standards, I completely re-architected the original baseline.

Key improvements and deviations from the original course include:

  • Language Upgrade: Migrated the entire codebase from plain JavaScript to strict TypeScript to ensure type safety, better developer experience, and maintainability.
  • Database Modernization: Replaced the traditional local MySQL setup with Neon PostgreSQL for a permanent, serverless cloud database.
  • Multi-Process Container: Implemented a shell script approach to run multiple Node.js processes within a single container, optimizing for free tier deployment.
  • Container Registry: Integrated Docker Hub for hosting container images with automated CI/CD via GitHub Actions.
  • Cloud Deployment: Migrated from local deployments to Render for production-ready web services.
  • API Gateway Pattern: Implemented the API Service as the single entry point for all client requests, handling authentication and routing.

πŸ“„ License

This project is licensed under the ISC License - see the LICENSE file for details.


πŸ‘€ Author

Yorber Rojas


πŸ™ Acknowledgments

  • Built with Express.js and TypeScript
  • Deployed on Render
  • Database hosted on Neon PostgreSQL
  • Containerized with Docker
  • Images hosted on Docker Hub

About

Cloud-native social network API built with a decoupled Microservices architecture (Node.js/TypeScript). Features JWT auth, automated CI/CD via GitHub Actions to Docker Hub, and deployed on Render.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors