4 min. de lectura (aproximado)

Tutorial completo: aws lambda con bref y PHP

AWS Lambda es un servicio de serverless proporcionado por Amazon Web Services, AWS. que permite ejecutar código sin necesidad de aprovisionar, configurar ni administrar servidores.

Requisitos previos

Se necesitas tener instalado

  • PHP 8.2+.
  • Composer.
  • Node.js, para Serverless Framework.
  • Cuenta de AWS configurada.
Instalar las herramientas globales:

npm install -g serverless
composer global require bref/bref   # opcional

Crear el proyecto base

mkdir proyecto-lambda
cd proyecto-lambda
composer require bref/bref
Crear el archivo "serverless.yml".

Ejemplos

Ejemplo 1: Un solo fichero PHP

Estructura

proyecto-lambda/
├── index.php
└── serverless.yml

index.php


<?php
echo "¡Hola desde AWS Lambda! - " . date('Y-m-d H:i:s');

serverless.yml

service: mi-proyecto-lambda

provider:
  name: aws
  region: us-east-1
  stage: dev

plugins:
  - ./vendor/bref/bref

functions:
  web:
    handler: index.php
    runtime: php-84-fpm
    events:
      - httpApi: '*'

Desplegar


serverless deploy
Al terminar se mostrará dará una URL. Abrirla en el navegador y se mostrará en el navegador

Ejemplo con dos funciones

Ahora se quieren dos endpoints distintos:
  • /fecha: muestra la fecha.
  • /mensaje: muestra un mensaje.

Estructura:

├── fecha.php
├── mensaje.php
└── serverless.yml

fecha.php

header('Content-Type: application/json');
echo json_encode([
    'fecha' => date('Y-m-d H:i:s'),
    'timestamp' => time()
]);

mensaje.php

header('Content-Type: application/json');
echo json_encode([
    'mensaje' => '¡Hola desde la segunda función Lambda!',
    'php_version' => PHP_VERSION
]);

serverless.yml

service: proyecto-lambda

provider:
  name: aws
  region: us-east-1

plugins:
  - ./vendor/bref/bref

functions:
  fecha:
    handler: fecha.php
    runtime: php-84-fpm
    events:
      - httpApi: 'GET /fecha'

  mensaje:
    handler: mensaje.php
    runtime: php-84-fpm
    events:
      - httpApi: 'GET /mensaje'

Desplegar y acceder

serverless deploy
Las urls serán:
  • https://xxxxx.execute-api.us-east-1.amazonaws.com/fecha
  • https://xxxxx.execute-api.us-east-1.amazonaws.com/mensaje

Proyecto completo

Estructura

mi-api/
├── public/
│   └── index.php          ← punto de entrada
├── src/
│   ├── Controllers/
│   │   ├── FechaController.php
│   │   └── MensajeController.php
│   └── Router.php
├── composer.json
└── serverless.yml

public/index.php

require __DIR__ . '/../vendor/autoload.php';

use App\Router;

$router = new Router();
$router->dispatch($_SERVER['REQUEST_URI']);

src/Router.phpphp

<?php
namespace App;

class Router
{
    public function dispatch(string $uri)
    {
        $path = parse_url($uri, PHP_URL_PATH);

        match ($path) {
            '/fecha'   => (new Controllers\FechaController())->handle(),
            '/mensaje' => (new Controllers\MensajeController())->handle(),
            default    => $this->notFound()
        };
    }

    private function notFound()
    {
        http_response_code(404);
        echo json_encode(['error' => 'Ruta no encontrada']);
    }
}

src/Controllers/FechaController.php

namespace App\Controllers;

class FechaController
{
    public function handle()
    {
        header('Content-Type: application/json');
        echo json_encode([
            'fecha' => date('Y-m-d H:i:s'),
            'timezone' => date_default_timezone_get()
        ]);
    }
}

src/Controllers/MensajeController.phpphp

namespace App\Controllers;

class MensajeController
{
    public function handle()
    {
        header('Content-Type: application/json');
        echo json_encode([
            'mensaje' => 'Bienvenido a mi API en Lambda',
            'autor' => 'Tu Nombre'
        ]);
    }
}

serverless.yml

service: mi-api

provider:
  name: aws
  region: us-east-1
  environment:
    APP_ENV: production

plugins:
  - ./vendor/bref/bref

functions:
  api:
    handler: public/index.php
    runtime: php-84-fpm
    timeout: 28
    events:
      - httpApi: '*'

package:
  patterns:
    - '!tests/**'
    - '!.git/**'
    - '!node_modules/**'

Ejemplo con parámetros

saludo.php

// Obtenemos los parámetros de la URL
$nombre = $_GET['nombre'] ?? 'Invitado';
$edad   = $_GET['edad'] ?? null;

// Respuesta
header('Content-Type: application/json');

echo json_encode([
    'mensaje' => "¡Hola $nombre!",
    'edad'    => $edad,
    'fecha'   => date('Y-m-d H:i:s')
], JSON_UNESCAPED_UNICODE);

serverless.yml

service: LambdaService

provider:
  name: aws
  region: us-east-1

plugins:
  - ./vendor/bref/bref

functions:
  saludo:
    handler: saludo.php
    runtime: php-84-fpm
    events:
      - httpApi: 'GET /saludo'

Deplegar

serverless deploy
Abrir la siguiente url en el navegador: https://xxxxx.execute-api.us-east-1.amazonaws.com/saludo?nombre=Carlos&edad=28