Skip to content

AcnoSaga/ticketing

Repository files navigation

Ticketing

Concert Ticket Reservation Service

A scalable, PubSub event-driven ticketing platform built with microservices architecture, leveraging Node.js, TypeScript, and React, orchestrated with Kubernetes, and featuring distributed data consistency through NATS Streaming for real-time event processing across services.

Table of Contents

  1. Project Overview
  2. Technical Stack
  3. Architecture
  4. Core Functionalities
  5. Microservices Ecosystem
  6. Development Process
  7. Kubernetes Deployment
  8. Challenges Overcome
  9. Local Development Setup

Project Overview

This project is a robust, scalable ticketing platform built on a microservices-based architecture.

It's a showcase of an advanced implementation of distributed systems concepts, along with modern web development, DevOps practices, and cloud-native technologies.

Key highlights:

  • Fully distributed microservices architecture with 5 independent services
  • Event-driven design using NATS Streaming for reliable, asynchronous inter-service communication
  • Implemented with TypeScript for type-safety and improved developer experience
  • Leverages Docker and Kubernetes for containerization and orchestration
  • Utilizes Next.js for server-side rendering, improving performance and SEO
  • Implements JWT-based authentication with custom middleware for secure, stateless authentication across services
  • Integrated Stripe for payment processing

Technical Stack

                                                                                                       

Architecture

The application follows a microservices architecture, with each service responsible for a specific business domain. This design allows for:

  • Independent development and deployment of services
  • Improved fault isolation and resilience
  • Easier scaling of individual components

Each microservice:

  • Is built with Node.js and Express
  • Uses its own MongoDB database
  • Publishes and subscribes to events via NATS Streaming
  • Is containerized using Docker
  • Is deployed to a Kubernetes cluster

Inter-service communication is primarily asynchronous, using an event-driven architecture to maintain data consistency across services.

Screenshot 2024-07-28 at 11 28 24 PM

Core Functionalities

  1. User Authentication:

    • Sign up, sign in, and sign out functionality
    • JWT-based authentication
    • Current user middleware for client-side rendering
  2. Ticket Management:

    • Create, update, and view tickets
    • Ticket locking mechanism during purchase process
  3. Order Processing:

    • Create and cancel orders
    • Implement 15-minute reservation period for tickets
  4. Expiration Service:

    • Manage time-sensitive operations
    • Automate order expiration after 15 minutes
  5. Payments:

    • Process payments using Stripe
    • Mark orders as complete upon successful payment
  6. Event-Driven Updates:

    • Real-time synchronization across services using NATS Streaming

Microservices Ecosystem

  1. Auth Service:

    • Handles user registration, login, and logout
    • Issues and validates JWT tokens
    • Exposes currentUser, signup, signin, and signout routes
  2. Tickets Service:

    • Manages ticket creation, updating, and retrieval
    • Publishes ticket:created and ticket:updated events
    • Implements optimistic concurrency control
  3. Orders Service:

    • Handles order creation and cancellation
    • Maintains order status (created, cancelled, awaiting:payment, complete)
    • Publishes order:created, order:cancelled events
  4. Expiration Service:

    • Listens for order:created events
    • Schedules and publishes expiration:complete events
    • Uses Bull.js for job queueing and scheduling
  5. Payments Service:

    • Processes payments using Stripe API
    • Updates order status upon successful payment
    • Publishes payment:created events
  6. Client Application:

    • Next.js based frontend for user interactions
    • Implements server-side rendering for improved SEO and performance
    • Uses Redux for state management

Each service is independently deployable, with its own database and API. Inter-service communication is achieved through event publishing and subscription via NATS Streaming.

Data Structure

There are 4 custom data types we use in this project.

Screenshot 2024-07-28 at 11 26 11 PM

Development Process

  1. Test-Driven Development (TDD):

    • Comprehensive unit tests for all services
    • Integration tests for critical workflows
    • Custom test setup for auth and database in each service
  2. Code Organization:

    • Consistent project structure across all services
    • Shared library for common code and events
  3. Error Handling:

    • Custom error classes (RequestValidationError, DatabaseConnectionError, NotFoundError, BadRequestError)
    • Centralized error handling middleware
  4. Typescript Configuration:

    • Strict type checking enabled
    • Consistent tsconfig across services
  5. NATS Streaming:

    • Custom abstract class for event publishing
    • Robust error handling and event acknowledgement
  6. Mongoose:

    • Custom plugins for optimistic concurrency control
    • Type definitions for all models

Kubernetes Deployment

  1. Kubernetes Resources:

    • Deployments for each microservice
    • ClusterIP services for inter-service communication
    • Ingress-NGINX for routing external traffic
  2. Config and Secrets Management:

    • Kubernetes secrets for sensitive data (JWT_KEY, STRIPE_KEY)
    • Environment variables injected into pods
  3. Local Development:

    • Skaffold for automating Kubernetes deployments
    • Hot-reloading configured for all services
  4. Digital Ocean Deployment:

    • Walkthrough of production deployment on Digital Ocean Kubernetes

Challenges Overcome

  1. Data Consistency:

    • Implemented event-driven architecture
    • Idempotent event handlers to handle duplicate events
    • Optimistic concurrency control using version numbers
  2. Distributed Transactions:

    • Saga pattern for multi-service operations
    • Compensating transactions for rollback scenarios
  3. Authentication in Microservices:

    • Stateless JWT-based auth
    • Shared auth middleware via npm package
  4. Testing Microservices:

    • In-memory MongoDB for unit tests
    • Custom test setup for auth and database mocking
  5. TypeScript Integration:

    • Consistent TypeScript configuration across services
    • Type definitions for events and shared libraries

Local Development Setup

  1. Prerequisites:

    • Node.js v16.x
    • Docker v20.x
    • Kubernetes (enabled in Docker Desktop or Minikube)
    • Skaffold v1.35.x
  2. Environment Setup:

    # Clone the repository
    git clone https://github.com/your-username/ticketing.git
    cd ticketing
    
    # Install dependencies
    npm install
    
    # Create Kubernetes secrets
    kubectl create secret generic jwt-secret --from-literal=JWT_KEY=your_jwt_key
    kubectl create secret generic stripe-secret --from-literal=STRIPE_KEY=your_stripe_key
    
    # Start the application
    skaffold dev
  3. Accessing the application:

    • The application will be available at http://ticketing.dev
    • Add 127.0.0.1 ticketing.dev to your /etc/hosts file

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published