NJ Municipality Lookup
Codebase

Examples

Runnable examples demonstrating how to use the NJ municipality geocoding domain in various contexts.

Examples

Runnable examples demonstrating how to use the NJ municipality geocoding domain in various contexts.

What This Directory Contains

This directory provides practical, copy-paste-ready examples showing how to integrate the geocoding domain into different applications. Each example is self-contained and can be run directly.

Why These Examples Exist

The domain layer is designed to be framework-agnostic and reusable. These examples demonstrate:

  1. How to wire up dependencies using factory functions and dependency injection
  2. Different integration patterns for various use cases (CLI, API, batch processing)
  3. Best practices for error handling, caching, and performance
  4. Extensibility through custom adapters

Directory Structure

Example Categories

1. Basic Usage (basic-usage/)

Getting started examples for common geocoding tasks.

ExampleDescriptionRun Command
simple-geocoding.tsMinimal geocoding setupbun run examples/basic-usage/simple-geocoding.ts
with-caching.tsAdding cache for performancebun run examples/basic-usage/with-caching.ts
batch-geocoding.tsProcessing multiple addressesbun run examples/basic-usage/batch-geocoding.ts

2. Custom Adapters (custom-adapter/)

Creating your own adapter implementations.

ExampleDescriptionRun Command
fake-geocoding-service.tsTesting without real API callsbun run examples/custom-adapter/fake-geocoding-service.ts
redis-cache-example.tsUsing Redis instead of in-memory cachebun run examples/custom-adapter/redis-cache-example.ts

3. Extracting the Domain (extracting-domain/)

Using the domain layer in entirely different applications.

ExampleDescriptionRun Command
cli-tool-example.tsBuilding a command-line toolbun run examples/extracting-domain/cli-tool-example.ts
express-api-example.tsBuilding an Express.js REST APIbun run examples/extracting-domain/express-api-example.ts

How to Run Examples

Prerequisites

# Install dependencies from project root
bun install

Running Individual Examples

# Simple geocoding
bun run examples/basic-usage/simple-geocoding.ts

# With caching
bun run examples/basic-usage/with-caching.ts

# Batch processing
bun run examples/basic-usage/batch-geocoding.ts

Running Example Tests

# Run tests for all examples
bun run test examples/

Key Concepts Demonstrated

Factory Functions

All services use factory functions for dependency injection:

const httpClient = createFetchClient({ timeout: 5000 });
const geocodingService = createNjGeocodingClient(httpClient, logger);
const cache = createInMemoryCache({ maxEntries: 1000 });

Port/Adapter Pattern

Domain defines interfaces (ports), adapters implement them:

// Domain port (interface)
interface GeocodingServicePort {
  geocodeAddress(address: AddressInput): Promise<GeocodingResult>;
}

// Your custom adapter
const myAdapter: GeocodingServicePort = {
  async geocodeAddress(address) {
    // Your implementation
  },
};

Error Handling

All examples demonstrate proper error handling with domain errors:

try {
  const result = await geocodingService.geocodeAddress(address);
} catch (error) {
  if (error instanceof AddressNotFoundError) {
    // Handle missing address
  } else if (error instanceof ApiTimeoutError) {
    // Handle timeout
  }
}

On this page