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

# Respuestas

> Explicamos los tipos de respuesta en Laravel y cómo devolver la respuesta adecuada desde un controlador.

## ¿Qué es una respuesta?

Los controladores y las rutas necesitan devolver alguna **respuesta** al navegador del usuario.
Laravel ofrece mecanismos sencillos para devolver diversos formatos: cadenas, arrays, vistas, redirecciones, JSON, etc.

## Respuestas básicas

### Devolver una cadena

La respuesta más simple es devolver una cadena.
Laravel la convierte automáticamente en la respuesta HTTP adecuada.

```php theme={null}
Route::get('/', function () {
    return 'Hello World';
});
```

### Devolver un array

Al devolver un array, Laravel lo convierte automáticamente a JSON.

```php theme={null}
Route::get('/users', function () {
    return [
        ['id' => 1, 'name' => 'Tanaka'],
        ['id' => 2, 'name' => 'Suzuki'],
    ];
});
```

<Info>
  Si devuelves un modelo Eloquent o una colección directamente, también se convierten automáticamente a JSON. Es un patrón muy usado para APIs sencillas.
</Info>

### Devolver un modelo Eloquent

```php theme={null}
use App\Models\User;

Route::get('/user/{user}', function (User $user) {
    return $user;
});
```

## Objeto Response

Con el helper `response()` puedes devolver una respuesta detallada con código de estado HTTP y cabeceras específicas.

```php theme={null}
Route::get('/home', function () {
    return response('Hello World', 200)
        ->header('Content-Type', 'text/plain');
});
```

El primer argumento de `response()` es el cuerpo y el segundo el código de estado HTTP.

### Códigos de estado HTTP habituales

| Código | Significado                                |
| ------ | ------------------------------------------ |
| `200`  | OK (éxito)                                 |
| `201`  | Created (recurso creado)                   |
| `204`  | No Content (sin contenido)                 |
| `301`  | Moved Permanently (redirección permanente) |
| `302`  | Found (redirección temporal)               |
| `404`  | Not Found (no encontrado)                  |
| `422`  | Unprocessable Entity (error de validación) |
| `500`  | Internal Server Error (error del servidor) |

## Respuestas con vistas

Para mostrar una plantilla Blade desde el controlador usa `view()`.
Es la respuesta más común en aplicaciones web.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\View\View;

class HomeController extends Controller
{
    public function index(): View
    {
        $users = [
            ['name' => 'Tanaka', 'email' => 'tanaka@example.com'],
            ['name' => 'Suzuki', 'email' => 'suzuki@example.com'],
        ];

        return view('users.index', ['users' => $users]);
    }
}
```

`view()` recibe el nombre de la vista como primer argumento y un array de datos como segundo.

<Tip>
  Tipar el retorno como `Illuminate\View\View` deja más clara la intención del código.
</Tip>

### `response()->view()` para más control

Si necesitas indicar código de estado o cabeceras, usa `response()->view()`.

```php theme={null}
return response()
    ->view('errors.404', ['message' => 'Página no encontrada'], 404);
```

## Redirecciones

### Redirección básica

El helper `redirect()` devuelve una respuesta de redirección.
Se usa mucho para llevar al usuario a otra página tras enviar un formulario.

```php theme={null}
use Illuminate\Http\RedirectResponse;

Route::get('/old-page', function (): RedirectResponse {
    return redirect('/new-page');
});
```

Uso en controlador:

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function store(Request $request): RedirectResponse
    {
        // Procesamiento para guardar el post...

        return redirect('/posts');
    }
}
```

### Redirección a ruta con nombre

Con `route()` puedes indicar el destino de la redirección por el nombre de la ruta, sin escribir la URL.
Aunque la URL cambie, no hay que modificar nada; usar rutas con nombre es una buena práctica.

```php theme={null}
// Da nombre a la ruta
Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
```

```php theme={null}
// Redirige a la ruta con nombre
return redirect()->route('posts.index');

// Con parámetros
return redirect()->route('posts.show', ['post' => $post->id]);
```

### Volver a la página anterior

Con `back()` vuelves a la página donde estaba el usuario.
Muy usado tras un fallo de validación.

```php theme={null}
return back();

// Vuelve manteniendo los datos introducidos
return back()->withInput();
```

### Redirección con mensaje flash

Con `with()` puedes redirigir dejando un mensaje en la sesión.
Útil para mostrar un mensaje tras enviar un formulario con éxito.

```php theme={null}
return redirect('/posts')->with('success', 'Post creado.');
```

