> For the complete documentation index, see [llms.txt](https://core-foundation-doc.rupeshstha.com.np/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://core-foundation-doc.rupeshstha.com.np/http-and-application-layer/controllers.md).

# Controllers

All controllers in your application should extend `CoreFoundation\Http\Controllers\BaseController`. This base controller provides standardized response helpers, exception handling, and translation utilities.

## Setup

```php
namespace App\Http\Controllers;

use App\Services\UserService;
use App\Transformers\UserResource;
use CoreFoundation\Http\Controllers\BaseController;

class UserController extends BaseController
{
    public function __construct(
        private readonly UserService $userService
    ) {}
}
```

## Integrated Traits

The `BaseController` combines several powerful traits:

* `HasApiResponse`: Provides methods like `successResponse()`, `createdResponse()`, and `paginatedResponse()`.
* `HasExceptionHandler`: Automatically maps exceptions to JSON responses (see [Exception Handling](/http-and-application-layer/exceptions.md)).
* `HasLang`: Simplifies access to translation keys scoped to the controller.
* `AuthorizesRequests`: Standard Laravel policy authorization.

## Standard Success Responses

Use these methods to return consistent JSON envelopes:

```php
public function index(Request $request)
{
    $users = $this->userService->index($request->query());

    return $this->successResponse(
        message: 'Users fetched successfully.',
        payload: UserResource::collection($users)
    );
}

public function store(StoreUserRequest $request)
{
    $user = $this->userService->create($request->validated());

    return $this->createdResponse(
        message: 'User created successfully.',
        payload: new UserResource($user)
    );
}
```

## Translation

### In controllers — `$this->lang()`

The `HasLang` trait strips the `Controller` suffix then applies kebab-case to derive a translation prefix:

```php
// UserController           → prefix 'user'
// ProductVariantController → prefix 'product-variant'
$this->lang('create-success')                  // → trans('product-variant.create-success')
$this->lang('core-foundation::http.not-found') // dot present → bypasses prefix → trans('core-foundation::http.not-found')
```

Override `langPrefix()` when the auto-derived prefix isn't right:

```php
protected function langPrefix(): string
{
    return 'product-variant'; // trans('product-variant.*')
}
```

### Outside controllers — `Lang::get()`

For classes that don't extend `BaseController` (exceptions, requests, static utilities), use `Lang::get()` directly:

```php
use CoreFoundation\Support\Lang;

Lang::get('core-foundation::http.unauthenticated')
Lang::get('core-foundation::features.not-found', ['feature' => $name])
```

> `HasLang` is a trait — never call `HasLang::method()` statically. Use `Lang::get()` instead.

## Exception Handling

The `BaseController` is designed to be used with try/catch blocks that delegate to the integrated handler:

```php
public function show(int $id)
{
    try {
        $user = $this->userService->find($id);
    } catch (\Throwable $e) {
        return $this->handleException($e);
    }

    return $this->successResponse('User found.', new UserResource($user));
}
```

Domain-specific exceptions should extend `BaseApiException` and carry their own `render()` method — Laravel calls it automatically. No controller mapping needed. `handleException()` is the last-resort fallback for anything that isn't a `BaseApiException`.

## Container Binding

Controllers are **not registered in the service container**. Laravel resolves them automatically per request — no binding needed. Constructor-injected dependencies (services, repositories) are resolved via the container on each request.

```php
// No binding required — Laravel handles controller resolution
class OrderController extends BaseController
{
    public function __construct(
        private readonly OrderService    $orderService,    // resolved per request
        private readonly OrderRepository $orderRepository, // resolved per request
    ) {}
}
```
