98 lines
2.1 KiB
Markdown
98 lines
2.1 KiB
Markdown
# Routing & Controllers Best Practices
|
|
|
|
## Use Implicit Route Model Binding
|
|
|
|
Let Laravel resolve models automatically from route parameters.
|
|
|
|
Incorrect:
|
|
```php
|
|
public function show(int $id)
|
|
{
|
|
$post = Post::findOrFail($id);
|
|
}
|
|
```
|
|
|
|
Correct:
|
|
```php
|
|
public function show(Post $post)
|
|
{
|
|
return view('posts.show', ['post' => $post]);
|
|
}
|
|
```
|
|
|
|
## Use Scoped Bindings for Nested Resources
|
|
|
|
Enforce parent-child relationships automatically.
|
|
|
|
```php
|
|
Route::get('/users/{user}/posts/{post}', function (User $user, Post $post) {
|
|
// $post is automatically scoped to $user
|
|
})->scopeBindings();
|
|
```
|
|
|
|
## Use Resource Controllers
|
|
|
|
Use `Route::resource()` or `apiResource()` for RESTful endpoints.
|
|
|
|
```php
|
|
Route::resource('posts', PostController::class);
|
|
Route::apiResource('api/posts', Api\PostController::class);
|
|
```
|
|
|
|
## Keep Controllers Thin
|
|
|
|
Aim for under 10 lines per method. Extract business logic to action or service classes.
|
|
|
|
Incorrect:
|
|
```php
|
|
public function store(Request $request)
|
|
{
|
|
$validated = $request->validate([...]);
|
|
if ($request->hasFile('image')) {
|
|
$request->file('image')->move(public_path('images'));
|
|
}
|
|
$post = Post::create($validated);
|
|
$post->tags()->sync($validated['tags']);
|
|
event(new PostCreated($post));
|
|
return redirect()->route('posts.show', $post);
|
|
}
|
|
```
|
|
|
|
Correct:
|
|
```php
|
|
public function store(StorePostRequest $request, CreatePostAction $create)
|
|
{
|
|
$post = $create->execute($request->validated());
|
|
|
|
return redirect()->route('posts.show', $post);
|
|
}
|
|
```
|
|
|
|
## Type-Hint Form Requests
|
|
|
|
Type-hinting Form Requests triggers automatic validation and authorization before the method executes.
|
|
|
|
Incorrect:
|
|
```php
|
|
public function store(Request $request): RedirectResponse
|
|
{
|
|
$validated = $request->validate([
|
|
'title' => ['required', 'max:255'],
|
|
'body' => ['required'],
|
|
]);
|
|
|
|
Post::create($validated);
|
|
|
|
return redirect()->route('posts.index');
|
|
}
|
|
```
|
|
|
|
Correct:
|
|
```php
|
|
public function store(StorePostRequest $request): RedirectResponse
|
|
{
|
|
Post::create($request->validated());
|
|
|
|
return redirect()->route('posts.index');
|
|
}
|
|
``` |