Tempest es un nuevo framework de PHP que combina algunas de las mejores funcionalidades de Laravel y Symfony, ofreciendo una experiencia de desarrollo moderna y eficiente. A la hora de escribir este artículo, Tempest se encuentra en versión alpha, y se espera que muchas de estas características se vayan puliendo y ampliando en futuras versiones.
Sistema de Migraciones de Laravel
Tempest incorpora un sistema de migraciones similar al de Laravel, permitiendo gestionar la estructura de la base de datos de manera programática y versionada. Las migraciones se descubren automáticamente si implementan la interfaz Migration
, facilitando su creación y mantenimiento.
Ejemplo de migración en Tempest:
// app/CreateBookTable.php
use Tempest\Database\Migration;
use Tempest\Database\QueryStatement;
use Tempest\Database\QueryStatements\CreateTableStatement;
use Tempest\Database\QueryStatements\DropTableStatement;
final readonly class CreateBookTable implements Migration
{
public function getName(): string
{
return '2024-08-12_create_book_table';
}
public function up(): QueryStatement|null
{
return CreateTableStatement::forModel(Book::class)
->primary()
->text('title')
->datetime('createdAt')
->datetime('publishedAt', nullable: true)
->integer('author_id', unsigned: true)
->belongsTo('Book.author_id', 'Author.id');
}
public function down(): QueryStatement|null
{
return DropTableStatement::forModel(Book::class);
}
}
Definición de Rutas con Atributos
Al igual que Symfony, Tempest permite definir rutas utilizando atributos en los controladores. Esto simplifica la asignación de rutas a métodos específicos, mejorando la legibilidad y el mantenimiento del código.
Ejemplo de definición de rutas con atributos:
// app/HomeController.php
use Tempest\Http\Get;
use Tempest\View\View;
use function view;
final readonly class HomeController
{
#[Get(uri: '/home')]
public function __invoke(): View
{
return view('home.view.php');
}
}
Validación de Solicitudes en Controladores como en Laravel
Tempest utiliza clases de solicitud para manejar y validar datos entrantes, similar a Laravel. Cada propiedad pública de una clase de solicitud representa un valor enviado desde el cliente, y el framework emplea el sistema de tipos de PHP para validar estos datos, ofreciendo atributos de validación para un control más detallado.
Ejemplo de validación de solicitud:
// app/BookRequest.php
use Tempest\Http\Request;
use Tempest\Http\IsRequest;
use Tempest\Validation\Rules\Length;
final class BookRequest implements Request
{
use IsRequest;
#[Length(min: 10, max: 120)]
public string $title;
public ?DateTimeImmutable $publishedAt = null;
public string $summary;
}
// app/BookController.php
use Tempest\Http\Post;
use Tempest\Http\Responses\Redirect;
use function Tempest\map;
use function Tempest\uri;
final readonly class BookController
{
#[Post(uri: '/books/create')]
public function store(BookRequest $request): Redirect
{
$book = map($request)->to(Book::class)->save();
return new Redirect(uri([self::class, 'show'], id: $book->id));
}
}
Vistas con Blade o Tempest View
Tempest ofrece su propio motor de plantillas, Tempest View, que proporciona una sintaxis limpia y moderna para la creación de vistas. Además, soporta Blade, el motor de plantillas de Laravel, brindando flexibilidad a los desarrolladores que prefieren esta opción.
Ejemplo de vista con Tempest View:
<ul>
<?php foreach ($this->posts as $post): ?>
<li>
<?= $post->title ?>
<?php if($this->showDate($post)): ?>
<span>
<?= $post->date ?>
</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
Modelos Independientes de la Base de Datos
A diferencia de muchos ORMs populares, los modelos en Tempest no están obligatoriamente vinculados a una base de datos. Los datos pueden cargarse desde diversas fuentes como APIs externas, JSON, Redis o XML, lo que proporciona una mayor flexibilidad en la gestión de datos.
Ejemplo de modelo con datos de un fichero JSON:
// app/Book.php
use Tempest\Validation\Rules\Length;
use App\Author;
final class Book
{
public function __construct(
#[Length(min: 1, max: 120)]
public string $title,
public Author $author,
/** @var \App\Chapter[] */
public array $chapters = [],
) {}
}
use function Tempest\map;
map('path/to/books.json')->collection->to(Book::class);
map($book)->to(MapTo::JSON);
Soporte para Páginas Estáticas
Tempest facilita la creación de páginas estáticas de forma sencilla. Al definir las rutas correspondientes, el framework se encarga de obtener y renderizar el contenido dinámicamente, optimizando el desarrollo de este tipo de páginas.
Ejemplo de página estática:
// app/HomeController.php
use Tempest\Http\Get;
use Tempest\Http\StaticPage;
use Tempest\View\View;
use function Tempest\view;
final readonly class HomeController
{
#[StaticPage]
#[Get('/')]
public function home(): View
{
return view('home');
}
}
./tempest static:generate
Roadmap de Desarrollo
La versión 1.0 de Tempest será una versión ligera del framework, con varias funcionalidades útiles aún ausentes. En versiones menores posteriores se irán añadiendo características como la gestión de colas y el soporte de correo:
- Versión 1.1: Autenticación, soporte para htmx, mejora en el soporte de formularios y eventos de la aplicación.
- Versión 1.2: Gestor de colas.
- Versión 1.3: Soporte para correo.
- Versión 1.4: Mejoras en el bus de eventos, posiblemente con soporte para ES.
Si deseas explorar más sobre Tempest, puedes acceder a su repositorio en GitHub: Tempest Framework en GitHub.
Aunque aún se encuentra en una etapa temprana, las promesas de las futuras versiones hacen que Tempest sea un framework a seguir de cerca, y sin duda algo para tener en el punto de mira.
Foto de Layne Lawson en Unsplash