Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
controllers
codebar-ag/coding-guidelines
implement
refactor
review
controllers
thin-controllers
form-requests
authorization
invokable-controllers
validation
http-responses

Thin HTTP entry points that validate input, delegate to Actions or Services, and return a response. Controllers contain no business logic.

Install
php artisan boost:add-skill codebar-ag/coding-guidelines

Save this content to: .claude/skills/controllers/SKILL.md

# Controllers

## When to Apply

- When creating or refactoring HTTP endpoints in `app/Http/Controllers/**`.
- When moving **business logic out of controllers** into Actions, Services, or Jobs.
- When ensuring API and web controllers follow consistent patterns for validation, authorization, and responses.
- When reviewing controllers for thinness, correct status codes, and proper delegation.

## Preconditions

- **Required:** Routing and controller setup exists (`routes/web.php`, `routes/api.php`).
- **Required:** Validation and authorization paths are defined (Form Requests, policies, or middleware).
- **Recommended:** Actions/Services for business logic are implemented before wiring the endpoint.
- **Recommended:** API/web response conventions (JSON vs views) are documented for the project.

## Process

### 1. Keep Controllers Thin

- Restrict controller responsibilities to:
  - Validating and authorizing incoming requests.
  - Delegating work to Actions, Services, or Jobs.
  - Returning appropriate HTTP responses (JSON or views).
- Remove any:
  - Direct database queries from controller methods.
  - Complex branching or multi-step domain logic.

### 2. Use Form Requests and Authorization

- Use dedicated `FormRequest` classes for **all validation**:
  - Avoid `$request->validate()` or `Validator::make()` directly in the controller.
- Enforce authorization at the controller level via:
  - `$this->authorize()` calls.
  - Form Request `authorize()` methods.
  - Route or controller middleware (e.g., `can:` or `auth`).

### 3. Design Controller Structure and Naming

- For single-action endpoints, use **invokable controllers** (`__invoke`):
  - Name them after the action: `StoreInvoiceController`, `ProcessWebhookController`.
- For resource controllers:
  - Keep each method thin and delegate to appropriate Actions or Services.
  - Only define the methods actually needed; prefer invokable controllers when only one or two actions exist.

### 4. Return Consistent Responses

- For API controllers:
  - Return JSON responses (e.g., `JsonResponse` or `Resource` / `ResourceCollection`).
  - Use appropriate HTTP status codes: 200, 201, 204, 403, 404, 422, etc.
  - Use explicit `JsonResponse` when status/header control matters; otherwise Laravel response casting is acceptable for simple payloads.
- For web controllers:
  - Return views or redirects, not JSON.
  - Keep view data preparation simple and delegated where possible.

### 5. Keep Controllers Testable

- Thin controllers push logic and most assertions into Action/Service tests.
- Controller tests should focus on HTTP contract: validation, authorization, status code, and response shape.

## Examples

```php
// Invokable single-action controller
class StoreInvoiceController extends Controller
{
    public function __invoke(StoreInvoiceRequest $request, CreateInvoice $action): JsonResponse
    {
        $invoice = $action->execute(
            orderId: (int) $request->validated('order_id'),
        );

        return new JsonResponse(new InvoiceResource($invoice), 201);
    }
}
```

```php
// Resource controller — thin, delegates to actions
class InvoiceController extends Controller
{
    public function index(): JsonResponse
    {
        // Explicit JsonResponse keeps status/header behavior clear for API controllers.
        return new JsonResponse(InvoiceResource::collection(Invoice::paginate()), 200);
    }

public function store(StoreInvoiceRequest $request, CreateInvoice $action): JsonResponse
    {
        $this->authorize('create', Invoice::class);

        $invoice = $action->execute(orderId: (int) $request->validated('order_id'));

        return new JsonResponse(new InvoiceResource($invoice), 201);
    }

    public function destroy(Invoice $invoice, DeleteInvoice $action): JsonResponse
    {
        $this->authorize('delete', $invoice);
        $action->execute($invoice);

        return new JsonResponse(null, 204);
    }
}
```

## Checklists

### Execution Checklist

- [ ] Controller methods contain **no business logic** or direct database queries.
- [ ] All validation is handled by **FormRequest** classes, not inline in the controller.
- [ ] Authorization is enforced via policies, Form Requests, or middleware.
- [ ] Controllers delegate to Actions, Services, or Jobs for business operations.
- [ ] Invokable controllers are used for single-action endpoints where appropriate.
- [ ] Responses use correct types and HTTP status codes (JSON for API, views for web).

## Safety / Things to Avoid

- Calling `$request->validate()` directly in a controller (use a FormRequest).
- Writing database queries or heavy business logic directly in controller methods.
- Using resource controllers with seven methods when only one or two are needed (prefer invokable controllers).
- Ignoring HTTP status codes or returning incorrect codes for errors and success.
- Performing authorization inside Actions instead of at the controller level.

