vemcogroup/laravel-weather
Laravel Weather offers a simple, fluent interface for retrieving current weather and forecasts from multiple providers in Laravel. Configure providers, units, and caching, then add reliable weather data to controllers, views, or scheduled tasks with minimal setup.
Install — composer require vemcogroup/laravel-weather. The service provider is auto-discovered on Laravel 5.5+; on older versions register Vemcogroup\Weather\WeatherServiceProvider and the Weather facade manually.
Publish the config — php artisan vendor:publish --provider="Vemcogroup\Weather\WeatherServiceProvider". This drops config/weather.php with a default provider and a providers map (OpenWeatherMap, Weatherbit, etc.). Pick your default in the config or via a WEATHER_PROVIDER env value.
Add the API key — each provider reads its credential from the published config, which in turn reads from .env (typically OPENWEATHERMAP_KEY, WEATHERBIT_KEY, …). Sign up, drop the key in .env, and run php artisan config:clear while developing.
First call — resolve the facade and ask for current conditions with coordinates:
use Vemcogroup\Weather\Facades\Weather;
$current = Weather::current(37.9838, 23.7275); // Athens
$current->temperature; // check the returned DTO for exact property names
Where to look first — read config/weather.php (that is the whole surface area you'll tune) and then src/Weather.php / the provider classes under src/Providers. If the returned object surprises you, dd($current) once — the package normalizes provider payloads into a small set of fields, and the exact property names are only documented in code.
First real use case — a "current conditions" widget on a dashboard or location page: fetch once, cache for 5–15 minutes, render. Forecasts are the same call shape (Weather::forecast(...)) but cost more quota, so prototype with current first.
Resolve once, use everywhere. Prefer constructor injection of the underlying service over the facade in classes you unit-test; keep the facade for controllers, commands, and Blade views. If the package exposes a contract, bind it in a service provider so you can swap providers or fake it in tests.
Always cache. Weather is the canonical cacheable resource. Wrap every call:
$current = Cache::remember(
"weather:current:{$lat}:{$lon}",
now()->addMinutes(10),
fn () => Weather::current($lat, $lon)
);
Round coordinates to 2–3 decimals in the cache key so nearby users share an entry, and include the provider name in the key so a provider swap doesn't serve stale shapes.
Keep the coordinates out of controllers. Create a small WeatherService (or ForecastRepository) that takes a Location value object, owns the caching, and returns your own DTO. That insulating layer is what lets you survive provider response tweaks and lets your tests avoid the network entirely.
Use it from scheduled work, not request paths, for forecasts. A php artisan weather:warm command per region on a 15-minute schedule keeps user-facing latency near zero and gives you one place to alert on provider failures.
Multi-provider fallback. Because providers live behind a keyed config map, a cheap pattern is a try/catch chain: attempt the default provider, catch its exception, retry with the secondary, and log which one answered. Don't build this until you've actually been rate-limited once — the complexity only pays off if you have a real secondary quota.
Geocoding belongs upstream. The package speaks lat/lon. If your input is a city name, resolve it once (Laravel's built-in HTTP client against Nominatim, or a stored location table) and persist lat/lon on the user/place record. Never geocode per weather request.
Testing. The package uses Laravel's HTTP client under the hood, so Http::fake([...]) with a canned provider payload covers the integration without hitting the network. For your own feature tests, fake the package's service binding instead — that's faster and doesn't couple tests to provider JSON.
Blade integration. Fetch in the controller (or a view composer), pass a plain array/DTO to the view. Doing the API call inside the template is the fastest way to add 400ms to every page render.
php artisan config:cache will keep serving the old values. Always config:clear between tweaks; on deploy, remember the cached config was built with the deploy-time env.config/weather.php — set it once, explicitly, and store unit assumptions next to your cached values. Silently mixing °C and °F is the classic bug here.null temperature will look like a rendering bug for hours.Http::timeout() in your own wrapper.src/Providers, publishing the config, and wrapping the facade in your own service. If you find yourself wanting to patch a response shape, do it in your DTO layer, not in a fork..env are not documented in the README consistently across versions — read the published config/weather.php, it's the source of truth for which env var each provider expects.How can I help you explore Laravel packages today?