[Программирование, Symfony] Развертывание приложения Symfony в AWS Lambda (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Сначала давайте разберемся, что такое бессерверная архитектура и когда она нужна.Бессерверная архитектура позволяет выполнять фрагменты кода без мороки с инфраструктурой: в этом случае управлением веб-сервером, физическим оборудованием и администрированием занимается облачный провайдер, позволяя вам сосредоточиться исключительно на коде.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". Если интересно узнать о курсе больше, приглашаем на день открытых дверей онлайн, где преподаватель расскажет о формате и программе обучения.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Smaine Milianni
===========Похожие новости:
- [Программирование, Разработка под Android] Онлайн-митап для Android-разработчиков
- [Программирование, Разработка под iOS, Разработка мобильных приложений, Конференции] Анонс эфира live-coding на SwiftUI
- [Java] Кросс-браузерное тестирование в Selenium (перевод)
- [Программирование, .NET, Карьера в IT-индустрии] Возможные неопределенности в карьере программиста. Часть 2
- [Программирование, Учебный процесс в IT] Рабочее место в кафе, улучшение фотографий и команды для хакатонов: выпускные работы наших студентов
- [Микросервисы] Использование микросервисов в работе с Kubernetes и GitOps (перевод)
- [Программирование, Kubernetes] Построение кластеров Kubernetes средствами самого Kubernetes (перевод)
- [JavaScript, Программирование, Angular] Кастомные операторы RxJS (перевод)
- [PHP, JavaScript] Браузерные Push-уведомления на Javascript и PHP
- [Информационная безопасность, Реверс-инжиниринг] Binary Coverage для Reverse Engeneering
Теги для поиска: #_programmirovanie (Программирование), #_symfony, #_symfony_framework, #_aws_lambda, #_serverless, #_solution_architect, #_php, #_blog_kompanii_otus (
Блог компании OTUS
), #_programmirovanie (
Программирование
), #_symfony
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 07:31
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Сначала давайте разберемся, что такое бессерверная архитектура и когда она нужна.Бессерверная архитектура позволяет выполнять фрагменты кода без мороки с инфраструктурой: в этом случае управлением веб-сервером, физическим оборудованием и администрированием занимается облачный провайдер, позволяя вам сосредоточиться исключительно на коде.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'); } } <?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 <?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(); } $ npm install -g serverless
$ serverless config credentials --provider aws --key --secret $ composer require bref/bref 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. Перевод материала подготовлен в рамках курса "Symfony Framework". Если интересно узнать о курсе больше, приглашаем на день открытых дверей онлайн, где преподаватель расскажет о формате и программе обучения.
=========== Источник: habr.com =========== =========== Автор оригинала: Smaine Milianni ===========Похожие новости:
Блог компании OTUS ), #_programmirovanie ( Программирование ), #_symfony |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 07:31
Часовой пояс: UTC + 5