Skip to content

Commit

Permalink
Merge pull request #14 from VMGWARE/feature/API-Health-Check
Browse files Browse the repository at this point in the history
Add 'Utilities' section to OpenAPI documentation configuration file to categorize API endpoints for fetching information
  • Loading branch information
Vahn Gomes authored Jul 24, 2023
2 parents f82c786 + 3686d2d commit e446cf8
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 1 deletion.
61 changes: 61 additions & 0 deletions src/app/Http/Controllers/API/HealthCheckController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Vyuldashev\LaravelOpenApi\Attributes as OpenApi;
use Illuminate\Http\JsonResponse;
use PDO;

#[OpenApi\PathItem]
class HealthCheckController extends Controller
{
/**
* API Health Check
*
* @return JsonResponse
*/
#[OpenApi\Operation(tags: ['Utilities'])]
#[OpenApi\Response(factory: \App\OpenApi\Responses\Utilities\HealthCheck\ErrorResponse::class, statusCode: 503)]
#[OpenApi\Response(factory: \App\OpenApi\Responses\Utilities\HealthCheck\SuccessResponse::class, statusCode: 200)]
public function index(): JsonResponse
{
// Status
$status = 'ok';

// Dependencies
$dependencies = [
'database' => DB::connection()->getPdo() ? 'OK' : 'Error',
'storage' => is_writable(storage_path()) ? 'OK' : 'Error',
];

// Check dependencies
foreach ($dependencies as $dependency) {
if ($dependency !== 'OK') {
$status = 'error';
break;
}
}

// Response
$response = [
'status' => $status,
'code' => $status === 'healthy' ? 200 : 503,
'message' => $status === 'healthy' ? 'API v1 is up and running!' : 'API v1 is having issues.',
'data' => [
'uptime' => 'N/A', // TODO: Get uptime from 'uptime' command
'timestamp' => now()->toAtomString(),
'app_version' => config('app.version'),
'api_version' => 'v1',
'diskspace' => disk_free_space('/') / disk_total_space('/') * 100,
'latency' => round(microtime(true) - LARAVEL_START, 3),
'dependencies' => $dependencies
]
];

return response()->json($response);
}
}
39 changes: 39 additions & 0 deletions src/app/OpenApi/Responses/Utilities/HealthCheck/ErrorResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\OpenApi\Responses\Utilities\HealthCheck;

use GoldSpecDigital\ObjectOrientedOAS\Objects\MediaType;
use GoldSpecDigital\ObjectOrientedOAS\Objects\Response;
use GoldSpecDigital\ObjectOrientedOAS\Objects\Schema;
use Vyuldashev\LaravelOpenApi\Factories\ResponseFactory;
use Vyuldashev\LaravelOpenApi\Contracts\Reusable;

class ErrorResponse extends ResponseFactory implements Reusable
{
public function build(): Response
{
$response = Schema::object()->properties(
Schema::string('status')->example('error'),
Schema::string('message')->example('API v1 is having issues.'),
Schema::integer('code')->example(503),
Schema::object('data')->properties(
Schema::string('uptime')->example('3 days 2 hours'),
Schema::string('timestamp')->example('2021-01-01 00:00:00'),
Schema::string('app_version')->example('1.0.0'),
Schema::string('api_version')->example('v1'),
Schema::number('diskspace')->example(50.0),
Schema::number('latency')->example(0.123)
),
Schema::object('dependencies')->properties(
Schema::string('database')->example('Error'),
Schema::string('storage')->example('OK'),
)
);

return Response::create('GetHealthCheckError')
->description('Get API Health Check status.')
->content(
MediaType::json()->schema($response)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace App\OpenApi\Responses\Utilities\HealthCheck;

use GoldSpecDigital\ObjectOrientedOAS\Objects\MediaType;
use GoldSpecDigital\ObjectOrientedOAS\Objects\Response;
use GoldSpecDigital\ObjectOrientedOAS\Objects\Schema;
use Vyuldashev\LaravelOpenApi\Factories\ResponseFactory;
use Vyuldashev\LaravelOpenApi\Contracts\Reusable;

class SuccessResponse extends ResponseFactory implements Reusable
{
public function build(): Response
{
$response = Schema::object()->properties(
Schema::string('status')->example('ok'),
Schema::string('message')->example('API v1 is up and running!'),
Schema::integer('code')->example(200),
Schema::object('data')->properties(
Schema::string('uptime')->example('3 days 2 hours'),
Schema::string('timestamp')->example('2021-01-01 00:00:00'),
Schema::string('app_version')->example('1.0.0'),
Schema::string('api_version')->example('v1'),
Schema::number('diskspace')->example(50.0),
Schema::number('latency')->example(0.123)
),
Schema::object('dependencies')->properties(
Schema::string('database')->example('OK'),
Schema::string('storage')->example('OK'),
)
);

return Response::create('GetHealthCheckSuccess')
->description('Get API Health Check status.')
->content(
MediaType::json()->schema($response)
);
}
}
6 changes: 5 additions & 1 deletion src/config/openapi.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@
[
'name' => 'Text to Speech',
'description' => 'Endpoints for converting text to speech audio files.',
]
],
[
'name' => 'Utilities',
'description' => 'Endpoints for getting information about the API.',
],
],

'security' => [
Expand Down
3 changes: 3 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\HealthCheckController;
use App\Http\Controllers\API\AirportController;
use App\Http\Controllers\API\TextToSpeechController;
use Illuminate\Support\Facades\Route;
Expand All @@ -17,6 +18,8 @@

// API v1 Routes
Route::prefix('v1')->group(function () {
// Health check
Route::get('/health', [HealthCheckController::class, 'index'])->name('api.healthcheck');

// Airports
Route::prefix('airports')->group(function () {
Expand Down

0 comments on commit e446cf8

Please sign in to comment.