Skip to content

Repository files navigation

Image Processing API

A scalable Node.js Express API for dynamically resizing and serving images with intelligent caching. This project demonstrates enterprise-level architecture patterns including TypeScript, comprehensive testing, linting, and image processing capabilities.

Overview

This API provides two primary use cases:

  1. Rapid Prototyping: Place resized images in your frontend with dimensions specified via URL parameters
  2. Production Image Serving: Automatically resize and cache images to reduce page load sizes and optimize bandwidth

The API intelligently caches resized images on first access, serving pre-generated versions on subsequent requests for optimal performance.

Project Structure

image-processing-api/
├── src/                          # TypeScript source code
│   ├── index.ts                 # Server entry point
│   ├── controllers/
│   │   └── imagesController.ts  # Request handlers for image API
│   ├── routes/
│   │   └── images.ts            # API routes definition
│   └── services/
│       └── imageService.ts      # Image processing utility functions
├── tests/                        # Test files (Jasmine + SuperTest)
│   ├── api.spec.ts              # API endpoint tests
│   └── imageService.spec.ts     # Image service unit tests
├── build/                        # Compiled JavaScript output
├── assets/
│   ├── full/                    # Original full-size images
│   └── thumb/                   # Cached resized thumbnails
├── package.json                 # Project dependencies and scripts
├── tsconfig.json                # TypeScript configuration
├── eslint.config.mjs            # ESLint rules configuration
└── .prettierrc                   # Prettier formatting rules

Installation & Setup

Prerequisites

  • Node.js (v18 or higher)
  • npm

Step 1: Install Dependencies

npm install

Step 2: Set Up Images

Add your original JPG images to the assets/full/ directory:

cp your-image.jpg assets/full/

Step 3: Run the Server

npm start

The server will start on http://localhost:3000

Available Scripts

Development & Testing

# Run all tests (Jasmine + SuperTest)
npm test

# Watch mode with Nodemon (auto-reload on changes)
npm run dev

# Check code formatting and quality
npm run lint

# Auto-format code to match standards
npm run format

Production

# Compile TypeScript to JavaScript
npm run build

# Start the production server
npm start

API Endpoints

Resize Image

GET /api/images?filename=<imageName>&width=<widthPx>&height=<heightPx>

Query Parameters

  • filename (required, string): Name of image without extension (e.g., encenadaport)
  • width (required, number): Target width in pixels (must be positive integer)
  • height (required, number): Target height in pixels (must be positive integer)

Success Response

  • Status: 200 OK
  • Content: JPEG image file
  • Behavior:
    • First request: Processes and caches the resized image
    • Subsequent requests: Serves cached image (much faster)

Error Responses

Status Scenario Example
400 Missing parameters ?filename=image&width=200 (missing height)
400 Invalid width/height ?filename=image&width=abc&height=200
400 Non-positive dimensions ?filename=image&width=0&height=200
404 Image not found ?filename=nonexistent&width=200&height=200

Example Requests

Download a 200x200 thumbnail

curl "http://localhost:3000/api/images?filename=encenadaport&width=200&height=200"

Resize the same image to 400x300

curl "http://localhost:3000/api/images?filename=encenadaport&width=400&height=300"

Invalid request (missing parameter)

# Returns 400 error
curl "http://localhost:3000/api/images?filename=encenadaport&width=200"

Testing

The project includes comprehensive tests using Jasmine and SuperTest:

Run All Tests

npm test

Test Coverage

  • API Endpoint Tests (tests/api.spec.ts):

    • Missing parameter validation
    • Invalid dimension validation
    • Non-existent image handling
    • Valid request with caching verification
  • Image Service Tests (tests/imageService.spec.ts):

    • Direct function testing with valid inputs
    • Error handling for missing files
    • Caching behavior verification

Test Results

6 specs, 0 failures
- Image resizing functionality: ✓
- Error handling: ✓
- Caching mechanism: ✓
- Parameter validation: ✓

Code Quality Standards

