Skip to content

Commit 0853bc0

Browse files
committed
Looking at how we respond as an api
1 parent 3bd035c commit 0853bc0

File tree

11 files changed

+202
-29
lines changed

11 files changed

+202
-29
lines changed

app/Enum/Error.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Enum;
6+
7+
enum Error: string
8+
{
9+
case AUTH_001 = 'https://docs.api.com/errors/auth_001';
10+
case AUTH_002 = 'https://docs.api.com/errors/auth_002';
11+
case AUTH_003 = 'https://docs.api.com/errors/auth_003';
12+
case AUTH_004 = 'https://docs.api.com/errors/auth_004';
13+
}

app/Exceptions/Handler.php

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,44 +7,22 @@
77
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
88
use Throwable;
99

10-
class Handler extends ExceptionHandler
10+
final class Handler extends ExceptionHandler
1111
{
12-
/**
13-
* A list of exception types with their corresponding custom log levels.
14-
*
15-
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
16-
*/
17-
protected $levels = [
18-
//
19-
];
12+
protected $levels = [];
2013

21-
/**
22-
* A list of the exception types that are not reported.
23-
*
24-
* @var array<int, class-string<\Throwable>>
25-
*/
26-
protected $dontReport = [
27-
//
28-
];
14+
protected $dontReport = [];
2915

30-
/**
31-
* A list of the inputs that are never flashed to the session on validation exceptions.
32-
*
33-
* @var array<int, string>
34-
*/
3516
protected $dontFlash = [
3617
'current_password',
3718
'password',
3819
'password_confirmation',
3920
];
4021

41-
/**
42-
* Register the exception handling callbacks for the application.
43-
*/
4422
public function register(): void
4523
{
4624
$this->reportable(function (Throwable $e) {
47-
//
25+
dd($e);
4826
});
4927
}
5028
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Controllers;
6+
7+
use App\Enum\Error;
8+
use App\Http\Responses\ApiErrorResponse;
9+
use Illuminate\Http\Request;
10+
use JustSteveKing\StatusCode\Http;
11+
12+
final class FallbackController
13+
{
14+
public function __invoke(Request $request)
15+
{
16+
return new ApiErrorResponse(
17+
title: 'Oops',
18+
description: 'Oops I broke something.',
19+
code: Error::AUTH_001,
20+
status: Http::I_AM_A_TEAPOT,
21+
);
22+
}
23+
}

app/Http/Kernel.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace App\Http;
66

7+
use App\Http\Middleware\JsonApiResponseMiddleware;
78
use Illuminate\Foundation\Http\Kernel as HttpKernel;
89

910
class Kernel extends HttpKernel
@@ -44,6 +45,7 @@ class Kernel extends HttpKernel
4445
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
4546
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
4647
\Illuminate\Routing\Middleware\SubstituteBindings::class,
48+
JsonApiResponseMiddleware::class,
4749
],
4850
];
4951

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Middleware;
6+
7+
use Closure;
8+
use Illuminate\Http\Request;
9+
use Symfony\Component\HttpFoundation\Response;
10+
11+
final class JsonApiResponseMiddleware
12+
{
13+
/**
14+
* Handle an incoming request.
15+
*
16+
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
17+
*/
18+
public function handle(Request $request, Closure $next): Response
19+
{
20+
/**
21+
* @var Response $response
22+
*/
23+
$response = $next($request);
24+
25+
$response->headers->set(
26+
key: 'Content-Type',
27+
values: 'application/vnd.api+json',
28+
);
29+
30+
return $response;
31+
}
32+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Http\Responses;
6+
7+
use App\Enum\Error;
8+
use Illuminate\Contracts\Support\Responsable;
9+
use Illuminate\Http\JsonResponse;
10+
use JustSteveKing\StatusCode\Http;
11+
use Symfony\Component\HttpFoundation\Response;
12+
13+
final readonly class ApiErrorResponse implements Responsable
14+
{
15+
public function __construct(
16+
private string $title,
17+
private string $description,
18+
private Error $code,
19+
private Http $status = Http::INTERNAL_SERVER_ERROR,
20+
) {}
21+
22+
public function toResponse($request): Response
23+
{
24+
return new JsonResponse(
25+
data: [
26+
'title' => $this->title,
27+
'description' => $this->description,
28+
'code' => $this->code->value,
29+
'staus' => $this->status->value,
30+
],
31+
status: $this->status->value,
32+
);
33+
}
34+
}

app/Providers/RouteServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function boot(): void
1717
$this->configureRateLimiting();
1818

1919
$this->routes(function () {
20-
Route::middleware('api')
20+
Route::middleware(['api', 'treblle'])
2121
->as('api:')
2222
->group(
2323
base_path('routes/api.php')

app/Services/Cache/StorageService.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Services\Cache;
6+
7+
use Closure;
8+
use Illuminate\Support\Facades\Cache;
9+
10+
final class StorageService
11+
{
12+
public function remember(string $key, Closure $callback, int $ttl = 3600): mixed
13+
{
14+
return Cache::remember(
15+
key: $key,
16+
ttl: $ttl,
17+
callback: $callback,
18+
);
19+
}
20+
}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"laravel/framework": "^10.2",
1313
"laravel/sanctum": "^3.2.1",
1414
"laravel/tinker": "^2.8.1",
15-
"timacdonald/json-api": "v1.0.0-beta.4"
15+
"timacdonald/json-api": "v1.0.0-beta.4",
16+
"treblle/treblle-laravel": "^2.8"
1617
},
1718
"require-dev": {
1819
"fakerphp/faker": "^1.21.0",

composer.lock

Lines changed: 69 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)