Skip to content

Commit

Permalink
Merge pull request #6 from nspalo/development
Browse files Browse the repository at this point in the history
BWA-Dev-2-Weather-App-API-Functionality
  • Loading branch information
nspalo authored Sep 6, 2023
2 parents 506a013 + af6f054 commit 3d162a0
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 1 deletion.
2 changes: 1 addition & 1 deletion docker/containers/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ FROM php:8.1-fpm-alpine
RUN apk --no-cache add zip libzip-dev \
&& docker-php-ext-configure zip \
&& docker-php-ext-install zip mysqli pdo pdo_mysql \
&& docker-php-ext-enable pdo_mysql \
&& docker-php-ext-enable pdo_mysql
2 changes: 2 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ services:
volumes:
- "${PATH_CONFIG_PHP}:/usr/local/etc/php/php.ini"
- "${PATH_PROJECT_SOURCE}:/var/www/html"
links:
- php
depends_on:
- php
entrypoint: ['composer']
Expand Down
11 changes: 11 additions & 0 deletions src/app/Enums/WeatherTypeEnum.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace App\Enums;

enum WeatherTypeEnum: string
{
case Current = 'weather';
case Forecast = 'forecast';
}
135 changes: 135 additions & 0 deletions src/app/Http/Controllers/API/WeatherApp/WeatherUpdateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php

declare(strict_types=1);

namespace App\Http\Controllers\API\WeatherApp;

use App\Enums\WeatherTypeEnum;
use App\Http\Controllers\Controller;
use Illuminate\Http\Client\Response;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Http;

class WeatherUpdateController extends Controller
{
private string $weatherApiKey;
private string $weatherApiUnit;
private string $weatherApiOutput;
private string $weatherApiUri;
private string $geoapifyApiKey;
private string $geoapifyApiUri;
private string $geoapifyApiFilter;
private string $geoapifyApiFormat;
private string $geoapifyApiLang;
private string $geoapifyApiMaxOutput;
private string $geoapifyApiType;

public function __construct()
{
$this->weatherApiKey = \config('services.api.open_weather.key');
$this->weatherApiUnit = \config('services.api.open_weather.unit');
$this->weatherApiOutput = \config('services.api.open_weather.max_output');
$this->weatherApiUri = \config('services.api.open_weather.uri');
$this->geoapifyApiKey = \config('services.api.geoapify.key');
$this->geoapifyApiUri = \config('services.api.geoapify.uri');
$this->geoapifyApiFilter = \config('services.api.geoapify.filter');
$this->geoapifyApiFormat = \config('services.api.geoapify.format');
$this->geoapifyApiLang = \config('services.api.geoapify.lang');
$this->geoapifyApiMaxOutput = \config('services.api.geoapify.max_output');
$this->geoapifyApiType = \config('services.api.geoapify.type');
}

public function __invoke(Request $request): JsonResource
{
$location = $request->get('location') ?? 'Metro Manila, Philippines';

$responseGeolocation = $this->getGeoapifyGeolocation($location);

$responseCurrentWeather = $this->getWeatherUpdate($responseGeolocation['lon'], $responseGeolocation['lat']);
$responseForecastWeather = $this->getWeatherForecast($responseGeolocation['lon'], $responseGeolocation['lat']);

return new JsonResource([
'weather' => [
'geolocation' => $responseGeolocation,
'current' => $responseCurrentWeather->json(),
'forecast' => $responseForecastWeather->json(),
],
]);
}

private function buildQueryString(array $queryParam): string
{
return implode(
'&',
array_map(
static function($key, $value){
return $key . '=' . $value;
},
array_keys($queryParam),
$queryParam
)
);
}

private function buildGeoapifyApiUrl(string $location): string
{
$queryParam = [
'text' => $location,
'type' => $this->geoapifyApiType,
'limit' => $this->geoapifyApiMaxOutput,
'lang' => $this->geoapifyApiLang,
'filter' => $this->geoapifyApiFilter,
'format' => $this->geoapifyApiFormat,
'apiKey' => $this->geoapifyApiKey,
];

$queryString = $this->buildQueryString($queryParam);

return 'https://' . $this->geoapifyApiUri . '?' . $queryString;
}

private function getGeoapifyGeolocation(string $location): array
{
$geolocationUrl = $this->buildGeoapifyApiUrl($location);
$responseGeolocation = Http::get($geolocationUrl);
$data = $responseGeolocation->json('results');

return [
'lon' => $data[0]['lon'],
'lat' => $data[0]['lat'],
];
}

private function buildWeatherApiUrl(WeatherTypeEnum $requestType, float $lon, float $lat): string
{
$queryParam = [
'lon' => $lon,
'lat' => $lat,
'units' => $this->weatherApiUnit,
'appid' => $this->weatherApiKey,
];

if ($requestType === WeatherTypeEnum::Forecast) {
$queryParam['cnt'] = $this->weatherApiOutput;
}

$queryString = $this->buildQueryString($queryParam);

return 'https://' . $this->weatherApiUri . '/' . $requestType->value . '?' . $queryString;
}

private function getWeatherUpdate(float $lon, float $lat): Response
{
$currentWeatherUrl = $this->buildWeatherApiUrl(WeatherTypeEnum::Current, $lon, $lat);

return Http::get($currentWeatherUrl);
}

private function getWeatherForecast(float $lon, float $lat): Response
{
$forecastWeatherUrl = $this->buildWeatherApiUrl(WeatherTypeEnum::Forecast, $lon, $lat);

return Http::get($forecastWeatherUrl);
}
}
17 changes: 17 additions & 0 deletions src/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,21 @@
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
],

'api' => [
'open_weather' => [
'key' => env('OPEN_WEATHER_API_KEY', ''),
'max_output' => env('OPEN_WEATHER_MAX_OUTPUT', '5'),
'unit' => env('OPEN_WEATHER_UNIT', 'metric'),
'uri' => env('OPEN_WEATHER_API_URI', ''),
],
'geoapify' => [
'filter' => env('GEOAPIFY_FILTER', 'countrycode:none'),
'format' => env('GEOAPIFY_FORMAT', 'json'),
'key' => env('GEOAPIFY_API_KEY', ''),
'lang' => env('GEOAPIFY_LANG', 'en'),
'max_output' => env('GEOAPIFY_MAX_OUTPUT', '1'),
'type' => env('GEOAPIFY_TYPE', 'city'),
'uri' => env('GEOAPIFY_API_URI', ''),
],
],
];
7 changes: 7 additions & 0 deletions src/routes/api.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use App\Http\Controllers\API\WeatherApp\WeatherUpdateController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Expand All @@ -17,3 +18,9 @@
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});

// Bizmates Ph Weather App API Routes
Route::get('/weather-update', [
'as' => 'forecast',
'uses' => WeatherUpdateController::class,
]);

0 comments on commit 3d162a0

Please sign in to comment.