WebWeather

This app uses Weather.gov and Geoapify to retrieve current temperature and forecast data from the National Weather Service.

You can see this app in action here on Heroku.

How it works

The /forecast/new page has a form with a single address input. A user enters a location and a new GeoCoderJob is enqueued. A unique, deterministic Job ID hash is also generated based upon the user's input. This Job ID is used as a key for a first level cache layer with Rails.cache. It's also used to track the user's forecast request state on the backend while the background jobs process. Using a hash for caching based upon user input means the user does not control the length of the cache keys.

If the GeoCoderJob finds a matching location with a zip code, a ForecastJob is then enqueued for the given Job ID and returned latitude and longtitude. If no match is found the Job ID in cache is set to :not_found and error is shown to the user.

ForecastJob job uses the ForecastJob to make a couple queries to Weather.gov to get the all data needed to display the current temperature as well as a 3 day forecast.

Both the GeoCoderJob and ForecastJob utilize the cache. The GeoCoderJob uses a cache key based upon the Job ID. The ForecastJob uses a cache key based upon the zip code returned by the geocoding process along with a timestamp rounded to the nearest half hour. This ensures forecast requests for the same zip code avoid extra queries to the ForecastService. The timestamp ensures we keep forecast data fresh even if cache is repeatively hit.

ForecastService

This service makes 3 API calls to Weather.gov. The first API request translates a latitude and longtitude into the the geographically closest data feed to use for the publicly available National Weather Service forecasts. This response includes 2 forecast URLs, one for a hourly forecast to get the current temperature and for a long term forecast.

Please refer to the "How do I get a forecast for a location from the API?" section of the Weather.gov docs

Running the app

Redis is required to run the app. A docker-compose.yml file has been included for convenience:

docker-compose -f docker-compose.yml up -d

Next the you can either start the Rails server or run tests:

rails s -p 3000
rails test