Skip to content

Abhishekkr21/Real-Time-Polling-Application-API

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Real-Time Polling Application API

A comprehensive backend service for a real-time polling application built with Node.js, Express, PostgreSQL, Prisma, and WebSockets.

πŸš€ Features

  • RESTful API for complete CRUD operations on Users, Polls, and Votes
  • Real-time updates using WebSockets for live poll results
  • Secure authentication with JWT tokens and bcrypt password hashing
  • Database relationships properly modeled with Prisma ORM
  • Input validation and error handling middleware
  • Rate limiting and security headers
  • Comprehensive API documentation with example requests

πŸ—οΈ Architecture

Database Schema

The application uses PostgreSQL with the following entities and relationships:

  • User: id, name, email, passwordHash, createdAt, updatedAt
  • Poll: id, question, isPublished, createdAt, updatedAt, creatorId
  • PollOption: id, text, pollId
  • Vote: id, userId, pollOptionId, createdAt

Relationships

  • One-to-Many: User β†’ Polls (A user can create many polls)
  • One-to-Many: Poll β†’ PollOptions (A poll can have multiple options)
  • Many-to-Many: User ↔ PollOptions (Through Vote entity)

πŸ“‹ Prerequisites

  • Node.js (v16 or higher)
  • PostgreSQL (v12 or higher)
  • npm or yarn package manager

πŸ› οΈ Installation

  1. Clone the repository

    git clone <repository-url>
    cd real-time-polling-api
  2. Install dependencies

    npm install
  3. Environment Setup

    cp .env.example .env

    Update the .env file with your configuration:

    DATABASE_URL="postgresql://username:password@localhost:5432/polling_app"
    JWT_SECRET="your-super-secret-jwt-key-here"
    PORT=3000
    NODE_ENV=development
    CORS_ORIGINS="http://localhost:3000,http://localhost:3001"
  4. Database Setup

    # Generate Prisma client
    npm run db:generate
    
    # Push schema to database (for development)
    npm run db:push
    
    # Or run migrations (for production)
    npm run db:migrate
  5. Start the server

    # Development mode with auto-reload
    npm run dev
    
    # Production mode
    npm start

πŸ“‘ API Endpoints

Authentication

Register User

POST /api/users/register
Content-Type: application/json

{
  "name": "John Doe",
  "email": "[email protected]",
  "password": "securepassword"
}

Login User

POST /api/users/login
Content-Type: application/json

{
  "email": "[email protected]",
  "password": "securepassword"
}

Users

Get User Profile

GET /api/users/profile
Authorization: Bearer <jwt_token>

Get All Users

GET /api/users?page=1&limit=10

Get User by ID

GET /api/users/:id

Polls

Create Poll

POST /api/polls
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "question": "What's your favorite programming language?",
  "options": ["JavaScript", "Python", "Java", "Go"],
  "isPublished": true
}

Get All Polls

GET /api/polls?page=1&limit=10&search=programming

Get User's Polls

GET /api/polls/my
Authorization: Bearer <jwt_token>

Get Poll by ID

GET /api/polls/:id

Update Poll

PUT /api/polls/:id
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "question": "Updated question",
  "isPublished": true
}

Delete Poll

DELETE /api/polls/:id
Authorization: Bearer <jwt_token>

Get Poll Results

GET /api/polls/:id/results

Votes

Cast Vote

POST /api/votes
Authorization: Bearer <jwt_token>
Content-Type: application/json

{
  "pollOptionId": "poll_option_id_here"
}

Remove Vote

DELETE /api/votes/:pollId
Authorization: Bearer <jwt_token>

Get User's Votes

GET /api/votes/my
Authorization: Bearer <jwt_token>

Get Poll Votes (Creator Only)

GET /api/votes/poll/:pollId
Authorization: Bearer <jwt_token>

πŸ”Œ WebSocket Events

Client β†’ Server Events

Join Poll Room

socket.emit('joinPoll', { pollId: 'poll_id_here' });

Leave Poll Room

socket.emit('leavePoll', { pollId: 'poll_id_here' });

Get Poll Statistics

socket.emit('getPollStats', { pollId: 'poll_id_here' });

Ping

socket.emit('ping');

Server β†’ Client Events

Poll Joined

socket.on('pollJoined', (data) => {
  console.log('Joined poll:', data.pollId);
  console.log('Current results:', data.results);
});

