Building a Weather WebApp with Laravel and HERE Weather API

Roberto Butti
5 min readNov 3, 2018

For a Laravel 5.7 side project I needed to show some information about local weather. I created this post just to share my experience playing with Laravel and weather APIs.

I wrote an updated post with Laravel 7 and new Destination Weather API. https://medium.com/@robertodev/building-a-weather-forecasts-cli-app-with-laravel7-faad8366b05b

HERE Weather API

HERE Developer (https://developer.here.com) is a magic place where to find a bunch of APIs related to geolocation. You can find tools and APIs to build maps, to convert address to geo coordinates, routing infos, places, traffic infos, weather foreasting, etc.

If you are interested on it, the best place to start is : https://developer.here.com/documentation

In one of my side project I needed some forecasting about weather. I know there is a lot of services that provides information about weather. I tried to use this HERE service.

The weather API in HERE developer ecosystem is named Destination Weather API .

You can create an HERE account for free and start to use the APIs with a “Freemium Plan”

Once you created an account, you can create a new project and obtain APP_ID and APP_CODE. These two parameters are useful for calling HERE APIs.

Create a new Laravel project

The first step is to create a new Laravel project. Laravel is an amazing and very productive framework. You have a lot of tools/libraries/commands that make your life easier.

The requirements are listed in this page https://laravel.com/docs/5.7#installation

I suggest you to install the “laravel” command that helps you on some tasks for example for creating a new project.

composer global require laravel/installer

Once you have installed “laravel” command you can create your project:

laravel new weather

enter in the new directory:

cd weather

and then launch the internal web server:

php artisan serve

If you open your browser and go on the URL: http://127.0.0.1:8000 you will see the default welcome page.

Installing Guzzle (for client HTTP API)

You will call an API via HTTP, so you need a client to manage the HTTP protocol. My suggestion for this small project is to use Guzzle:

composer require guzzlehttp/guzzle

The user story

As user I can access to the hourly forecast page ( / path), so that I can see a list of an hour-by-hour seven day weather forecast.

Todo list

The things the we need to do are:

  • take APP_ID and APP_CODE and put it into the .env file;
  • create a route that calls a new method in a new controller;
  • create a new controller with a method;
  • create the view (blade template);
  • implement API’s call with the right parameters;
  • implement the view;
  • testing the execution watching also outside your window.

APP_ID , APP_CODE and config params

Once you created an HERE account, a project you can obtain APP_ID and APP_CODE from the HERE developer portal.

I suggest you to append to the end these 2 keys on your Laravel .env file like this:

HERE_APP_ID="yourappid"
HERE_APP_CODE="yourappcode"
HERE_LAT_DEFAULT=41.894392700114
HERE_LNG_DEFAULT=12.483014757919278

I suggest you to create also a here.php file in the /config/ directory. This file will be loaded automatically by the framework. As you can see , I added also 2 keys for the default latitude and longitude. This is useful when we will call the APIs for the local weather.

The content of config/here.php:

<?php
return
[
'app_id' => env('HERE_APP_ID', "NOAPPID"),
'app_code' => env('HERE_APP_CODE', "NOAPPCODE"),
'lat_default' => env('HERE_LAT_DEFAULT', 0),
'lng_default' => env('HERE_LNG_DEFAULT', 0)
];

In this way you can access to the value to these parameters in your code (controller, view etc).

In your code (in the controller for example) you can access to them via the config() helper function.

$app_id = config("here.app_id");
$app_code = config("here.app_code");

You can see that the file name (here) in the config directory works like a namespace used in the config() helper.

Create the route

In the routes directory you can find web.php file where you can configure your routing configuration. Add this line:

Route::get('/', 'HomeController@index');

This line allow to Laravel to load index method in HomeController when there is a request on / path.

Create the controller

In the app/Http/Controllers directory, create a new file named HomeController.php:

<?php

namespace
App\Http\Controllers;


use App\Http\Controllers\Controller;


class HomeController extends Controller
{
public function index()
{
$forecast = [];
return
view('forecastview', ["forecast" => $forecast]);
}
}

Create the view

In the controller you return a view named forecastview , passing a parameter named forecast.

So you need to create a new blade file resources/views/forecastview.blade.php

Implement logic

What you need is to call Weather APIs in the controller pass the response to the view. To do that you need to:

  • manage caching to avoid to call the APIs every time that the controller is called;
  • perform some check on the API response, for example check the HTTP status code (equal to 200);
  • take the response (a string) and transform it into a JSON object (json_decode).

Your method index in the controller:

public function index()
{
$minutes = 60;
$forecast = Cache::remember('forecast', $minutes, function () {
Log::info("Not from cache");
$app_id = config("here.app_id");
$app_code = config("here.app_code");
$lat = config("here.lat_default");
$lng = config("here.lng_default");
$url = "https://weather.api.here.com/weather/1.0/report.json?product=forecast_hourly&latitude=${lat}&longitude=${lng}&oneobservation=true&language=it&app_id=${app_id}&app_code=${app_code}";
Log::info($url);
$client = new \GuzzleHttp\Client();
$res = $client->get($url);
if ($res->getStatusCode() == 200) {
$j = $res->getBody();
$obj = json_decode($j);
$forecast = $obj->hourlyForecasts->forecastLocation;
}
return $forecast;
});
return view('forecastview', ["forecast" => $forecast]);
}

The important thing is that we are composing the url in this way:

  • the base url is https://weather.api.here.com/weather/1.0/report.json
  • parameter product: identify that we need a forecast by hours (forecast_hourly)
  • latitude and longitude are taken by the .env file
  • language is italian (language=it). Yes you have the strings and sentences translated by the API;
  • we need only 1 location (oneobservation=true)
  • metric=true indicates that you want values in metric format ( °C for temperature and km/h for the wind speed)
  • app_id and app_code (read from .env file).

For the view, we have form the JSON response:

$forecast = $obj->hourlyForecasts->forecastLocation;

The view (blade template)

In the view we have the forecast object:

<div class="links">
{{ $forecast->city }} - {{ $forecast->state }} - {{ $forecast->country }}
<br>
{{ $forecast->latitude }},{{ $forecast->longitude }}
<br>
@if (count($forecast->forecast))
<table class="table">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Weather</th>
<th scope="col">Hour</th>
<th scope="col">Temperature</th>
</tr>
</thead>
<tbody>
@foreach (array_slice($forecast->forecast,0,24) as $f)
<tr>
<th scope="row">
<img width=24 src="{{ $f->iconLink }}">
</th>
<td>{{ $f->description }}</td>
<td>{{ Carbon\Carbon::createFromFormat("HmdY", $f->localTime) }}</td>
<td> {{ $f->temperature }}&deg;</td>
</tr>

@endforeach
</tbody>
</table>
@else
<li>Sorry my dear friend, no forecast here.</li>
@endif

</div>

For each next hours you have a lot of information. We show only:

  • iconLink: the url of the weather icon (you can show it in a img src);
  • description: the weather translated in the right language (language parameter);
  • temperature: the temperature in Celsius (if you setted metric=true) or Fahrenheit (if you setted metric=false).

If you need a more detailed documentation:

Please feedback

That’s all for now. I will appreciate if you have any kind of feedback!!!

--

--

Roberto Butti

I’m technophile. Vuejs and Laravel enthusiast! #vuejs #laravel. I love #coding