> ## Documentation Index
> Fetch the complete documentation index at: https://alphaconsultings.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Controllers

> Generated controller CRUD flow and mixin-aware runtime behavior.

# Controller Usage Guide

Use generated controllers as thin Express adapters. Keep persistence, relation loading, cache policy, and soft-delete rules in services and models.

Preferred CRUD flow:

* controllers delegate to service methods
* services use `User.find(...)`, `User.create(...)`, loaded-instance `update(...); save()`, and explicit `User.deleteById(...)` / `User.restoreById(...)`
* controllers should not introduce their own persistence logic

## Generate a controller

```bash theme={null}
eloquent make:controller User
eloquent make:controller User --soft
eloquent make:controller User --test
```

## Generated methods

* `index()`
* `show()`
* `store()`
* `update()`
* `destroy()`
* `restore()` when generated with `--soft`

## Express route wiring

```ts theme={null}
import express from "express";
import { UserController } from "./app/controllers/UserController";

const app = express();
app.use(express.json());

const controller = new UserController();

app.get("/users", controller.index.bind(controller));
app.get("/users/:id", controller.show.bind(controller));
app.post("/users", controller.store.bind(controller));
app.put("/users/:id", controller.update.bind(controller));
app.delete("/users/:id", controller.destroy.bind(controller));
app.patch("/users/:id/restore", controller.restore.bind(controller));
```

Only add the restore route when the controller was generated with `--soft`.

## Mixin-aware behavior

Controllers do not own mixins. They consume model/service behavior that comes from the composed model stack.

### Soft deletes

If the model supports soft deletes, keep `destroy()` as soft delete and expose `restore()` from the controller.

Recommended service shape behind the controller:

```ts theme={null}
async destroy(id: number | string) {
  return User.deleteById(id);
}

async restore(id: number | string) {
  return User.restoreById(id);
}
```

Use one schema declaration, not both:

```ts theme={null}
deleted_at: column("softDeletes")
```

or:

```ts theme={null}
softDeletes: mixin("SoftDeletes")
```

### Serialization

If the model uses hidden/appended fields, prefer `toObject()` before `res.json(...)`.

### Eager loading and cache

* Keep relation loading in the service layer.
* Keep cache logic in the service layer.

## Driver note

The controller contract is the same for SQL and Mongo models. Keep driver branching out of route handlers.