Vote Update (Real-time)

socket.on('voteUpdate', (results) => {
  console.log('Live poll results:', results);
  // Update UI with new vote counts and percentages
});

Poll Statistics

socket.on('pollStats', (stats) => {
  console.log('Poll statistics:', stats);
});

Error Handling

socket.on('error', (error) => {
  console.error('WebSocket error:', error.message);
});

πŸ”§ Development

Database Management

# View database in Prisma Studio
npm run db:studio

# Reset database (development only)
npx prisma db push --force-reset

# Generate Prisma client after schema changes
npm run db:generate

Project Structure

src/
β”œβ”€β”€ middleware/
β”‚   β”œβ”€β”€ auth.js          # JWT authentication middleware
β”‚   └── validation.js    # Request validation middleware
β”œβ”€β”€ routes/
β”‚   β”œβ”€β”€ users.js         # User authentication and management
β”‚   β”œβ”€β”€ polls.js         # Poll CRUD operations
β”‚   └── votes.js         # Voting functionality
β”œβ”€β”€ websocket/
β”‚   └── socketHandler.js # WebSocket event handling
└── server.js            # Main application entry point

prisma/
└── schema.prisma        # Database schema definition

πŸ”’ Security Features

  • JWT Authentication with secure token generation
  • Password Hashing using bcrypt with salt rounds
  • Rate Limiting to prevent API abuse
  • CORS Configuration for cross-origin requests
  • Input Validation using express-validator
  • SQL Injection Protection through Prisma ORM
  • Security Headers via Helmet middleware

πŸ§ͺ Testing

Manual Testing with cURL

Register and Login

# Register
curl -X POST http://localhost:3000/api/users/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Test User","email":"[email protected]","password":"password123"}'

# Login
curl -X POST http://localhost:3000/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"password123"}'

Create and Vote on Poll

# Create poll (replace TOKEN with actual JWT)
curl -X POST http://localhost:3000/api/polls \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"question":"Favorite color?","options":["Red","Blue","Green"],"isPublished":true}'

# Vote on poll (replace POLL_OPTION_ID with actual ID)
curl -X POST http://localhost:3000/api/votes \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer TOKEN" \
  -d '{"pollOptionId":"POLL_OPTION_ID"}'

WebSocket Testing

You can test WebSocket functionality using a simple HTML client:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Test</title>
    <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
</head>
<body>
    <script>
        const socket = io('http://localhost:3000', {
            auth: {
                token: 'YOUR_JWT_TOKEN_HERE'
            }
        });

        socket.on('connect', () => {
            console.log('Connected to server');
            
            // Join a poll room
            socket.emit('joinPoll', { pollId: 'POLL_ID_HERE' });
        });

        socket.on('voteUpdate', (data) => {
            console.log('Live vote update:', data);
        });

        socket.on('error', (error) => {
            console.error('Error:', error);
        });
    </script>
</body>
</html>

πŸš€ Deployment

Environment Variables for Production

NODE_ENV=production
DATABASE_URL="postgresql://user:pass@host:5432/dbname"
JWT_SECRET="your-production-jwt-secret"
PORT=3000
CORS_ORIGINS="https://yourdomain.com"

Docker Deployment (Optional)

Create a Dockerfile:

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npx prisma generate
EXPOSE 3000
CMD ["npm", "start"]

πŸ“Š Performance Considerations

  • Database Indexing: Ensure proper indexes on foreign keys and frequently queried fields
  • Connection Pooling: Configure PostgreSQL connection pooling for production
  • Rate Limiting: Adjust rate limits based on expected traffic
  • WebSocket Scaling: Consider using Redis adapter for multi-server WebSocket scaling

πŸ› Troubleshooting

Common Issues

  1. Database Connection Error

    • Verify PostgreSQL is running
    • Check DATABASE_URL format
    • Ensure database exists
  2. JWT Token Issues

    • Verify JWT_SECRET is set
    • Check token expiration
    • Ensure proper Authorization header format
  3. WebSocket Connection Issues

    • Check CORS configuration
    • Verify client is using correct URL and port
    • Check firewall settings

πŸ“ License

MIT License - see LICENSE file for details.

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

πŸ“ž Support

For issues and questions:

  • Create an issue in the repository
  • Check existing documentation
  • Review the troubleshooting section

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published