## References

- [Laravel Controllers](https://laravel.com/docs/controllers)
- Related (read first): `Actions/SKILL.md` — the delegation pattern used by thin controllers
- Related: `FormRequests/SKILL.md` — all input validation
- Related: `Policies/SKILL.md` — authorization enforced in controllers

Controllers

When to Apply

  • When creating or refactoring HTTP endpoints in app/Http/Controllers/**.
  • When moving business logic out of controllers into Actions, Services, or Jobs.
  • When ensuring API and web controllers follow consistent patterns for validation, authorization, and responses.
  • When reviewing controllers for thinness, correct status codes, and proper delegation.

Preconditions

  • Required: Routing and controller setup exists (routes/web.php, routes/api.php).
  • Required: Validation and authorization paths are defined (Form Requests, policies, or middleware).
  • Recommended: Actions/Services for business logic are implemented before wiring the endpoint.
  • Recommended: API/web response conventions (JSON vs views) are documented for the project.

Process

1. Keep Controllers Thin

  • Restrict controller responsibilities to:
    • Validating and authorizing incoming requests.
    • Delegating work to Actions, Services, or Jobs.
    • Returning appropriate HTTP responses (JSON or views).
  • Remove any:
    • Direct database queries from controller methods.
    • Complex branching or multi-step domain logic.

2. Use Form Requests and Authorization

  • Use dedicated FormRequest classes for all validation:
    • Avoid $request->validate() or Validator::make() directly in the controller.
  • Enforce authorization at the controller level via:
    • $this->authorize() calls.
    • Form Request authorize() methods.
    • Route or controller middleware (e.g., can: or auth).

3. Design Controller Structure and Naming

  • For single-action endpoints, use invokable controllers (__invoke):
    • Name them after the action: StoreInvoiceController, ProcessWebhookController.
  • For resource controllers:
    • Keep each method thin and delegate to appropriate Actions or Services.
    • Only define the methods actually needed; prefer invokable controllers when only one or two actions exist.

4. Return Consistent Responses

  • For API controllers:
    • Return JSON responses (e.g., JsonResponse or Resource / ResourceCollection).
    • Use appropriate HTTP status codes: 200, 201, 204, 403, 404, 422, etc.
    • Use explicit JsonResponse when status/header control matters; otherwise Laravel response casting is acceptable for simple payloads.
  • For web controllers:
    • Return views or redirects, not JSON.
    • Keep view data preparation simple and delegated where possible.

5. Keep Controllers Testable

  • Thin controllers push logic and most assertions into Action/Service tests.
  • Controller tests should focus on HTTP contract: validation, authorization, status code, and response shape.

Examples

// Invokable single-action controller
class StoreInvoiceController extends Controller
{
    public function __invoke(StoreInvoiceRequest $request, CreateInvoice $action): JsonResponse
    {
        $invoice = $action->execute(
            orderId: (int) $request->validated('order_id'),
        );

        return new JsonResponse(new InvoiceResource($invoice), 201);
    }
}
// Resource controller — thin, delegates to actions
class InvoiceController extends Controller
{
    public function index(): JsonResponse
    {
        // Explicit JsonResponse keeps status/header behavior clear for API controllers.
        return new JsonResponse(InvoiceResource::collection(Invoice::paginate()), 200);
    }

public function store(StoreInvoiceRequest $request, CreateInvoice $action): JsonResponse
    {
        $this->authorize('create', Invoice::class);

        $invoice = $action->execute(orderId: (int) $request->validated('order_id'));

        return new JsonResponse(new InvoiceResource($invoice), 201);
    }

    public function destroy(Invoice $invoice, DeleteInvoice $action): JsonResponse
    {
        $this->authorize('delete', $invoice);
        $action->execute($invoice);

        return new JsonResponse(null, 204);
    }
}

Checklists

Execution Checklist

  • Controller methods contain no business logic or direct database queries.
  • All validation is handled by FormRequest classes, not inline in the controller.
  • Authorization is enforced via policies, Form Requests, or middleware.
  • Controllers delegate to Actions, Services, or Jobs for business operations.
  • Invokable controllers are used for single-action endpoints where appropriate.
  • Responses use correct types and HTTP status codes (JSON for API, views for web).

Safety / Things to Avoid

  • Calling $request->validate() directly in a controller (use a FormRequest).
  • Writing database queries or heavy business logic directly in controller methods.
  • Using resource controllers with seven methods when only one or two are needed (prefer invokable controllers).
  • Ignoring HTTP status codes or returning incorrect codes for errors and success.
  • Performing authorization inside Actions instead of at the controller level.

References

  • Laravel Controllers
  • Related (read first): Actions/SKILL.md — the delegation pattern used by thin controllers
  • Related: FormRequests/SKILL.md — all input validation
  • Related: Policies/SKILL.md — authorization enforced in controllers
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib