A comprehensive Node.js REST API for expense splitting and friend management, built with MongoDB, JWT authentication, and robust security features.
Splitlyr API is the backend service powering the Splitlyr mobile application. It provides a complete expense-splitting platform with user management, friend networks, group functionality, and detailed expense tracking with automatic balance calculations.
- JWT-based Authentication - Secure token-based auth system
- Password Hashing - bcrypt with salt rounds for secure password storage
- Rate Limiting - Protection against brute force attacks (production)
- Input Validation - Comprehensive Joi validation schemas
- Security Headers - Helmet middleware for HTTP security
- CORS Protection - Configurable cross-origin resource sharing
- User Registration & Login - Complete authentication flow
- Profile Management - Update user information and profile images
- Password Management - Secure password change functionality
- User Search - Find users by name or email
- Account Status - Active/inactive user management
- Friend Management - Add, remove, and manage friends
- Pending Friends - Invite system for non-registered users
- Contact Integration - Support for email and phone-based invitations
- Automatic Friend Conversion - Convert pending friends when they join
- Friend Search - Search existing app users
- Group Creation - Create groups with multiple members
- Member Management - Add/remove members with role-based access
- Group Roles - Admin and member permissions
- Group Settings - Update group information and descriptions
- Member Validation - Automatic friend addition for group members
- Expense Creation - Record shared expenses with detailed splits
- Multiple Split Types - Flexible expense splitting options
- Balance Calculations - Automatic balance tracking between users
- Settlement System - Mark expenses as settled
- Group Expenses - Track expenses within groups
- Category Support - Organize expenses by categories
- Currency Support - Multi-currency expense tracking
- Health Checks - Comprehensive system health monitoring
- Database Status - MongoDB connection monitoring
- Memory Usage - System resource tracking
- Uptime Monitoring - Service availability tracking
- MVC Pattern - Clean, organized code structure
- MongoDB Integration - Mongoose ODM with advanced schemas
- Error Handling - Comprehensive error handling and logging
- Middleware Stack - Modular middleware architecture
- Docker Support - Containerized deployment ready
POST /register- Register new userPOST /login- User login
GET /profile- Get user profile (protected)PATCH /profile- Update user profile (protected)PATCH /change-password- Change user password (protected)GET /- Search users by name/email (protected)GET /balances- Get all user balances (protected)
GET /friends- Get user's friends and pending friends (protected)POST /friends- Add friends (bulk operation) (protected)DELETE /friends/:friendId- Remove friend (protected)GET /friends/:friendId/balance- Get balance with specific friend (protected)
POST /- Create new group (protected)GET /- Get user's groups (protected)GET /:id- Get specific group details (protected)PUT /:id- Update group information (protected)DELETE /:id- Delete group (protected)POST /:id/members- Add member to group (protected)DELETE /:id/members/:memberId- Remove member from group (protected)DELETE /:id/leave- Leave group (protected)
POST /- Create new expense (protected)GET /- Get user's expenses (protected)GET /:id- Get specific expense details (protected)PUT /:id- Update expense (protected)DELETE /:id- Delete expense (protected)PATCH /:id/settle- Settle expense split (protected)GET /group/:groupId- Get group expenses (protected)GET /group/:groupId/balance- Get group balance (protected)
GET /- System health check (public)
- Node.js (v16 or higher)
- MongoDB (local or cloud instance)
- npm or yarn package manager
-
Clone and navigate to services directory:
cd services -
Install dependencies:
npm install
-
Set up environment variables: Create a
.envfile in the root directory:# Database Configuration MONGO_URL=mongodb+srv://username:password@cluster.mongodb.net/Splitlyr?retryWrites=true&w=majority # JWT Configuration JWT_SECRET=your-super-secret-jwt-key-here-make-it-long-and-random JWT_EXPIRES_IN=2d # Server Configuration PORT=3000 NODE_ENV=development # Security (Production) RATE_LIMIT_WINDOW_MS=900000 RATE_LIMIT_MAX_REQUESTS=100
-
Start the server:
# Development mode (with nodemon) npm run dev # Production mode npm start
-
Verify installation: Visit
http://localhost:3000/v1/healthzto check if the server is running.
-
Build the Docker image:
docker build -t splitlyr-api . -
Run with Docker Compose:
docker-compose up -d
-
Health check:
curl http://localhost:3000/v1/healthz
POST /v1/auth/register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword123"
}
# Response
{
"success": true,
"message": "User created successfully",
"data": {
"user": {
"id": "user_id",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"isActive": true,
"createdAt": "2024-01-01T00:00:00.000Z"
},
"token": "jwt_token_here"
}
}POST /v1/auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "securepassword123"
}
# Response
{
"success": true,
"message": "Login successfully",
"data": {
"user": {
"id": "user_id",
"name": "John Doe",
"email": "john@example.com",
"role": "user",
"isActive": true,
"lastLogin": "2024-01-01T00:00:00.000Z"
},
"token": "jwt_token_here"
}
}Include the JWT token in the Authorization header:
GET /v1/users/profile
Authorization: Bearer <your-jwt-token>POST /v1/users/friends
Authorization: Bearer <token>
Content-Type: application/json
{
"friends": [
{
"name": "Jane Smith",
"email": "jane@example.com"
},
{
"name": "Bob Johnson",
"phoneNumber": "+1234567890"
}
]
}POST /v1/groups
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Weekend Trip",
"description": "Expenses for our weekend getaway",
"members": ["friend_user_id_1", "friend_user_id_2"]
}POST /v1/expenses
Authorization: Bearer <token>
Content-Type: application/json
{
"description": "Dinner at restaurant",
"amount": 120.00,
"currency": "USD",
"paidBy": "user_id",
"splitWith": [
{
"user": "friend_id_1",
"amount": 40.00
},
{
"user": "friend_id_2",
"amount": 40.00
},
{
"user": "current_user_id",
"amount": 40.00
}
],
"category": "food",
"group": "group_id_optional"
}GET /v1/users/balances
Authorization: Bearer <token>
# Response
{
"success": true,
"data": [
{
"friend": {
"_id": "friend_id",
"name": "Jane Smith",
"profileImage": "image_url"
},
"balance": 25.50,
"message": "You are owed 25.50"
}
]
}services/
├── config/
│ └── database.js # MongoDB connection configuration
├── controllers/
│ ├── authController.js # Authentication logic (register, login)
│ ├── userController.js # User management and friends
│ ├── groupController.js # Group management operations
│ ├── expenseController.js # Expense tracking and balances
│ └── healthController.js # Health monitoring endpoints
├── middleware/
│ ├── auth.js # JWT authentication middleware
│ └── errorHandler.js # Global error handling
├── models/
│ ├── User.js # User schema with friends system
│ ├── Group.js # Group schema with member management
│ ├── Expense.js # Expense schema with split calculations
│ └── PendingFriend.js # Pending friend invitations
├── routes/
│ ├── index.js # Main router configuration
│ ├── auth.js # Authentication routes
│ ├── users.js # User and friend management routes
│ ├── groups.js # Group management routes
│ ├── expenses.js # Expense tracking routes
│ └── health.js # Health check routes
├── scripts/ # Database scripts and utilities
├── utils/ # Utility functions and helpers
├── .env # Environment variables (gitignored)
├── .env.example # Environment variables template
├── docker-compose.yml # Docker composition for deployment
├── Dockerfile # Docker container configuration
├── package.json # Dependencies and npm scripts
├── server.js # Main application entry point
└── README.md # This documentation
- JWT Tokens: Secure token-based authentication with configurable expiration
- Password Hashing: bcrypt with salt rounds (12) for secure password storage
- Token Validation: Comprehensive JWT verification with user status checks
- Role-based Access: Admin and user role management
- Account Status: Active/inactive user account management
- Joi Validation: Comprehensive request validation schemas
- Mongoose Validation: Database-level data validation
- Email Validation: Advanced email format validation with edge case handling
- MongoDB Sanitization: Protection against NoSQL injection attacks
- XSS Protection: Input sanitization and output encoding
- Helmet: Security headers for HTTP protection
- CORS: Configurable cross-origin resource sharing
- Rate Limiting: Brute force attack prevention (production only)
- HPP: HTTP Parameter Pollution protection
- Compression: Response compression for performance
- Morgan: HTTP request logging for monitoring
- Global Error Handler: Centralized error processing
- Structured Logging: Comprehensive request and error logging
- Health Monitoring: System health and database status checks
- Graceful Shutdown: Proper handling of unhandled rejections and exceptions
| Variable | Description | Default | Required |
|---|---|---|---|
MONGO_URL |
MongoDB connection string | - | ✅ |
JWT_SECRET |
Secret key for JWT signing | - | ✅ |
JWT_EXPIRES_IN |
JWT token expiration time | 2d |
❌ |
PORT |
Server port | 3000 |
❌ |
NODE_ENV |
Environment mode | development |
❌ |
RATE_LIMIT_WINDOW_MS |
Rate limit window (ms) | 900000 |
❌ |
RATE_LIMIT_MAX_REQUESTS |
Max requests per window | 100 |
❌ |
- Authentication: Email, password (hashed), role, status
- Profile: Name, profile image, phone number
- Relationships: Friends array, pending friends array
- Timestamps: Created, updated, last login
- Basic Info: Name, description, creator
- Members: User references with roles (admin/member)
- Metadata: Active status, member count, timestamps
- Details: Description, amount, currency, category
- Participants: Paid by, split with (amounts and settlement status)
- Organization: Group reference, date, settlement tracking
- Calculations: Automatic balance calculations and validations
- Contact Info: Name, email, phone number
- Relationship: Added by user reference
- Auto-conversion: Converts to friend when user joins
All successful API responses follow this consistent format:
{
"success": true,
"message": "Operation completed successfully",
"data": {
// Response data object or array
}
}All error responses follow this format:
{
"success": false,
"message": "Error description",
"errors": [
{
"field": "fieldName",
"message": "Specific field error"
}
]
}| Status Code | Description | Usage |
|---|---|---|
200 |
OK | Successful GET, PUT, PATCH requests |
201 |
Created | Successful POST requests |
400 |
Bad Request | Validation errors, malformed requests |
401 |
Unauthorized | Authentication required or failed |
403 |
Forbidden | Insufficient permissions |
404 |
Not Found | Resource not found |
409 |
Conflict | Duplicate resource creation |
422 |
Unprocessable Entity | Validation errors |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server-side errors |
503 |
Service Unavailable | Database connection issues |
{
"success": false,
"message": "Validation failed",
"errors": [
{
"field": "email",
"message": "Please provide a valid email address"
},
{
"field": "password",
"message": "Password must be at least 6 characters long"
}
]
}{
"success": false,
"message": "Invalid credentials"
}{
"success": false,
"message": "User not found"
}# Install dependencies
npm install
# Start in development mode (with nodemon auto-reload)
npm run dev
# Start in production mode
npm start
# Run with Docker
docker-compose up -d
# View logs
docker-compose logs -f app-
Setup Development Environment:
# Clone repository git clone <repository-url> cd services # Install dependencies npm install # Copy environment template cp .env.example .env # Edit .env with your configuration
-
Database Setup:
- Set up MongoDB (local or cloud)
- Update
MONGO_URLin.env - The application will automatically connect on startup
-
Testing the API:
# Health check curl http://localhost:3000/v1/healthz # Register a user curl -X POST http://localhost:3000/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"name":"Test User","email":"test@example.com","password":"password123"}'
- Controllers: Handle HTTP requests and responses
- Models: Define database schemas and business logic
- Middleware: Handle cross-cutting concerns (auth, validation, errors)
- Routes: Define API endpoints and route handlers
- Utils: Utility functions and helpers
User
├── friends: [User] (many-to-many)
├── pendingFriends: [PendingFriend] (one-to-many)
└── groups: [Group] (many-to-many through members)
Group
├── members: [User] (many-to-many)
├── createdBy: User (many-to-one)
└── expenses: [Expense] (one-to-many)
Expense
├── createdBy: User (many-to-one)
├── paidBy: User (many-to-one)
├── splitWith: [User] (many-to-many with amounts)
└── group: Group (many-to-one, optional)
PendingFriend
└── addedBy: User (many-to-one)
-
Environment Setup:
# Set production environment variables NODE_ENV=production MONGO_URL=mongodb+srv://... JWT_SECRET=your-production-secret -
Docker Deployment:
# Build and run with Docker Compose docker-compose up -d # Check health curl http://your-domain.com:3000/v1/healthz
-
Security Checklist:
- Strong JWT secret (64+ characters)
- Secure MongoDB connection string
- Rate limiting enabled
- HTTPS configured (reverse proxy)
- Environment variables secured
- Database access restricted
- Health Checks:
/v1/healthzendpoint for monitoring - Logging: Comprehensive request and error logging
- Memory Monitoring: Built-in memory usage tracking
- Database Status: Connection status monitoring
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow existing code style and patterns
- Add comprehensive error handling
- Include input validation for all endpoints
- Write clear commit messages
- Test API endpoints thoroughly
- Update documentation for new features
This project is licensed under the ISC License.
API Version: v1
Node.js: v22+
MongoDB: v4.4+
Docker: Supported