This solution demonstrates my approach to microservices architecture and API integration. While designed as a recruitment task, I've focused on clean architecture and demonstrability over production-ready features.
The following production considerations were intentionally simplified but would be essential for live deployment:
- Documentation (OpenAPI)
- Rate Limitation, API provider limits verification
- Caching for odds microservice
- Health check endpoints
- CI/CD
- Tests - unit tests would require extensive mocking of external APIs and database calls
- Better logging + eg. graylog
- Error tracker eg. Sentry
- Better error handling - for both microservices, especially in places with external API usage
- Scheduler for refetching odds from API, I'd use Bull Queues with its dashboard
- Separate each microservice to independent git repository
Odds Provider– fetches odds from an external API and stores them in a local PostgreSQL database.Sheets Publisher– publishes data to Google Sheets.API Gateway– aggregates and exposes a unified API for the frontend or other consumers.
NestJS– backend framework for all services.PostgreSQL– database for storing odds.Google Sheets API– for presenting data to users.Docker Compose– for local development and orchestration.
cd odds-provider && cp .env.example .env
cd sheets-publisher && cp .env.example .env
cd api-gateway && cp .env.example .envOdds Provider:
ODDS_API_KEY- Create an account at https://the-odds-api.com/
Sheets Publisher:
GOOGLE_CLIENT_EMAILandGOOGLE_PRIVATE_KEY- Enable Google Sheets API and Google Drive API in Google Cloud Console, generate service account credentials and extract values from the JSON file.
docker compose up -d --buildcurl --location --request POST 'localhost:4000/api/odds-sync/force-refresh-odds' \
--header 'Content-Type: application/json'curl --location --request POST 'localhost:4000/api/odds-sync' \
--header 'Content-Type: application/json' \
--data-raw '{
"emailsToInvite": ["<YOUR_EMAIL_HERE>"]
}'In response you'll receive:
{
"spreadsheetId": "exampleId",
"spreadsheetUrl": "https://docs.google.com/spreadsheets/d/exampleId/edit",
"insertedRows": 100,
"emailsWithAccess": [
// invited emails
]
}