A robust, production-ready TypeScript API service for validating and standardizing US property addresses. Built with Fastify and powered by the Smarty Address Validation service, this API transforms free-form address strings into structured, validated address components.
The Address Validator API accepts unstructured address input and returns standardized address data with validation status indicators. The service is designed specifically for US addresses and provides detailed feedback on address validity, corrections made during standardization, and comprehensive error handling for edge cases.
- US Address Validation: Validates and standardizes US addresses using Smarty's industry-leading address database
- Structured Response Format: Returns consistent JSON responses with street, number, city, state, and zipcode components
- Validation Status Indicators: Clear status codes (valid, corrected, unverifiable, invalid) with detailed feedback
- Production-Ready: Includes logging, rate limiting, security headers, graceful shutdown, and comprehensive error handling
- Resilient Architecture: Circuit breaker pattern protects against external API failures with automatic recovery
- Developer-Friendly: TypeScript throughout, comprehensive test suite, and clear API documentation
Benefits: Enables easy switching between validation providers, isolates external dependencies, makes testing easier with mocked implementations
The system uses the Adapter pattern to abstract the validation provider interface, allowing seamless switching between different address validation services without changing core business logic. The ValidationProviderAdapter interface defines a consistent contract that any provider implementation must follow.
Benefits: Prevents cascading failures, provides graceful degradation during outages, automatic recovery, protects against external API instability
Implemented using the Opossum library, the circuit breaker wraps calls to the Smarty API. When the external service experiences issues, the circuit breaker fails fast and provides meaningful error responses instead of hanging requests. It automatically attempts recovery after a configured timeout period.
Benefits: Prevents API abuse, ensures fair usage, protects server resources, improves overall system stability
Built-in rate limiting using Fastify's rate-limit plugin protects the service from abuse and ensures consistent performance. Rate limits are applied per IP address with configurable windows and limits.
Benefits: Built-in retry logic, official support and updates, simplified integration, handles authentication and request formatting
The official Smarty JavaScript SDK provides robust error handling, automatic retries, and simplified authentication. This reduces the complexity of our integration code and ensures we benefit from Smarty's best practices and updates.
This project was developed using a spec-driven development approach with AI assistance, demonstrating modern development workflows that combine human expertise with AI capabilities.
1. Specification Phase with Kiro IDE + Claude Sonnet 4.0
- Generated initial
requirements.mdwith structured user stories and EARS format acceptance criteria - Created comprehensive
design.mdcovering architecture, components, data models, and testing strategy - Developed detailed
tasks.mdwith incremental implementation steps and requirement traceability - Iteratively refined specifications based on architectural patterns and best practices input
2. Implementation Phase with Claude Code
- Executed individual tasks independently, focusing on one component at a time
- Maintained consistency with the established design patterns and requirements
- Implemented comprehensive test coverage alongside feature development
- Applied TypeScript best practices and production-ready error handling
Specification Quality: AI assistance helped create comprehensive, well-structured requirements and design documents that served as reliable implementation guides throughout the project.
Pattern Implementation: AI effectively implemented established architectural patterns (Adapter, Circuit Breaker) with proper abstractions and error handling, reducing development time while maintaining code quality.
Test Coverage: AI generated thorough unit and integration tests that validate both happy path and edge case scenarios, ensuring robust code quality.
Documentation Consistency: AI maintained consistent documentation standards across code comments, API documentation, and this README, improving long-term maintainability.
The development process leveraged human expertise for:
- Architectural decision-making and pattern selection
- Requirements refinement and business logic validation
- Code review and quality assurance
- Strategic technical decisions and trade-off evaluation
While AI contributed:
- Rapid code generation following established patterns
- Comprehensive test suite creation
- Detailed documentation and error handling
- Consistent implementation of design specifications
This hybrid approach demonstrates how AI can accelerate development velocity while maintaining high code quality and architectural integrity when guided by experienced developers.
- Node.js 18+
- npm or yarn
- Smarty Address Validation API credentials (Get them here)
- Clone the repository:
git clone <repository-url>
cd address-validator- Install dependencies:
npm install- Set up environment variables:
cp .env.example .env
# Edit .env with your Smarty API credentials- Start the development server:
npm run devThe API will be available at http://localhost:3000
npm run build
npm startGET /health
Returns the service health status.
curl http://localhost:3000/healthResponse:
{
"status": "ok",
"timestamp": "2024-01-15T10:30:00.000Z",
"uptime": 3600.5,
"environment": "development"
}POST /validate-address
Validates and standardizes a US address.
Request Body:
{
"address": "1600 Amphitheatre Pkwy, Mountain View, CA"
}Example Usage:
# Valid address
curl -X POST http://localhost:3000/validate-address \
-H "Content-Type: application/json" \
-d '{"address": "1600 Amphitheatre Pkwy, Mountain View, CA"}'
# Address with typos (will be corrected)
curl -X POST http://localhost:3000/validate-address \
-H "Content-Type: application/json" \
-d '{"address": "1600 Ampitheater Parkway, Mtn View, California"}'
# Invalid address
curl -X POST http://localhost:3000/validate-address \
-H "Content-Type: application/json" \
-d '{"address": "123 Fake Street, Nowhere, XX"}'
# Partial address (missing secondary info)
curl -X POST http://localhost:3000/validate-address \
-H "Content-Type: application/json" \
-d '{"address": "350 5th Ave, New York, NY"}'Successful Response:
{
"status": "valid",
"original": "1600 Amphitheatre Pkwy, Mountain View, CA",
"validated": {
"street": "Amphitheatre Pkwy",
"number": "1600",
"city": "Mountain View",
"state": "CA",
"zipcode": "94043"
},
"corrections": [],
"metadata": {
"provider": "smarty",
"processingTime": 245,
"retryCount": 0
}
}Corrected Address Response:
{
"status": "corrected",
"original": "1600 Ampitheater Parkway, Mtn View, California",
"validated": {
"street": "Amphitheatre Pkwy",
"number": "1600",
"city": "Mountain View",
"state": "CA",
"zipcode": "94043"
},
"corrections": [
{
"field": "street",
"original": "Ampitheater Parkway",
"corrected": "Amphitheatre Pkwy"
},
{
"field": "city",
"original": "Mtn View",
"corrected": "Mountain View"
}
],
"metadata": {
"provider": "smarty",
"processingTime": 312,
"retryCount": 0
}
}valid: Address was validated successfully without changescorrected: Address was validated but required corrections (typos, abbreviations, etc.)unverifiable: Address components are valid but cannot be fully verified (e.g., missing apartment number)invalid: Address could not be validated or standardized
400 Bad Request:
{
"error": {
"code": "INVALID_REQUEST",
"message": "Address field is required and must be a non-empty string",
"timestamp": "2024-01-15T10:30:00.000Z",
"requestId": "abc123def456"
}
}429 Rate Limited:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Try again in 45 seconds.",
"timestamp": "2024-01-15T10:30:00.000Z",
"requestId": "abc123def456",
"details": {
"limit": 100,
"window": "15 minutes",
"remaining": 45000
}
}
}503 Service Unavailable:
{
"error": {
"code": "EXTERNAL_SERVICE_UNAVAILABLE",
"message": "Address validation service is temporarily unavailable",
"timestamp": "2024-01-15T10:30:00.000Z",
"requestId": "abc123def456"
}
}The application is configured through environment variables. Copy .env.example to .env and customize as needed.
| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Server port |
HOST |
localhost |
Server host (use 0.0.0.0 for production) |
NODE_ENV |
development |
Environment mode |
| Variable | Required | Default | Description |
|---|---|---|---|
SMARTY_AUTH_ID |
✅ | - | Your Smarty Auth ID |
SMARTY_AUTH_TOKEN |
✅ | - | Your Smarty Auth Token |
SMARTY_LICENSES |
us-core-cloud |
Comma-separated list of Smarty licenses | |
SMARTY_MAX_CANDIDATES |
1 |
Maximum address candidates to return | |
SMARTY_MATCH_STRATEGY |
strict |
Match strategy: strict, invalid, or enhanced |
| Variable | Default | Description |
|---|---|---|
CIRCUIT_BREAKER_TIMEOUT |
10000 |
Request timeout in milliseconds |
CIRCUIT_BREAKER_ERROR_THRESHOLD |
50 |
Error percentage to open circuit |
CIRCUIT_BREAKER_RESET_TIMEOUT |
30000 |
Time before attempting reset (ms) |
| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_MAX |
100 |
Maximum requests per window |
RATE_LIMIT_WINDOW |
15 minutes |
Rate limiting time window |
| Variable | Default | Description |
|---|---|---|
LOG_LEVEL |
info |
Log level: debug, info, warn, error |
LOG_FORMAT |
json |
Log format: json or pretty |
- Sign up at Smarty.com
- Navigate to your account dashboard
- Generate API keys for the US Address Validation API
- Add the
us-core-cloudlicense to your account - Use the Auth ID and Auth Token in your environment configuration
# Development with hot reload
npm run dev
# Build TypeScript to JavaScript
npm run build
# Start production server
npm start
# Run tests
npm test
# Run tests with coverage
npm test -- --coverage
# Run tests in watch mode
npm test -- --watchsrc/
├── config/ # Configuration management
├── errors/ # Custom error classes
├── middleware/ # Express middleware
├── providers/ # Address validation providers
├── services/ # Business logic services
├── types/ # TypeScript type definitions
└── index.ts # Application entry point
__tests__/
├── fixtures/ # Test data and mocks
├── integration/ # Integration tests
├── providers/ # Provider unit tests
├── services/ # Service unit tests
└── setup.ts # Test configuration
The project includes comprehensive unit and integration tests:
# Run all tests
npm test
# Run tests with coverage report
npm test -- --coverage
# Run specific test file
npm test -- AddressValidationService.test.ts
# Run tests in watch mode during development
npm test -- --watchSolution: Ensure you've copied .env.example to .env and added your Smarty API credentials.
Possible causes:
- Invalid Smarty API credentials
- Smarty service outage
- Network connectivity issues
- Rate limiting from Smarty
Solutions:
- Verify your Smarty credentials are correct
- Check Smarty's status page for service outages
- Ensure your server can reach external APIs
- Review your Smarty account usage limits
Solution: The API includes built-in rate limiting (100 requests per 15 minutes by default). Adjust RATE_LIMIT_MAX and RATE_LIMIT_WINDOW environment variables if needed.
Cause: Too many failures to the Smarty API have triggered the circuit breaker. Solution: Wait for the reset timeout period, or check Smarty service status. The circuit breaker will automatically attempt to close after the configured reset timeout.
Solutions:
- Monitor logs for unusual patterns
- Adjust circuit breaker timeouts if needed
- Consider scaling horizontally for high traffic
- Review rate limiting configuration
Enable debug logging for detailed request/response information:
LOG_LEVEL=debug npm run devThis will show:
- Incoming request details
- Address validation processing steps
- External API call timing
- Circuit breaker state changes
- Detailed error information
The /health endpoint provides basic service status. For production monitoring, consider:
- Setting up alerts on HTTP 5xx responses
- Monitoring the
/healthendpoint availability - Tracking response times for the validation endpoint
- Monitoring circuit breaker state changes in logs
Benefits: Consistent deployment environments, easier scaling, simplified CI/CD, environment isolation, reproducible builds
Containerizing the application would provide:
- Consistent runtime environment across development, staging, and production
- Simplified deployment process with container orchestration platforms
- Better resource isolation and management
- Easier horizontal scaling with container orchestration
- Simplified CI/CD pipeline integration
Implementation considerations:
- Multi-stage Docker build for optimized production images
- Health check integration for container orchestration
- Proper handling of environment variables and secrets
- Non-root user execution for security
Benefits: Secure API access, user-specific rate limiting, audit trails, role-based permissions
Adding authentication would enable:
- Secure API access with JWT token validation
- User-specific rate limiting and usage tracking
- Detailed audit trails for compliance requirements
- Role-based access control for different API features
- Integration with existing identity providers
Implementation considerations:
- JWT token validation middleware
- User management and role assignment
- Rate limiting per authenticated user
- Audit logging for security compliance
- Integration with OAuth2/OpenID Connect providers
- Caching Layer: Redis-based caching for frequently validated addresses
- Metrics & Monitoring: Prometheus metrics and Grafana dashboards
- Multiple Provider Support: Fallback to secondary validation providers
- Batch Processing: Support for validating multiple addresses in a single request
- Webhook Support: Async validation with callback URLs
- Geographic Data: Enhanced location data including coordinates and timezone information
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
For questions, issues, or contributions:
- Create an issue in the GitHub repository
- Review the troubleshooting section above
- Check the Smarty API documentation for provider-specific questions
Built using TypeScript, Fastify, and Smarty Address Validation