hefestoapicontainer

Base de datos (PostgreSQL + PostGIS)

Cada API tiene su propia base de datos PostgreSQL aislada del resto. Esto significa que no puedes acceder a la BD de otra API directamente; debes usar conexiones HTTP locales para comunicarte entre APIs.

Endpoints de gestión

Añade estos endpoints a tu api.yaml para gestionar la base de datos:

  delete /database:
    Drop:
      directive: DatabaseDrop
  post /database:
    Create:
      directive: DatabaseCreate
    Connect:
      directive: DatabaseConnect
    Migrate:
      directive: DatabaseMigrate
      files: "Assets/sql/"
  post /database/migrate:
    Connect:
      directive: DatabaseConnect
    Migrate:
      directive: DatabaseMigrate
      files: "Assets/sql/"

Migraciones SQL

Las migraciones son ficheros SQL en Assets/sql/ con nombres como:

001_create_table_users.sql
002_create_table_companies.sql
003_create_index_name_to_users.sql

Los ficheros se ejecutan en orden alfabético. Solo se ejecutan una vez; Hefesto lleva un registro de las migraciones ejecutadas en una tabla migrations.

Ejemplo de 001_create_table_users.sql:

CREATE TABLE users (
    id VARCHAR ( 120 ) PRIMARY KEY,
    name VARCHAR ( 120 ) NOT NULL,
    email VARCHAR ( 255 ) UNIQUE NOT NULL,
    created_at TIMESTAMP NOT NULL
);

Conexión y consultas

Para conectar a la base de datos desde cualquier endpoint, usa la directiva DatabaseConnect. Esto almacena la conexión PDO en memory con la clave db-conn:

post /user:
  LoadUser:
    directive: LoadAndValidateModel
    source: $.message.bodyAsArray
    target: user
  Connect:
    directive: DatabaseConnect
  SaveUser:
    directive: SaveUser
    user: $.memory.user

Dentro de la directiva SaveUser (personalizada), la conexión se usa así:

$db = $state->memory()->get('db-conn');

$sth = $db->prepare('SELECT id FROM users WHERE name = ?');
$sth->execute([$user['name']]);
$data = $sth->fetchObject();

if (!isset($data->id)) {
    $sth = $db->prepare(
        'INSERT INTO users (id, name, email, created_at) 
         VALUES (?, ?, ?, NOW())'
    );
    $sth->execute([
        uniqid('user_', true),
        $user['name'],
        $user['email']
    ]);
}

La conexión recuperada es un objeto PDO estándar de PHP, por lo que puedes usar todos los métodos de PDO.

Transacciones

Puedes agrupar varias operaciones en una transacción usando DatabaseBeginTransaction y DatabaseCommitTransaction:

post /order:
  LoadOrder:
    directive: LoadAndValidateModel
    source: $.message.bodyAsArray
    target: order
  Connect:
    directive: DatabaseConnect
  Begin:
    directive: DatabaseBeginTransaction
  SaveOrder:
    directive: SaveOrder
  UpdateStock:
    directive: UpdateStock
  Commit:
    directive: DatabaseCommitTransaction

Si cualquier directiva entre Begin y Commit lanza una excepción, la transacción se deshace automáticamente (rollback implícito por PDO al destruirse la conexión).

PostGIS

Hefesto incluye la extensión PostGIS . Puedes habilitarla ejecutando la siguiente sentencia SQL en una migración:

CREATE EXTENSION postgis;

Una vez habilitada, puedes usar tipos de datos geográficos (GEOMETRY, GEOGRAPHY), índices espaciales, consultas de distancia, etc.