Answer the question
In order to leave comments, you need to log in
How to build a large project?
Hello. Need advice - how to build a large project?
now I have created something like this project structure:
there is a CategoryController controller
class CategoryController extends Controller
{
public function __construct(
private CategoryService $categoryService
)
{
}
public function store(CategoryRequest $request)
{
return $this->categoryService->store($request->validated());
}
public function show(int $id)
{
return $this->categoryService->showById($id);
}
public function update(CategoryRequest $request, int $id)
{
return $this->categoryService->updateById($id, $request->validated());
}
}
class CategoryService
{
use JsonResponseTrait;
public function __construct(
private CategoryQueryInterface $categoryQuery,
private CategoryActionInterface $categoryAction,
)
{
}
public function store(array $data): JsonResponse
{
try {
$this->categoryAction->store($data);
return $this->successApiResponse([], Lang::get('database.store_success'));
} catch (Exception $e) {
return $this->errorStringApiResponse($e->getMessage(), 500);
}
}
public function showById(int $id): JsonResponse
{
$category = $this->categoryQuery->findById($id);
if (!$category) return $this->notFoundApiResponse([], '404');
$data = [
'id' => $category->id,
'name' => $category->name,
'icon' => $category->icon,
'description' => $category->description,
'metaTitle' => $category->meta_title,
'metaDescription' => $category->meta_description,
'isPublished' => $category->is_published,
'slug' => $category->slug,
'updatedAt' => $category->updated_at
];
return $this->okApiResponse($data);
}
public function updateById(int $id, array $data): JsonResponse
{
$model = $this->categoryQuery->findById($id);
if (!$model) return $this->notFoundApiResponse([], Lang::get('database.record_not_fount'));
try {
$this->categoryAction->update($id, $data);
return $this->successApiResponse([], Lang::get('database.update_success'));
} catch (Exception $e) {
return $this->errorStringApiResponse($e->getMessage(), 500);
}
}
}
class CategoryQuery implements CategoryQueryInterface
{
public function findById(int $id): ?Category
{
$query = Category::find($id);
return $query;
}
}
class CategoryAction implements CategoryActionInterface
{
public function store(array $data): void
{
$store = new Category();
$store->name = trim($data['name']);
$store->icon = trim($data['icon']);
$store->description = trim($data['description']);
$store->text = $data['text'];
$store->meta_title = $data['metaTitle'] ?? $data['name'];
$store->meta_description = $data['metaDescription'] ?? $data['metaDescription'];
$store->is_published = $data['isPublished'];
$store->slug = trim($data['slug']) ?? Str::slug($data['title'], '-');
$store->save();
}
public function update(Category $category, array $data): void
{
$category->name = trim($data['name']);
$category->icon = trim($data['icon']);
$category->description = trim($data['description']);
$category->text = $data['text'];
$category->meta_title = $data['metaTitle'] ?? $data['name'];
$category->meta_description = $data['metaDescription'] ?? $data['metaDescription'];
$category->is_published = $data['isPublished'];
$category->slug = trim($data['slug']) ?? Str::slug($data['title'], '-');
$category->save();
}
}
Answer the question
In order to leave comments, you need to log in
It is called, I heard a ringing, but I don’t know where it is.
1. You turned the service layer into a controller.
Those. you have a controller, and you created another one, because somewhere heard that services are necessary.
But, services do not send responses, this is an internal layer for separating logic.
You can call those methods through the console, other services, etc.
There, return should simply be generated, and the response itself is already in the controller (so that the controller performs its own function). Validation of the request, by the way, also needs to be done not in the server.
2. CategoryQuery is just wild game.
You're making a duplicate again because you heard about the repositories, and even the interface. So I'm dying from people who shove interfaces everywhere. Interfaces are needed where they are needed. Where there will be 2+ interface inheritors.
Where do you get heirs from here, if you are tied to the elocuent?
And the legs are from the Indian repositories. Repository, Query and interfaces are not needed when working in elokuent. He already contains all this in himself and all the repeating things are already wrapped. find, first, firstOrNew etc.
So use elocuent and don't overcomplicate the project unnecessarily. Don't make it hard, make it simple.
3.CategoryAction.
Again, the interface ...
This is Action, in fact, you have a service. Here you transferred the business logic of creation and editing and return the response of this method. Here, delete your CategoryAction and transfer the methods to the service.
the showById method seems superfluous to me.
404 and so will return if you use model binding,
why rebuild attributes? just return the model and that's it. hide unnecessary attributes in the $hidden property, add custom attributes to $appends
will be short
public function show(Category $category)
{
return response()->json($category->toArray());
}
No no no, first build a flowchart to have a visual representation of what kind of interactions you will have, how the data will walk. Since everything is forgotten over time, you can always turn to her and remember. Moreover, when you want to change something, you will reflect it in the flowchart, and you will know what exactly needs to be changed in the project and, which is very important, you will know how the changed parts affect others.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question