Skip to content

Commit

Permalink
feat: Update project with multiple improvements and new features
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
joelbladt committed Nov 23, 2024
1 parent 774343f commit 29a1213
Show file tree
Hide file tree
Showing 35 changed files with 2,338 additions and 681 deletions.
22 changes: 20 additions & 2 deletions app/Exceptions/BookNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
* @OA\Schema(
* schema="404BookNotFound",
* type="object",
* title="404 - Book not Found",
* description="Scheme Error - Book not Found",
*
* @OA\Property(
* property="error",
* type="object",
* @OA\Property(
* property="message",
* type="string",
* example="Book can not found"
* )
* )
* )
*/
class BookNotFoundException extends Exception
{
public function render(Request $request): JsonResponse
{
return response()->json([
'error' => [
'message' => "Book can not found"
]
'message' => 'Book can not found',
],
], 404);
}
}
22 changes: 20 additions & 2 deletions app/Exceptions/PublisherNotFoundException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,32 @@
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
* @OA\Schema(
* schema="404PublisherNotFound",
* type="object",
* title="404 - Publisher not Found",
* description="Scheme Error - Publisher not Found",
*
* @OA\Property(
* property="error",
* type="object",
* @OA\Property(
* property="message",
* type="string",
* example="Publisher can not found"
* )
* )
* )
*/
class PublisherNotFoundException extends Exception
{
public function render(Request $request): JsonResponse
{
return response()->json([
'error' => [
'message' => "Publisher can not found"
]
'message' => 'Publisher can not found',
],
], 404);
}
}
128 changes: 114 additions & 14 deletions app/Http/Controllers/BookController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,73 +10,173 @@
use App\Http\Resources\BookResourceCollection;
use App\Services\BookService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class BookController extends Controller
{
public function __construct(
protected BookService $bookService
) {
)
{
}

/**
* Display a listing of the resource.
*
* @return BookResourceCollection|\Illuminate\Http\Resources\Json\AnonymousResourceCollection
* @OA\Get(
* path="/api/books",
* summary="Get a collection of books",
* tags={"Books"},
*
* @OA\Parameter(ref="#/components/parameters/itemsPerPage"),
* @OA\Parameter(ref="#/components/parameters/currentPage"),
*
* @OA\Response(
* response=200,
* description="A collection of books",
*
* @OA\JsonContent(ref="#/components/schemas/BookResourceCollection")
* )
* )
*/
public function index()
public function index(Request $request): BookResourceCollection
{
$books = $this->bookService->getAllBooks();
$perPage = $request->integer('per_page', 10);
$page = $request->integer('page', 1);

$books = $this->bookService->getAllBooks($perPage, $page);

return new BookResourceCollection($books);
}

/**
* Store a newly created resource in storage.
*
* @param StoreBookRequest $request
* @return JsonResponse
* @OA\Post (
* path="/api/books",
* description="Created a new book",
* tags={"Books"},
*
* @OA\RequestBody(
* description="Store a new Book",
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/StoreBookRequest")
* ),
*
* @OA\Response(
* response=201,
* description="Created",
*
* @OA\JsonContent(ref="#/components/schemas/BookResource")
* )
* )
*/
public function store(StoreBookRequest $request): JsonResponse
{
$book = $this->bookService->createBook($request->validated());

return response()->json(new BookResource($book), 201);
}

/**
* Display the specified resource.
*
* @param int $id
* @return JsonResponse
* @throws BookNotFoundException
*
* @OA\Get(
* path="/api/books/{id}",
* description="Display the specified book",
* tags={"Books"},
*
* @OA\Parameter(ref="#/components/parameters/identifier"),
*
* @OA\Response(
* response=200,
* description="OK",
*
* @OA\JsonContent(ref="#/components/schemas/BookResource")
* ),
*
* @OA\Response(
* response=404,
* description="Book not Found",
*
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
* )
* )
*/
public function show(int $id): JsonResponse
{
$book = $this->bookService->findBookById($id);

return response()->json(new BookResource($book));
}

/**
* Update the specified resource in storage.
*
* @param UpdateBookRequest $request
* @param int $id
* @return JsonResponse
* @throws PublisherNotFoundException
* @throws BookNotFoundException|PublisherNotFoundException
*
* @OA\Put(
* path="/api/books/{id}",
* description="Update the specified book by replacing all properties",
* tags={"Books"},
*
* @OA\Parameter(ref="#/components/parameters/identifier"),
*
* @OA\RequestBody(
* description="Update the specified book by replacing all properties",
* required=true,
*
* @OA\JsonContent(ref="#/components/schemas/UpdateBookRequest")
* ),
*
* @OA\Response(
* response=200,
* description="OK",
*
* @OA\JsonContent(ref="#/components/schemas/BookResource")
* ),
*
* @OA\Response(
* response=404,
* description="Book not Found",
*
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
* )
* )
*/
public function update(UpdateBookRequest $request, int $id): JsonResponse
{
$book = $this->bookService->updateBook($id, $request->validated());

return response()->json(new BookResource($book), JsonResponse::HTTP_OK);
}

/**
* Remove the specified resource from storage.
*
* @param int $id
* @return bool|JsonResponse
* @OA\Delete(
* path="/api/books/{id}",
* description="Delete the specified book entirely",
* tags={"Books"},
*
* @OA\Parameter(ref="#/components/parameters/identifier"),
*
* @OA\Response(response=204, description="Success"),
* @OA\Response(
* response=404,
* description="Book not Found",
*
* @OA\JsonContent(ref="#/components/schemas/404BookNotFound")
* )
* )
*/
public function destroy(int $id): bool|JsonResponse
{
$this->bookService->deleteBook($id);

return response()->json(null, JsonResponse::HTTP_NO_CONTENT);
}
}
76 changes: 76 additions & 0 deletions app/Http/Controllers/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,82 @@

namespace App\Http\Controllers;

/**
* @OA\OpenApi(
*
* @OA\Info(
* version="1.1.0",
* title="Laravel API Boilerplate",
* description="API-Documentation for this Boilerplate",
* )
* ),
*
* @OA\Parameter(
* parameter="identifier",
* name="id",
* in="path",
* required=true,
*
* @OA\Schema(type="integer")
* )
*
* @OA\Parameter(
* parameter="itemsPerPage",
* name="per_page",
* in="query",
* required=false,
* description="Items per page for pagination",
*
* @OA\Schema(
* type="integer",
* default=10
* )
* )
*
* @OA\Parameter(
* parameter="currentPage",
* name="page",
* in="query",
* required=false,
* description="Current page number for the pagination",
*
* @OA\Schema(
* type="integer",
* default=1
* )
* )
* @OA\Schema(
* schema="MetadataResource",
* type="object",
* title="Metadata Schema Resource",
* description="Scheme for the Metadata",
*
* @OA\Property(
* property="per_page",
* type="integer",
* description="The number of items displayed per page in the paginated response",
* example="10"
* ),
* @OA\Property(
* property="current_page",
* type="integer",
* description="The current page number of the paginated data",
* example="1"
* ),
* @OA\Property(
* property="last_page",
* type="integer",
* description="The total number of pages available",
* example="1"
* ),
* @OA\Property(
* property="total",
* type="integer",
* description="The total number of items in the dataset",
* example="3"
* )
* )
*/
abstract class Controller
{
//
Expand Down
Loading

0 comments on commit 29a1213

Please sign in to comment.