Muéstralo en la plantilla Blade.

```blade theme={null}
@if (session('success'))
    <div class="alert alert-success">
        {{ session('success') }}
    </div>
@endif
```

## Respuestas JSON

Para APIs, usa `response()->json()`.
La cabecera `Content-Type: application/json` se configura automáticamente.

```php theme={null}
use Illuminate\Http\JsonResponse;

Route::get('/api/users', function (): JsonResponse {
    $users = [
        ['id' => 1, 'name' => 'Tanaka'],
        ['id' => 2, 'name' => 'Suzuki'],
    ];

    return response()->json($users);
});
```

También puedes indicar el código de estado.

```php theme={null}
return response()->json(['message' => 'Creado'], 201);
```

Uso en controlador:

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(): JsonResponse
    {
        $users = User::all();

        return response()->json($users);
    }

    public function store(Request $request): JsonResponse
    {
        // Crear con los datos validados (tras usar form request o $request->validate())
        $user = User::create($request->validated());

        return response()->json($user, 201);
    }
}
```

<Info>
  Devolver directamente un array o un modelo Eloquent también produce una respuesta JSON, pero `response()->json()` te da control fino sobre el código de estado y las cabeceras.
</Info>

## Cabeceras de respuesta

Con `header()` añades una cabecera HTTP a la respuesta.

```php theme={null}
return response('Hello World')
    ->header('Content-Type', 'text/plain')
    ->header('X-Custom-Header', 'MyValue');
```

Para configurar varias a la vez, usa `withHeaders()`.

```php theme={null}
return response('Hello World')
    ->withHeaders([
        'Content-Type' => 'text/plain',
        'X-Custom-Header' => 'MyValue',
        'Cache-Control' => 'no-cache',
    ]);
```

## Ejemplo práctico: elección según la acción del controlador

Ejemplo de uso de respuestas según el caso.

<Steps>
  <Step title="Definir las rutas">
    ```php theme={null}
    use App\Http\Controllers\PostController;

    Route::get('/posts', [PostController::class, 'index'])->name('posts.index');
    Route::get('/posts/create', [PostController::class, 'create'])->name('posts.create');
    Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
    Route::get('/posts/{post}', [PostController::class, 'show'])->name('posts.show');
    Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('posts.destroy');
    ```
  </Step>

  <Step title="Implementar el controlador">
    ```php theme={null}
    <?php

    namespace App\Http\Controllers;

    use App\Models\Post;
    use Illuminate\Http\RedirectResponse;
    use Illuminate\Http\Request;
    use Illuminate\View\View;

    class PostController extends Controller
    {
        // Listar: devuelve una vista
        public function index(): View
        {
            $posts = Post::latest()->get();

            return view('posts.index', ['posts' => $posts]);
        }

        // Formulario de creación: devuelve una vista
        public function create(): View
        {
            return view('posts.create');
        }

        // Guardar: devuelve una redirección
        public function store(Request $request): RedirectResponse
        {
            // Crear con datos validados (si usas una form request)
            $post = Post::create($request->validated());

            return redirect()
                ->route('posts.show', ['post' => $post->id])
                ->with('success', 'Post creado.');
        }

        // Detalle: devuelve una vista
        public function show(Post $post): View
        {
            return view('posts.show', ['post' => $post]);
        }

        // Eliminar: devuelve una redirección
        public function destroy(Post $post): RedirectResponse
        {
            $post->delete();

            return redirect()
                ->route('posts.index')
                ->with('success', 'Post eliminado.');
        }
    }
    ```
  </Step>
</Steps>

<Tip>
  En una aplicación web, la elección básica es entre `View` y `RedirectResponse`. Las acciones de visualización devuelven `View`; las de cambio (crear/actualizar/eliminar) tras procesar devuelven `RedirectResponse`. Es el patrón habitual.
</Tip>

## Próximos pasos

<Card title="Validación" icon="check-circle" href="/es/validation">
  Aprende a validar los datos de entrada antes de devolver la respuesta.
</Card>


## Related topics

- [Ciclo de vida de la solicitud](/es/lifecycle.md)
- [Personalización del rate limiting](/es/advanced/rate-limiting.md)
- [Laravel Chisel — Biblioteca de scripts de post-instalación para starter kits](/es/blog/chisel-introduction.md)
- [Tutorial de bots - Laravel Bluesky](/es/packages/laravel-bluesky/bot-tutorial.md)
- [Crear un servidor MCP con Laravel](/es/advanced/mcp-server.md)
