Skip to content

SplitNest is a Splitwise-like expense sharing backend system built using Go microservices, SQLite, RabbitMQ, and an NGINX API Gateway.

Notifications You must be signed in to change notification settings

Aytaditya/splitnest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

18 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SplitNest โ€“ Expense Sharing Backend (Microservices)

SplitNest is a Splitwise-like expense sharing backend system built using Go microservices, SQLite, RabbitMQ, and an NGINX API Gateway.

The project focuses on clean service boundaries, correct expense math, transaction safety, and event-driven architecture, rather than over-engineering.


๐Ÿš€ Features

  • User registration & login (JWT-based authentication)
  • Group creation and member management
  • Expense creation with equal split logic
  • Net balance calculation per group
  • Asynchronous notifications using RabbitMQ
  • Event-driven extensibility
  • API Gateway using NGINX
  • Independent database per service
  • Dockerized setup

๐Ÿงฑ Architecture Overview

Core Services

  • User Service โ€“ user registration, login, identity
  • Group Service โ€“ group creation & membership
  • Expense Service โ€“ expense tracking & balance calculation

Supporting Services

  • Notification Service โ€“ consumes events asynchronously
  • API Gateway โ€“ routes requests to services (NGINX)

๐Ÿ” Communication Pattern

  • Synchronous (HTTP)
    Used for core business logic (e.g., Expense โ†’ Group)

  • Asynchronous (RabbitMQ)
    Used for side effects like notifications


๐Ÿ“ฆ Tech Stack

  • Language: Go
  • Databases: SQLite (one per service)
  • Messaging: RabbitMQ
  • Auth: JWT
  • Gateway: NGINX
  • Containerization: Docker & Docker Compose

๐Ÿ“‚ Project Structure

.
โ”œโ”€โ”€ api-gateway
โ”‚   โ””โ”€โ”€ nginx.conf
โ”œโ”€โ”€ docker-compose.yaml
โ”œโ”€โ”€ user-service
โ”œโ”€โ”€ group-service
โ”œโ”€โ”€ expense-service
โ”œโ”€โ”€ notification-service
โ””โ”€โ”€ Makefile

Each service follows a clean internal structure:

  • cmd/ โ€“ entry point
  • internal/http โ€“ HTTP handlers
  • internal/storage โ€“ database logic
  • internal/middleware โ€“ JWT validation
  • internal/types โ€“ request/response models

๐Ÿ” Authentication

  • JWT-based authentication
  • Token passed via header:
Authorization: Bearer <JWT_TOKEN>

Each service validates JWT independently.


๐Ÿ“ก API Documentation

๐Ÿง‘ User Service (Port: 8081)

Health Check

GET /

Register User

POST /register
{
  "username": "aditya",
  "email": "[email protected]",
  "password": "secret123"
}

Login

POST /login
{
  "email": "[email protected]",
  "password": "secret123"
}

Response:

{
  "token": "<jwt-token>"
}

Find User by Username (Internal)

GET /find-user/{username}

๐Ÿ‘ฅ Group Service (Port: 8082)

Health Check

GET /

Create Group

POST /create-group

Headers:

Authorization: Bearer <JWT>
{
  "name": "Goa Trip"
}

Add Member to Group

POST /add-members/{groupId}
{
  "username": "rohan"
}

Get User Groups

GET /user-groups

Returns all groups where the user is a member or admin.


Get Group Members

GET /group-members/{groupId}

Response:

[
  { "user_id": 1 },
  { "user_id": 2 },
  { "user_id": 4 }
]

Used internally by Expense Service.


๐Ÿ’ธ Expense Service (Port: 8083)

Health Check

GET /

Add Expense

POST /add-expense/{groupId}
{
  "amount": 1500
}

Behavior:

  • Equal split among group members
  • Transaction-safe writes
  • Publishes expense.created event to RabbitMQ

Get Group Expenses

GET /get-expense/{groupId}

๐Ÿงฎ Balance Logic

For each expense:

net_balance = money_paid - money_owed
  • Positive โ†’ user gets money
  • Negative โ†’ user owes money
  • Balances always sum to 0

Balances are incrementally updated, not recomputed.


๐Ÿ”” Events (RabbitMQ)

Exchange

  • Name: events
  • Type: topic

Published Events

expense.created

{
  "event": "expense.created",
  "group_id": 3,
  "expense_id": 2,
  "paid_by": 4,
  "amount": 900
}

group.member_added

{
  "event": "group.member_added",
  "group_id": 3,
  "user_id": 4
}

Events are published after successful DB transaction commit.


๐Ÿ›  Running the Project

Prerequisites

  • Docker
  • Docker Compose

Start all services

docker compose up --build

Stop services

docker compose down

๐Ÿงช Future Enhancements (Not Implemented)

  • Analytics Service (event-driven)
  • Settlement optimization (who pays whom)
  • gRPC for internal calls
  • Idempotency keys
  • Observability & metrics

About

SplitNest is a Splitwise-like expense sharing backend system built using Go microservices, SQLite, RabbitMQ, and an NGINX API Gateway.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published