Skip to content

Commit

Permalink
repository pattern implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Ali Özen committed Apr 26, 2023
1 parent ef4156a commit f355a5d
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 11 deletions.
1 change: 1 addition & 0 deletions app/Enums/CommentStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ enum CommentStatus: string
case PASSIVE = 'passive';
case PENDING = 'pending';
case TRASH = 'trash';
case ANALYZING = 'analyzing';
}
35 changes: 27 additions & 8 deletions app/Http/Controllers/CommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,54 @@
use App\Http\Requests\CommentRequest;
use App\Http\Resources\CommentResource;
use App\Models\Comment;
use App\Repositories\CommentRepositoryInterface;

class CommentController extends Controller
{
public function __construct(protected CommentRepositoryInterface $repository)
{
}

public function index()
{
return CommentResource::collection(Comment::all());
return CommentResource::collection(
$this->repository->all()
);
}

public function store(CommentRequest $request)
{
return new CommentResource(Comment::create($request->validated()));
return new CommentResource(
$this->repository->create(
$request->validated()
)
);
}

public function show(Comment $comment)
{
return new CommentResource($comment);
return new CommentResource(
$this->repository->find(
$comment->id
)
);
}

public function update(CommentRequest $request, Comment $comment)
{
$comment->update($request->validated());

return new CommentResource($comment);
return new CommentResource(
$this->repository->update(
$comment->id,
$request->validated()
)
);
}

public function delete(Comment $comment)
{
$comment->delete();

return response()->json();
return $this->repository->delete(
$comment->id
);
}
}
4 changes: 3 additions & 1 deletion app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace App\Providers;

use App\Repositories\CommentRepository;
use App\Repositories\CommentRepositoryInterface;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
Expand All @@ -11,7 +13,7 @@ class AppServiceProvider extends ServiceProvider
*/
public function register(): void
{
//
$this->app->bind(CommentRepositoryInterface::class, CommentRepository::class);
}

/**
Expand Down
40 changes: 40 additions & 0 deletions app/Repositories/BaseRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Repositories;

use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use stdClass;

class BaseRepository implements BaseRepositoryInterface
{
public function __construct(protected Model $model)
{

}

public function all(): Collection
{
return $this->model->all();
}

public function find(int|string $id): ?stdClass
{
return (object) $this->model->findOrFail($id)->toArray();
}

public function create(array $data): stdClass
{
return $this->model->create([$data])->toArray();
}

public function update(string|int $id, array $data): ?stdClass
{
return (object) tap($this->model->findOrFail($id))->update($data)->toArray();
}

public function delete(int|string $id): bool
{
return $this->model->findOrFail($id)->delete();
}
}
19 changes: 19 additions & 0 deletions app/Repositories/BaseRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Repositories;

use Illuminate\Database\Eloquent\Collection;
use stdClass;

interface BaseRepositoryInterface
{
public function all(): Collection;

public function find(int|string $id): ?stdClass;

public function create(array $data): stdClass;

public function update(int|string $id, array $data): ?stdClass;

public function delete(int|string $id): bool;
}
28 changes: 28 additions & 0 deletions app/Repositories/CommentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace App\Repositories;

use App\Enums\CommentStatus;
use App\Models\Comment;
use stdClass;

class CommentRepository extends BaseRepository implements CommentRepositoryInterface
{
public function __construct(Comment $comment)
{
parent::__construct($comment);
}

// Overriding BaseRepository method
// For example. If I have to pass ANALYZING case when $data['status'] is not exists. This can be handle in CommentRepository.
//(Maybe here is not a great place to apply this usage. In Comment Model we can use creating case on boot method)
public function create(array $data): stdClass
{
return (object) $this->model->create([
'email' => $data['email'],
'body' => $data['body'],
'rate' => $data['rate'],
'status' => $data['status'] ?? CommentStatus::ANALYZING->value,
])->toArray();
}
}
11 changes: 11 additions & 0 deletions app/Repositories/CommentRepositoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace App\Repositories;

interface CommentRepositoryInterface
{
// In here some of interface instances may override
// Usage examples:
// Example1: In some cases, instead of using "array $data" as
// parameter, a structure like "CommentDTO $data" can be used
}
15 changes: 13 additions & 2 deletions tests/Feature/Api/CommentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

class CommentTest extends TestCase
{
public function test_index_has_comments()
{
$this->get('/api/comments')->assertSuccessful();
}

public function test_stores_a_comment()
{
$this->post('/api/comments', [
Expand All @@ -16,17 +21,23 @@ public function test_stores_a_comment()
])->assertSuccessful();
}

public function test_view_a_comment()
{
$comment = Comment::latest()->first();
$this->get('/api/comments/'.$comment->id)->assertSuccessful();
}

public function test_updates_a_comment()
{
$comment = Comment::first();
$comment = Comment::latest()->first();
$this->put('/api/comments/'.$comment->id, [
'body' => 'update comment | testing repository pattern',
])->assertSuccessful();
}

public function test_delete_a_comment()
{
$comment = Comment::first();
$comment = Comment::latest()->first();
$this->delete('/api/comments/'.$comment->id)->assertSuccessful();
}
}

0 comments on commit f355a5d

Please sign in to comment.