Socket
Book a DemoInstallSign in
Socket

github.com/rodruizronald/flight-price-api

Package Overview
Dependencies
Alerts
File Explorer
Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

github.com/rodruizronald/flight-price-api

v0.0.0-20250514123348-2b62077c0e12
Source
Go
Version published
Created
Source

Flight Price API

Project Overview

Flight Price API is a high-performance microservice built in Go that aggregates flight pricing data from multiple instances of the same provider, Google Flights.

I didn't have access to paid versions of private airline APIs or a paid RapidAPI subscription. I consider the main challenge of this project to be designing a system that efficiently handles multiple concurrent calls in the background.

Therefore, I implemented only one provider (Google Flights) and ran three instances of it, enabling multiple concurrent API calls—although the data returned is the same across instances.

Finding and accessing the necessary data was time-consuming, and I don't believe that was the primary purpose of the project. As feedback for Jobsity, it might be helpful to provide endpoints with pre-loaded data for these types of challenges, allowing candidates to focus on development rather than data acquisition.

The service implements concurrent API requests to ensure quick response times and provides structured comparison data including cheapest and fastest flight options.

Key Features

  • Multi-provider Integration: Fetches flight data from multiple sources concurrently
  • Price Comparison: Identifies the cheapest and fastest flights across all providers
  • Secure API: JWT authentication for all API endpoints
  • Concurrent Processing: Uses Go's goroutines and channels for parallel requests
  • Docker Support: Containerized deployment with optimized Docker configuration
  • Web Interface: Simple frontend for searching and comparing flights

Architecture & Design

High-level Architecture

alt text

Component Breakdown

  • API Layer:

    • Handles HTTP requests and responses using Gin framework
    • Implements authentication middleware for JWT validation
    • Routes requests to appropriate handlers
  • Service Layer:

    • Manages business logic for flight searches
    • Coordinates concurrent requests to multiple providers
    • Aggregates and processes results from all providers
  • Provider Layer:

    • Abstracts external API interactions behind a common interface
    • Handles mapping between external API responses and internal models
    • Implements provider-specific error handling
  • Auth System:

    • JWT-based authentication for API security
    • Token generation and validation

Concurrent Request Model

The service uses Go's concurrency primitives to fetch flight data from multiple providers simultaneously:

  • A search request triggers concurrent goroutines for each provider
  • Each goroutine makes an API request to its assigned provider
  • Results are collected through a channel with proper timeout handling
  • Data from all providers is aggregated, with partial results returned if some providers fail
// Launch a goroutine for each provider
for _, provider := range s.providers {
    p := flightProvider{
        FlightProvider: provider,
        resultCh:       resultCh,
    }
    go p.searchFlights(ctx, req, s.searchTimeout)
}

// Collect results from all providers
for remainingProviders > 0 {
    select {
    case <-ctx.Done():
        return nil, ctx.Err()
    case <-timer.C:
        // Handle timeout
    case result := <-resultCh:
        // Process result
    }
}

Data Flow

  • Client submits search parameters (origin, destination, date)
  • Request is authenticated via JWT middleware
  • Flight service dispatches concurrent requests to all providers
  • Results are collected, processed, and compared
  • Structured response with cheapest/fastest options is returned to client

API Endpoints

Authentication

POST /login

Authenticates a user and returns a JWT token.

Request:

{
  "username": "username",
  "password": "password"
}

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

User Information

GET /api/user

Returns information about the authenticated user.

Headers:

Authorization: Bearer <token>

Response:

{
  "username": "username"
}

GET /api/flights/search?origin=XXX&destination=YYY&date=YYYY-MM-DD

Searches for flights matching the specified criteria.

Headers:

Authorization: Bearer <token>

Parameters:

  • origin: Origin airport code (e.g., LAX, AUS)
  • destination: Destination airport code (e.g., JFK, ORD)
  • date: Flight date in YYYY-MM-DD format

Response:

{
  "count": 3,
  "flights": [
    {
      "cheapest": {
        "Airline": "Delta Air Lines",
        "FlightNumber": "DL1234",
        "Origin": "LAX",
        "Destination": "JFK",
        "DepartureTime": "2025-03-19T06:00:00Z",
        "ArrivalTime": "2025-03-19T14:15:00Z",
        "Duration": 29700000000000,
        "Price": 299.99,
        "Provider": "Google Flights 1",
        "Stops": 0
      },
      "fastest": {
        "Airline": "American Airlines",
        "FlightNumber": "AA789",
        "Origin": "LAX",
        "Destination": "JFK",
        "DepartureTime": "2025-03-19T08:30:00Z",
        "ArrivalTime": "2025-03-19T16:30:00Z",
        "Duration": 28800000000000,
        "Price": 349.99,
        "Provider": "Google Flights 1",
        "Stops": 0
      }
    },
    // Results from other providers...
  ]
}

Authentication & Security

JWT Implementation

