A robust and secure API built with Node.js, Express, and TypeScript that integrates weather and cryptocurrency data.
Watch the YouTube video for a detailed walkthrough of the project.
This is a technical assignment for the role Senior Backend Engineer at Spinada.
There is no need to implement POST /v1/data endpoint.
-
Authentication & Authorization
- JWT-based authentication
- Role-based access control (User/Admin)
- Secure password hashing with bcrypt
- Login attempt delay for enhanced security
-
API Features
- Weather data integration
- Cryptocurrency price tracking
- Combined data endpoint with caching
- Rate limiting for API protection
-
Developer Experience
- OpenAPI/Swagger documentation
- TypeScript for type safety
- ESLint + Prettier configuration
- Husky for pre-commit hooks
- Comprehensive test suite
- API versioning (v1)
- Centralized logging
-
Production Ready
- Graceful shutdown handling
- Error handling middleware
- Winston logger integration
- Consistent API responses
- JWT issue time validation
- Uncaught error handling
-
Rate Limiting
- Prevents brute force attacks
- Configurable limits per endpoint
- Progressive delays for failed login attempts
-
JWT Security
- Token expiration
- Issue time validation
- Secure token storage practices
-
Data Protection
- Password hashing with bcrypt
- Input validation and sanitization
- SQL injection protection
-
Authentication Enhancements
- Implement refresh token endpoint
- Add OAuth 2.0 support
- Implement 2FA
-
Performance Optimizations
- Implement Redis for:
- Rate limiting store
- Cache storage
- Implement Redis for:
-
Architecture Improvements
- Implement pagination for
/v1/usersendpoint - Implement dependency injection
- Implement pagination for
-
Developer Experience
- Implement CI/CD pipeline
- Add Docker support
- Add Kubernetes configurations
-
Monitoring & Logging
- Add performance monitoring
- Implement error tracking
-
Security Enhancements
- Add API key management
- Implement IP whitelisting
- Implement CORS properly
- Local Development:
http://localhost:3000/v1 - Production:
https://spinada.tural.pro/v1
POST /v1/auth/register
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword"
}POST /v1/auth/login
Content-Type: application/json
{
"email": "john@example.com",
"password": "securepassword"
}GET /v1/data?city=London¤cy=BTC&refresh=false
Authorization: Bearer <your_token>Query Parameters:
city: City name for weather data (required)currency: Cryptocurrency symbol (required)refresh: Force cache refresh (optional, default: false)
- Node.js (v18 or higher)
- npm or yarn
- SQLite (included)
- Clone the repository:
git clone https://github.com/turalAsgar/spinada-task.git
cd spinada-task- Install dependencies:
npm install- Create a .env file(or copy .env.example):
PORT=your_port_number
DATABASE_PATH=your_sqlite_database_path
JWT_SECRET=your_jwt_secret
OPENWEATHER_API_KEY=your_openweather_api_key
COINGECKO_API_KEY=your_coingecko_api_key
- Seed the database:
npm run seed- Start the development server:
npm run devnpm run dev- Start development server with hot reloadnpm run build- Build the TypeScript projectnpm run test- Run testsnpm run test:watch- Run tests in watch modenpm run test:coverage- Generate test coverage reportnpm run lint- Run ESLintnpm run lint:fix- Fix ESLint issuesnpm run generate:types- Generate TypeScript types from OpenAPI specnpm start- Start the production server
All API responses follow a consistent format:
{
"success": true,
"data": {
// Response data here
},
"error": null
}Error responses:
{
"success": false,
"data": null,
"error": {
"code": "ERROR_CODE",
"message": "Human readable message",
"details": {}
}
}A Postman collection is included in the Spinada.postman_collection.json file. You can import this collection into Postman to test the API endpoints easily.