Aplicação Serverless desenvolvida em PHP usando AWS Lambda

Se você não está familiarizado com o conceito, recomendo a leitura do artigo “Serverless: uma introdução“, que introduz os pilares dessa forma de utilizar a computação em nuvem.

PHP Básico
Curso de PHP Básico
CONHEÇA O CURSO

Bref

O Bref é uma ferramenta que permite publicarmos aplicações PHP serverless no AWS Lambda.

Para rodar o PHP no Lambda o Bref usa AWS Lambda Layers, uma nova API da AWS que permite que qualquer linguagem seja executada. O Bref intermedia e tira a complexidade dessa integração para que possamos nos preocupar em apenas desenvolver o nosso código.

O Bref utiliza Serverless Framework, um framework para gerenciamento, teste e publicação de funções nas principais plataformas FaaS do mercado.

Daqui pra frente trabalharemos com:

  • Terminal;
  • PHP (é necessário que você tenha conhecimento ao menos intermediário em PHP e que também tenha o Composer instalado na sua máquina);
  • NodeJS (O Serverless Framework funciona sob o NodeJS, então é necessário tê-lo instalado no seu ambiente);
  • AWS (é necessário ter uma conta na AWS para a publicação da aplicação, pois o Bref funciona apenas na AWS nesse momento);

Se você ainda não tem uma conta na AWS, você pode criar uma clicando aqui e utilizá-la por 1 ano de forma gratuita (mas com alguns limites) a maioria dos serviços. No caso do AWS Lambda, a conta gratuita permite que façamos muitas requisições por mês de forma grátis, o que é suficiente para que implementamos nossas primeiras funções sem ter nenhum gasto com isso.

Criando um usuário na AWS

Se você já criou a sua conta na AWS, agora é a hora de termos uma chave de acesso, chave esta que será usada pelo Serverless Framework no deploy da função.

Vamos criar um usuário, pro nosso exemplo didático, chamado serverless-admin. Você deve usar o serviço IAM para criar esse usuário:

https://console.aws.amazon.com/iam/home?region=sa-east-1#/users

Em “Access type” escolha a opção “Programmatic access“:

Na próxima tela, vou dar permissão de administrador para esse usuário. Veja bem, essa chave de acesso estará disponível apenas no meu ambiente. Na vida real, usuários devem ter permissões bem mais “magras”, com apenas o que for suficiente para que desempenhem suas funções.

Basta avançar e depois concluir a criação do usuário:

Guarde a Access key ID e a Secret access key, pois as utilizaremos daqui a pouco.

Instalando o Serverless Framework

O primeiro passo é instalar o Serverless Framework. É necessário que você tenha NodeJS e NPM instalados no seu ambiente:

$ npm install -g serverless

Depois, é hora de configurar nele as chaves que geramos anterior na AWS:

$ serverless config credentials --provider aws --key <access key id> --secret <secret access key>

Basta que você substitua os placeholders e pelas chaves geradas no passo anterior.

Se tudo ocorrer bem, você receberá no terminal:

Serverless: Setting up AWS...

Criando a aplicação

Na sua pasta preferida, onde você desenvolve os seus projetos, crie uma nova pasta chamada cep-serverless. Dentro dela, pelo terminal, execute:

$ composer require bref/bref "^0.5"

Isso instalará o Bref como dependência do projeto.

Nota: O foco do artigo está no uso da versão 0.5 do Bref, futuras versões podem ter quebras de compatibilidade.

Em seguida, rode o comando que inicializará o template padrão do Bref na pasta que acabamos de criar:

$ vendor/bin/bref init

A ferramenta perguntará que tipo de aplicação estamos desenvolvendo. Vamos escolher a opção 1, pois a ideia aqui é a gente expor uma API pública e aberta de consulta de cep e essa opção nos permitirá criar uma aplicação que use, por exemplo, o Slim, para responder às requisições:

 What kind of lambda do you want to create? (you will be able to add more functions later by editing `serverless.yml`) [PHP function]:
  [0] PHP function
  [1] HTTP application
  [2] Console application

Se tudo der certo, o resultado será:

[OK] Project initialized and ready to test or deploy.

Não ignore a documentação oficial, ela possui muitos insights sobre todo o processo. Por exemplo, leia também a seção que explica aplicações HTTP no Bref, que é o tipo que estamos usando.

Na raiz do projeto, abra o arquivo template.yaml. É nesse arquivo que temos todas as configurações usadas pelo Serverless Framework para o deploy da nossa aplicação.

Primeiro de tudo, alterei o nome da aplicação de app :

service: app

Para:

service: cep

Em layers temos:

${bref:layer.php-73-fpm}

Como o AWS Lambda não tem suporte nativo ao PHP, o Bref usa a API AWS Lambda Layers para executar o código numa compilação do PHP (mantida pelo próprio Bref), como pode ser visto na seção Runtimes da documentação.

PHP Intermediário
Curso de PHP Intermediário
CONHEÇA O CURSO

Altere a linha:

region: us-east-1

Para a região de São Paulo:

region: sa-east-1

Outra propriedade que podemos alterar desde já é o nome da função, que por padrão é:

functions:
    api:
        handler: index.php

Podemos alterar para:

functions:
    consulta:
        handler: index.php

O arquivo a ser executado quando a função for invocada é definido na propriedade handler:

handler: index.php

As requisições HTTP passarão pelo API Gateway. Igual explicamos no artigo Serverless: uma introdução, as lambdas são invocadas por eventos e uma requisição HTTP é um evento que no API Gateway pode disparar a execução de uma lambda. É essa a dinâmica que a nossa aplicação terá.

Em events configuramos quais são os eventos que vão disparar a nossa Lambda. Por padrão, temos:

        events:
            -   http: 'ANY /'
            -   http: 'ANY /{proxy+}'

Essa configuração padrão faz com que qualquer requisição de qualquer método (GET, POST etc) seja enviada para a nossa função. Mas a nossa aplicação didática será simples e bem específica, queremos que apenas um endpoint funcione:

GET /cep/{cep}

Portanto, altere events para:

        events:
            -   http: 'GET /cep/{cep}'

A configuração final ficará assim:

service: cep

provider:
    name: aws
    region: sa-east-1
    runtime: provided

plugins:
    - ./vendor/bref/bref

functions:
    consulta:
        handler: index.php
        description: ''
        timeout: 30
        layers:
            - ${bref:layer.php-73-fpm}
        events:
            -   http: 'GET /cep/{cep}'

Agora é hora da gente desenvolver o protótipo da aplicação.

Respondendo à consulta do CEP

Vamos usar o Slim (micro framework PHP) para responder à requisição do CEP. Mas poderíamos usar qualquer framework ou library do ecossistema PHP. Como usamos o Composer, poderíamos, inclusive, ter uma estrutura padrão MVC de uma aplicação configurada.

Na raiz do projeto, execute:

$ composer require slim/slim "^3.0"

Altere o index.php para:

<?php

declare(strict_types=1);

use Slim\Http\Response;
use Psr\Http\Message\ServerRequestInterface as Request;

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

$slim = new Slim\App();

$slim->get('/cep/{cep}', function (Request $request, Response $response) {
    return $response->withJson([
        'cep' => $request->getAttribute('cep'),
        'rua' => 'Rua do Cruzeiro',
        'bairro' => 'Cruzeiro',
        'cidade' => 'Belo Horizonte',
        'uf' => 'MG',
    ]);
});

$slim->run();

O intuito principal do nosso projeto é o deploy de uma função no AWS Lambda. A nossa aplicação vai sempre retornar o mesmo endereço, mas poderíamos ter desenvolvido uma forma de extrair tais dados a partir do site dos Correios, por exemplo. Mas não é o escopo do artigo chegar na implementação propriamente dita.

Testando a aplicação:

Como a nossa aplicação é bem simples, tudo o que precisamos para testá-la é iniciar o servidor embutido do PHP:

$ php -S localhost:8000 index.php

E então no navegador acessá-la:

http://localhost:8000/cep/32685000 

Deploy no AWS Lambda

O Deploy é a parte mais simples de todas. Primeiro, o ideal é que forcemos o Composer a gerar o autoloader de forma otimizada:

$ composer install --optimize-autoloader --no-dev

Por fim, tudo o que precisamos fazer é executar:

$ serverless deploy

Se tudo ocorrer bem, você terá um resultado parecido com esse:

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service cep.zip file to S3 (3.57 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.................................
Serverless: Stack update finished...
Service Information
service: cep
stage: dev
region: sa-east-1
stack: cep-dev
resources: 11
api keys:
  None
endpoints:
  GET - https://tcs1o1xp65.execute-api.sa-east-1.amazonaws.com/dev/cep/{cep}
functions:
  consulta: cep-dev-consulta
layers:
  None
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.

Ele também já exibe o endpoint que deve ser usado:

endpoints:
  GET - https://tcs1o1xp65.execute-api.sa-east-1.amazonaws.com/dev/cep/{cep}

Por exemplo:

Você pode gerenciar a função pelo console do AWS Lambda.

PHP Avançado
Curso de PHP Avançado
CONHEÇA O CURSO

Concluindo

Se você se interessou pelo Bref, fique sempre atento ao Github do projeto e à documentação dele, principalmente. Na documentação tem muitos detalhes importantes que não estão documentados nesse artigo.

Até os próximos artigos sobre o assunto!

Deixe seu comentário
Share

Head de desenvolvimento. Vasta experiência em desenvolvimento Web com foco em PHP. Graduado em Sistemas de Informação. Pós-graduando em Arquitetura de Software Distribuído pela PUC Minas. Zend Certified Engineer (ZCE) e Coffee Addicted Person (CAP). @KennedyTedesco