The service uses JSON Web Tokens (JWT) for authentication:

  • Token Generation:

    • Generated upon successful login
    • Contains user identifier in claims
    • Configurable expiration time (default: 24 hours)
  • Token Validation:

    • All API requests must include a valid token in the Authorization header
    • Auth middleware extracts and validates tokens before processing requests
    • Invalid or expired tokens result in 401 Unauthorized responses
  • Security Best Practices:

    • Token secret configured via environment variables
    • Non-sensitive user info stored in token claims
    • Token expiration enforced to limit exposure

Code Example: JWT Validation

// Extract the token from Authorization header
authHeader := c.GetHeader("Authorization")
parts := strings.Split(authHeader, " ")
tokenString := parts[1]

// Validate the token
claims, err := validator.Validate(secretKey, tokenString)
if err != nil {
    c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid or expired token"})
    c.Abort()
    return
}

// Set userID in context for handlers
c.Set("userID", claims.UserID)

Parallel Processing

Concurrent API Requests

The service implements a pattern for making concurrent API requests to multiple flight providers:

  • Each provider search runs in its own goroutine
  • Results and errors are communicated through a channel
  • A timeout mechanism ensures the service remains responsive
  • The main goroutine collects and aggregates results

Error Handling

The service is designed to gracefully handle provider failures:

  • If all providers fail, a comprehensive error is returned
  • If some providers fail but others succeed, available results are returned with errors logged
  • If a global timeout occurs, partial results are returned when available

Aggregation Logic

Flight data from all providers is processed to identify:

  • The cheapest flight across all providers
  • The fastest flight across all providers
  • Provider-specific cheapest and fastest flights

Testing

Unit Tests

The codebase includes comprehensive unit tests for key components:

  • Handler Tests: Verify API endpoint behavior
  • Service Tests: Ensure business logic correctly processes flight data
  • Provider Tests: Mock external API interactions to validate mapping logic

HTTPS/TLS Configuration for Production

Direct TLS in the Go application, modify the server startup code:

// In main.go
import "crypto/tls"

// Add TLS configuration
func main() {
    // ... existing setup code ...
    
    // For production, use environment variables for certificate paths
    certFile := os.Getenv("TLS_CERT_FILE")
    keyFile := os.Getenv("TLS_KEY_FILE")
    
    // Use the default Gin router
    if certFile != "" && keyFile != "" {
        log.Infof("Starting server with TLS on port %s", cfg.Server.Port)
        r.RunTLS(":"+cfg.Server.Port, certFile, keyFile)
    } else {
        log.Infof("Starting server without TLS on port %s", cfg.Server.Port)
        r.Run(":"+cfg.Server.Port)
    }
}

Certificate Management

  • Development: For local development, use self-signed certificates

    openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
      -keyout ./certs/server.key -out ./certs/server.crt
    
  • Production:

    • With Nginx: Use Certbot
    • With Traefik: Built-in ACME support
    • Standalone: Use certbot in standalone mode to generate certificates

Security Recommendations

  • Enforce TLS 1.2+: Disable older TLS/SSL protocols
  • Implement HSTS: Add Strict-Transport-Security header
  • Configure Strong Ciphers: Use modern, secure cipher suites
  • Certificate Rotation: Set up automated certificate renewal
  • Content Security Policy: Add CSP headers for the web interface

Running the Application

Docker Setup

Build and run the application using Docker:

# Build the Docker image
make build

# Start the container
make start

# View logs
make logs

# Stop the container
make stop

Environment Variables

Configure the application through environment variables in the .env file:

VariableDescriptionDefault
PORTServer port8080
JWT_SECRETSecret key for JWT signingRequired
JWT_EXPIRES_INToken expiration in hours24
USERNAMEDefault usernamejobsity
PASSWORDDefault password123456
RAPID_API_KEYAPI key for RapidAPIRequired
LOGGER_LOG_LEVELLog level (debug, info, warn, error)debug

Example API Requests

Set your RAPID_API_KEY in the .env file before trying the examples otherwise the flight search request will fail.

Login

curl -X POST http://localhost:8080/login \
  -H "Content-Type: application/json" \
  -d '{"username":"jobsity","password":"123456"}'

Search Flights

curl -X GET "http://localhost:8080/api/flights/search?origin=LAX&destination=JFK&date=2025-03-19" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Web Interface

The application includes a simple web interface for searching flights:

  • Navigate to http://localhost:8080 in your browser
  • Log in with the configured credentials
  • Use the search form to find flights
  • View results including cheapest and fastest options

Troubleshooting

Common issues and solutions:

  • API Key Error: Ensure your RAPID_API_KEY is valid and has access to the Google Flights API
  • Authentication Failed: Verify username/password match the environment variables
  • No Flight Results: Check that the origin/destination pair is supported (currently LAX→JFK and AUS→ORD)

FAQs

Package last updated on 14 May 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

About

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.

  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc

U.S. Patent No. 12,346,443 & 12,314,394. Other pending.