TypeScript

  • ✓ All source code (src/**/*.ts) uses TypeScript
  • ✓ Type annotations on all functions and parameters
  • ✓ No use of any type
  • ✓ Proper module imports/exports

Linting & Formatting

# Check code quality
npm run lint

# Auto-format code
npm run format

ESLint Configuration: Node.js optimized, TypeScript support Prettier: Enforces consistent code formatting

Build

# Compiles TypeScript to JavaScript
npm run build

# Output: `build/` directory with compiled `.js` files

Caching Strategy

The API implements intelligent file-based caching:

  1. Cache Location: assets/thumb/ directory
  2. Cache Naming: {filename}_{width}_{height}.jpg
  3. First Request: Image is processed and saved to cache
  4. Subsequent Requests: Pre-cached version is served immediately
  5. Performance: ~50-100ms for cached images vs ~500-1000ms for processing

Example Cache

assets/thumb/
├── encenadaport_200_200.jpg      # 200x200 cache
├── encenadaport_400_300.jpg      # 400x300 cache
└── seagull_150_150.jpg           # Different image cache

Error Handling

The API provides clear error messages for all failure scenarios:

// Missing parameters
GET /api/images400: "Missing filename, width, or height"

// Invalid dimensions
GET /api/images?filename=img&width=abc&height=200
 400: "Width and height must be positive numbers"

// Image not found
GET /api/images?filename=nonexistent&width=200&height=200
 404: "Image not found"

Architecture & Scalability

Design Patterns

  • Separation of Concerns: Routes, Controllers, Services
  • Async/Await: Consistent asynchronous handling
  • Error Middleware: Centralized error handling
  • Module Pattern: Reusable, testable functions

Performance Optimizations

  • File-based caching for instant retrieval
  • Sharp library for efficient image processing
  • ESM modules for better tree-shaking
  • Minimal dependencies (~4 production packages)

Scalability Features

  • Stateless server design (horizontal scaling ready)
  • Service abstraction layer for database/cache integration
  • Middleware architecture for feature additions
  • Environment-agnostic configuration

Future Enhancements

  • Multiple image format support (PNG, WebP, AVIF)
  • Redis caching for distributed systems
  • Image compression optimization options
  • CDN integration
  • Admin dashboard for cache management
  • S3/Cloud storage backend

Dependencies

Production

  • express (^5.2.1): Web server framework
  • sharp (^0.34.5): High-performance image processing

Development

  • typescript (^5.9.3): Type safety
  • ts-node (^10.9.2): TypeScript execution
  • jasmine (^6.1.0): Testing framework
  • supertest (^7.2.2): HTTP assertion library
  • eslint (^9.39.4): Code linting
  • prettier (^3.8.1): Code formatting
  • nodemon (^3.1.14): Development auto-reload

Environment Variables

Currently, the API uses hardcoded defaults. For production, consider adding:

NODE_ENV=production    # Server environment
PORT=3000              # Server port
LOG_LEVEL=info         # Logging level
CACHE_DIR=./assets/thumb  # Cache directory
UPLOAD_DIR=./assets/full   # Upload directory

Troubleshooting

Issue: npm start fails with "cannot find module"

Solution: Run npm run build first to compile TypeScript

Issue: Images not resizing

Solution: Ensure image files are in assets/full/ and are valid JPGs

Issue: Linting errors

Solution: Run npm run format to auto-fix formatting issues

Issue: Tests fail

Solution:

  1. Delete assets/thumb/ cache: rm -rf assets/thumb/*
  2. Re-run: npm test

Running the Complete Workflow

# 1. Install
npm install

# 2. Add test images
cp your-image.jpg assets/full/encenadaport.jpg

# 3. Check code quality
npm run lint
npm run format

# 4. Run tests
npm test

# 5. Build for production
npm run build

# 6. Start server
npm start

# 7. Test endpoint
curl "http://localhost:3000/api/images?filename=encenadaport&width=200&height=200"

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages