Skip to content

Commit 29a1213

Browse files
committed
feat: Update project with multiple improvements and new features
- Applied Laravel Pint with default rules for consistent code formatting. - Implemented `LengthAwarePaginator` in `index()` methods to enable pagination, ensuring better performance and user experience. - Added a new API route `/api/publisher/{id}/books` to fetch books by publisher, also with pagination using `LengthAwarePaginator`. - Updated `l5-swagger.php` to use `storage_path('docs')` instead of `api-docs` and removed the outdated `api-docs` directory. - Enhanced API tests to ensure 100% test coverage and validate new functionality.
1 parent 774343f commit 29a1213

35 files changed

+2338
-681
lines changed

app/Exceptions/BookNotFoundException.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,32 @@
66
use Illuminate\Http\JsonResponse;
77
use Illuminate\Http\Request;
88

9+
/**
10+
* @OA\Schema(
11+
* schema="404BookNotFound",
12+
* type="object",
13+
* title="404 - Book not Found",
14+
* description="Scheme Error - Book not Found",
15+
*
16+
* @OA\Property(
17+
* property="error",
18+
* type="object",
19+
* @OA\Property(
20+
* property="message",
21+
* type="string",
22+
* example="Book can not found"
23+
* )
24+
* )
25+
* )
26+
*/
927
class BookNotFoundException extends Exception
1028
{
1129
public function render(Request $request): JsonResponse
1230
{
1331
return response()->json([
1432
'error' => [
15-
'message' => "Book can not found"
16-
]
33+
'message' => 'Book can not found',
34+
],
1735
], 404);
1836
}
1937
}

app/Exceptions/PublisherNotFoundException.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,32 @@
66
use Illuminate\Http\JsonResponse;
77
use Illuminate\Http\Request;
88

9+
/**
10+
* @OA\Schema(
11+
* schema="404PublisherNotFound",
12+
* type="object",
13+
* title="404 - Publisher not Found",
14+
* description="Scheme Error - Publisher not Found",
15+
*
16+
* @OA\Property(
17+
* property="error",
18+
* type="object",
19+
* @OA\Property(
20+
* property="message",
21+
* type="string",
22+
* example="Publisher can not found"
23+
* )
24+
* )
25+
* )
26+
*/
927
class PublisherNotFoundException extends Exception
1028
{
1129
public function render(Request $request): JsonResponse
1230
{
1331
return response()->json([
1432
'error' => [
15-
'message' => "Publisher can not found"
16-
]
33+
'message' => 'Publisher can not found',
34+
],
1735
], 404);
1836
}
1937
}

app/Http/Controllers/BookController.php

Lines changed: 114 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,73 +10,173 @@
1010
use App\Http\Resources\BookResourceCollection;
1111
use App\Services\BookService;
1212
use Illuminate\Http\JsonResponse;
13+
use Illuminate\Http\Request;
1314

1415
class BookController extends Controller
1516
{
1617
public function __construct(
1718
protected BookService $bookService
18-
) {
19+
)
20+
{
1921
}
2022

2123
/**
2224
* Display a listing of the resource.
2325
*
24-
* @return BookResourceCollection|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
26+
* @OA\Get(
27+
* path="/api/books",
28+
* summary="Get a collection of books",
29+
* tags={"Books"},
30+
*
31+
* @OA\Parameter(ref="#/components/parameters/itemsPerPage"),
32+
* @OA\Parameter(ref="#/components/parameters/currentPage"),
33+
*
34+
* @OA\Response(
35+
* response=200,
36+
* description="A collection of books",
37+
*
38+
* @OA\JsonContent(ref="#/components/schemas/BookResourceCollection")
39+
* )
40+
* )
2541
*/
26-
public function index()
42+
public function index(Request $request): BookResourceCollection
2743
{
28-
$books = $this->bookService->getAllBooks();
44+
$perPage = $request->integer('per_page', 10);
45+
$page = $request->integer('page', 1);
46+
47+
$books = $this->bookService->getAllBooks($perPage, $page);
48+
2949
return new BookResourceCollection($books);
3050
}
3151

3252
/**
3353
* Store a newly created resource in storage.
3454
*
35-
* @param StoreBookRequest $request
36-
* @return JsonResponse
55+
* @OA\Post (
56+
* path="/api/books",
57+
* description="Created a new book",
58+
* tags={"Books"},
59+
*
60+
* @OA\RequestBody(
61+
* description="Store a new Book",
62+
* required=true,
63+
*
64+
* @OA\JsonContent(ref="#/components/schemas/StoreBookRequest")
65+
* ),
66+
*
67+
* @OA\Response(
68+
* response=201,
69+
* description="Created",
70+
*
71+
* @OA\JsonContent(ref="#/components/schemas/BookResource")
72+
* )
73+
* )
3774
*/
3875
public function store(StoreBookRequest $request): JsonResponse
3976
{
4077
$book = $this->bookService->createBook($request->validated());
78+
4179
return response()->json(new BookResource($book), 201);
4280
}
4381

4482
/**
4583
* Display the specified resource.
4684
*
47-
* @param int $id
48-
* @return JsonResponse
4985
* @throws BookNotFoundException
86+
*
87+
* @OA\Get(
88+
* path="/api/books/{id}",
89+
* description="Display the specified book",
90+
* tags={"Books"},
91+
*
92+
* @OA\Parameter(ref="#/components/parameters/identifier"),
93+
*
94+
* @OA\Response(
95+
* response=200,
96+
* description="OK",
97+
*
98+
* @OA\JsonContent(ref="#/components/schemas/BookResource")
99+
* ),
100+
*
101+
* @OA\Response(
102+
* response=404,
103+
* description="Book not Found",
104+
*
105+
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
106+
* )
107+
* )
50108
*/
51109
public function show(int $id): JsonResponse
52110
{
53111
$book = $this->bookService->findBookById($id);
112+
54113
return response()->json(new BookResource($book));
55114
}
56115

57116
/**
58117
* Update the specified resource in storage.
59118
*
60-
* @param UpdateBookRequest $request
61-
* @param int $id
62-
* @return JsonResponse
63-
* @throws PublisherNotFoundException
119+
* @throws BookNotFoundException|PublisherNotFoundException
120+
*
121+
* @OA\Put(
122+
* path="/api/books/{id}",
123+
* description="Update the specified book by replacing all properties",
124+
* tags={"Books"},
125+
*
126+
* @OA\Parameter(ref="#/components/parameters/identifier"),
127+
*
128+
* @OA\RequestBody(
129+
* description="Update the specified book by replacing all properties",
130+
* required=true,
131+
*
132+
* @OA\JsonContent(ref="#/components/schemas/UpdateBookRequest")
133+
* ),
134+
*
135+
* @OA\Response(
136+
* response=200,
137+
* description="OK",
138+
*
139+
* @OA\JsonContent(ref="#/components/schemas/BookResource")
140+
* ),
141+
*
142+
* @OA\Response(
143+
* response=404,
144+
* description="Book not Found",
145+
*
146+
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
147+
* )
148+
* )
64149
*/
65150
public function update(UpdateBookRequest $request, int $id): JsonResponse
66151
{
67152
$book = $this->bookService->updateBook($id, $request->validated());
153+
68154
return response()->json(new BookResource($book), JsonResponse::HTTP_OK);
69155
}
70156

71157
/**
72158
* Remove the specified resource from storage.
73159
*
74-
* @param int $id
75-
* @return bool|JsonResponse
160+
* @OA\Delete(
161+
* path="/api/books/{id}",
162+
* description="Delete the specified book entirely",
163+
* tags={"Books"},
164+
*
165+
* @OA\Parameter(ref="#/components/parameters/identifier"),
166+
*
167+
* @OA\Response(response=204, description="Success"),
168+
* @OA\Response(
169+
* response=404,
170+
* description="Book not Found",
171+
*
172+
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
173+
* )
174+
* )
76175
*/
77176
public function destroy(int $id): bool|JsonResponse
78177
{
79178
$this->bookService->deleteBook($id);
179+
80180
return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
81181
}
82182
}

app/Http/Controllers/Controller.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,82 @@
22

33
namespace App\Http\Controllers;
44

5+
/**
6+
* @OA\OpenApi(
7+
*
8+
* @OA\Info(
9+
* version="1.1.0",
10+
* title="Laravel API Boilerplate",
11+
* description="API-Documentation for this Boilerplate",
12+
* )
13+
* ),
14+
*
15+
* @OA\Parameter(
16+
* parameter="identifier",
17+
* name="id",
18+
* in="path",
19+
* required=true,
20+
*
21+
* @OA\Schema(type="integer")
22+
* )
23+
*
24+
* @OA\Parameter(
25+
* parameter="itemsPerPage",
26+
* name="per_page",
27+
* in="query",
28+
* required=false,
29+
* description="Items per page for pagination",
30+
*
31+
* @OA\Schema(
32+
* type="integer",
33+
* default=10
34+
* )
35+
* )
36+
*
37+
* @OA\Parameter(
38+
* parameter="currentPage",
39+
* name="page",
40+
* in="query",
41+
* required=false,
42+
* description="Current page number for the pagination",
43+
*
44+
* @OA\Schema(
45+
* type="integer",
46+
* default=1
47+
* )
48+
* )
49+
* @OA\Schema(
50+
* schema="MetadataResource",
51+
* type="object",
52+
* title="Metadata Schema Resource",
53+
* description="Scheme for the Metadata",
54+
*
55+
* @OA\Property(
56+
* property="per_page",
57+
* type="integer",
58+
* description="The number of items displayed per page in the paginated response",
59+
* example="10"
60+
* ),
61+
* @OA\Property(
62+
* property="current_page",
63+
* type="integer",
64+
* description="The current page number of the paginated data",
65+
* example="1"
66+
* ),
67+
* @OA\Property(
68+
* property="last_page",
69+
* type="integer",
70+
* description="The total number of pages available",
71+
* example="1"
72+
* ),
73+
* @OA\Property(
74+
* property="total",
75+
* type="integer",
76+
* description="The total number of items in the dataset",
77+
* example="3"
78+
* )
79+
* )
80+
*/
581
abstract class Controller
682
{
783
//

0 commit comments

Comments
 (0)