How TREK Fetches 16-Day Forecasts from the Open-Meteo API

The TREK backend retrieves 16-day weather forecasts by validating date offsets against a ±16-day window, querying the Open-Meteo forecast endpoint with specific latitude and longitude parameters, and transforming numeric WMO weather codes into localized descriptions, with results cached for one hour.

The TREK repository (mauriceboe/TREK) implements a robust weather aggregation layer in server/src/services/weatherService.ts that interfaces with the Open-Meteo API to deliver multi-day forecasts without requiring API keys. This service handles the entire lifecycle of forecast retrieval—from date validation and URL construction to response caching and error handling—enabling reliable 16-day forecasts for any geographic coordinates.

How the Weather Service Retrieves 16-Day Forecasts

The core logic resides in the private _getWeatherImpl method within weatherService.ts, which orchestrates the fetch process through seven distinct steps when a user requests future weather data.

Validating the 16-Day Forecast Window

Before initiating network requests, the service calculates the day offset (diffDays) between the requested date and the current date. According to the source code at lines 66-70, the service only proceeds with the forecast branch when the offset falls within the supported range of -1 to +16 days. Requests outside this window trigger alternative logic for historical archives or climate data.

Constructing the Open-Meteo API Request

For valid forecast requests, the service constructs a parameterized URL targeting the Open-Meteo forecast endpoint. The implementation explicitly sets forecast_days=16 to maximize the available prediction window, while requesting specific daily variables including maximum and minimum temperatures and weather codes.

const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}`
            + `&daily=temperature_2m_max,temperature_2m_min,weathercode`
            + `&timezone=auto&forecast_days=16`;

This construction appears in lines 66-70 of weatherService.ts, ensuring the API returns the full 16-day dataset from which the service can extract any specific day within the range.

Fetching Data and Error Handling

The service executes a standard fetch(url) call and implements strict validation logic at lines 71-74. If the HTTP status is not OK or the JSON payload contains an error flag, the service throws an ApiError with descriptive messaging, preventing malformed data from propagating through the application.

Selecting the Target Day Index

Once the API returns the 16-day dataset, the service locates the specific requested date by comparing the ISO date string (dateStr) against the daily.time array in the response. Lines 76-78 demonstrate how the code retrieves the index (idx) of the matching day, which then serves as the accessor for temperature and weather code arrays.

Mapping WMO Weather Codes to Descriptions

Open-Meteo returns numeric WMO weather codes (e.g., 0 for Clear, 61 for Rain) that require translation. The service utilizes WMO_MAP for primary condition mapping and language-specific dictionaries (WMO_DESCRIPTION_EN or WMO_DESCRIPTION_DE) to generate human-readable descriptions. This transformation occurs between lines 58-83, converting abstract codes into localized weather summaries.

Assembling the WeatherResult Object

The final assembly stage (lines 84-92) constructs a WeatherResult object containing:

  • Average, maximum, and minimum temperatures
  • Main weather condition and localized description
  • A type flag set to 'forecast' to distinguish from historical data

Caching Forecast Data for Performance

To minimize redundant API calls, the service implements an in-memory cache (weatherCache) with a time-to-live of one hour (TTL_FORECAST_MS). As shown in lines 25-33, subsequent requests for identical latitude, longitude, and date combinations return cached results immediately, bypassing network latency and respecting Open-Meteo's rate limits.

Practical Implementation Examples

Fetching a 6-Day Forecast

The public getWeather function exposes this functionality to the rest of the application. Here is how to retrieve a forecast for a specific date six days in the future:

import { getWeather } from './server/src/services/weatherService';

// Paris coordinates: 48.8566 N, 2.3522 E
const lat = '48.8566';
const lng = '2.3522';

// Calculate date six days from now
const sixDaysLater = new Date(Date.now() + 6 * 24 * 60 * 60 * 1000)
                       .toISOString()
                       .split('T')[0]; // "YYYY-MM-DD"

const forecast = await getWeather(lat, lng, sixDaysLater, 'en');

console.log(forecast);
// Output:
// {
//   temp: 22,
//   temp_max: 25,
//   temp_min: 18,
//   main: 'Rain',
//   description: 'Light rain',
//   type: 'forecast'
// }

Retrieving Detailed Hourly Data

For applications requiring granular precipitation, wind, or humidity data, the getDetailedWeather function provides access to hourly arrays:

import { getDetailedWeather } from './server/src/services/weatherService';

const result = await getDetailedWeather('48.8566', '2.3522', sixDaysLater, 'en');
console.log(result.hourly?.slice(0, 3)); // First three hourly entries

NestJS Integration Architecture

While weatherService.ts contains the core logic, the application exposes these capabilities through server/src/nest/weather/weather.service.ts, a NestJS wrapper service that forwards controller requests to the implementation layer. This separation allows the weather logic to remain framework-agnostic while integrating with TREK's NestJS API layer.

Summary

  • Date validation: The service checks if the requested date falls within the ±16-day forecast window before querying the API.
  • API construction: Requests target api.open-meteo.com/v1/forecast with forecast_days=16 and specific daily variable parameters.
  • Error handling: Invalid HTTP responses or API error flags trigger ApiError exceptions with descriptive messages.
  • Data mapping: Numeric WMO weather codes translate to localized descriptions using WMO_MAP and language-specific dictionaries.
  • Caching strategy: Results cache for one hour (TTL_FORECAST_MS) to reduce latency and API load.
  • Entry points: Use getWeather() for daily summaries or getDetailedWeather() for hourly granularity.

Frequently Asked Questions

How does TREK handle dates beyond the 16-day forecast limit?

When the calculated day offset exceeds +16 days or predates yesterday (-1), the service bypasses the forecast endpoint and routes the request to historical archive or climate data endpoints, ensuring the application always returns valid weather information regardless of the date range.

What weather variables does the Open-Meteo request include?

The constructed URL explicitly requests temperature_2m_max, temperature_2m_min, and weathercode from the daily dataset, providing sufficient data to calculate average temperatures and determine weather conditions for each day in the forecast period.

Is the weather data cached per location or globally?

The service maintains an in-memory weatherCache keyed by latitude, longitude, and date string, meaning each unique location-date combination caches independently with a one-hour TTL (TTL_FORECAST_MS), optimizing for repeated queries to popular destinations.

Does the service require an API key for Open-Meteo?

No authentication is required. The TREK weather service leverages Open-Meteo's free public endpoint, making the forecast_days=16 parameter accessible without key management or rate-limiting concerns beyond the service's internal caching layer.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →