Implementación de una aplicación Symfony en AWS Lambda

Primero, comprendamos qué es una arquitectura sin servidor y cuándo se necesita.





La arquitectura sin servidor le permite ejecutar fragmentos de código sin la molestia de la infraestructura: en este caso, el proveedor de la nube se encarga de la gestión del servidor web, el hardware físico y la administración, lo que le permite centrarse únicamente en el código.





AWS Lambda , . , cron-, , API, - . . .





 

API, Symfony, LinkedIn. .





 

Symfony 5- Notifier, (Slack, Twitter, Twilio .).





Symfony LinkedIn, Notifier . , .









$ symfony new --full aws-lambda-linkedin-notifier
$ cd aws-lambda-linkedin-notifier
$ composer require eniams/linkedin-notifier
      
      



(. )





<?php
// config/bundles.php
return [
// others bundles,
Eniams\Notifier\LinkedIn\LinkedInNotifierBundle::class => ['all' => true]];
// .env
LINKEDIN_DSN=
      
      








<?php

class PostContentController
{
    /**
     * @Route("/contents", name="post_content", methods="POST")
     */
    public function __invoke(NotifierInterface $notifier, Request $request)
    {
        if(null !== $message = (\json_decode($request->getContent(), true)['message'] ?? null)) {
            $notifier->send(new Notification($message, ['chat/linkedin']));
            return new JsonResponse('message posted with success', 201);
        }

        throw new BadRequestException('Missing "message" in body');
    }
}
      
      



: API /contents



, POST message



.





11- LinkedIn — Symfony !





, :






<?php
class PostContentControllerTest extends WebTestCase
    /**
     * @dataProvider methodProvider
     */
    public function testANoPostRequestShouldReturnA405(string $method)
    {
        $client = static::createClient();

        $client->request($method, '/contents');

        self::assertEquals(405, $client->getResponse()->getStatusCode());
    }

    public function testAPostRequestWithoutAMessageInBodyShouldReturnA400()
    {
        $client = static::createClient();

        $client->request('POST', '/contents');

        self::assertEquals(400, $client->getResponse()->getStatusCode());
    }

    public function testAPostRequestWithAMessageInBodyShouldReturnA201()
    {
        $request = new Request([],[],[],[],[],[], json_encode(['message' => 'Hello World']));

        $notifier = new class implements NotifierInterface {
            public function send(Notification $notification, Recipient ...$recipients): void
            {
            }
        };

        $controller = new PostContentController();
        $response = $controller->__invoke($notifier, $request);

        self::assertEquals(201, $response->getStatusCode());
    }

    public function methodProvider()
    {
        return [
            ['GET'],
            ['PUT'],
            ['DELETE'],
        ];
    }
view rawTestPostContentController.php hosted with ​ by GitHub
      
      



!  

! ?! AWS Lambda PHP!





: AWS Lambda , , Go, Java, Python, Ruby, NodeJS .NET.





? , !





(Matthieu Nappoli), Bref.sh, ,





Bref PHP- AWS AWS Lambda.









kernel.php :





<?php
    // Kernel.php
    public function getLogDir(): string
    {
        if (getenv('LAMBDA_TASK_ROOT') !== false) {
            return '/tmp/log/';
        }

        return parent::getLogDir();
    }

    public function getCacheDir()
    {
        if (getenv('LAMBDA_TASK_ROOT') !== false) {
            return '/tmp/cache/'.$this->environment;
        }

        return parent::getCacheDir();
    }
      
      



Serverless (. ):





$ npm install -g serverless
$ serverless config credentials --provider aws --key  --secret
$ composer require bref/bref
      
      



serverless.yaml:





service: notifier-linkedin-api

provider:
    name: aws
    region: eu-west-3
    runtime: provided
    environment: # env vars
        APP_ENV: prod
        LINKEDIN_DSN: YOUR_DSN


plugins:
    - ./vendor/bref/bref

functions:
    website:
        handler: public/index.php # bootstrap 
        layers:
            - ${bref:layer.php-73-fpm} # https://bref.sh/docs/runtimes/index.html#usage 
        timeout: 28 # Timeout to stop the compute time
        events:
            - http: 'POST /contents' # Only POST to /contents are allowed

package:
    exclude:
        - 'tests/**'
view rawserverless.yaml hosted with ​ by GitHub
      
      



!





$ serverless deploy
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service notifier-linkedin-api.zip file to S3 (10.05 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
....................
Serverless: Stack update finished...
Service Information
service: notifier-linkedin-api
stage: dev
region: eu-west-3
stack: notifier-linkedin-api-dev
resources: 15
api keys:
  None
endpoints:
  POST - https://xxx.execute-api.eu-west-3.amazonaws.com/dev/contents
functions:
  website: notifier-linkedin-api-dev-website
layers:
  None
Serverless: Removing old service artifacts from S3...
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
      
      



AWS Lambda, API https://xxx.execute-api.eu-west-3.amazonaws.com/dev/contents



.





:






"Symfony Framework". , , .








All Articles