Бессерверная структура позволяет ссылаться на внешние файлы JSON, YML и JS, используя синтаксис ${file:(fileName):propertyName}
. Однако вы не можете настроить эти внешние файлы конфигурации с помощью аргументов времени выполнения.
Читатель спросил меня:
«У меня есть этот шаблон, который многократно повторяется в моем serverless.yml, как мне повторно использовать шаблон, но переопределить только определенные поля?»
Это интересный вопрос, и вот несколько возможных решений.
Заявление об ограничении ответственности: в приведенных ниже примерах источник события HTTP используется с единственной целью проиллюстрировать решения с помощью тривиального объекта конфигурации.
Якоря YML
Самое простое решение - использовать якоря YML. Вы можете определить и применить привязку и переопределить определенные поля. Например:
Если шаблон большой, вы можете поместить его в отдельный файл. К сожалению, я не нашел способа заставить якоря работать с внешними файлами конфигурации в serverless.yml
. Я не могу импортировать содержимое привязки из другого файла (как показано ниже). Пожалуйста, дайте мне знать в комментариях, если вы знаете, что я здесь сделал не так.
Более серьезная проблема с якорями состоит в том, что их сложно заменить вложенными полями. Например, с учетом следующего якоря:
defaultPerson: &defaultPerson location: city: Amsterdam country: Netherlands occupation: title: independent consultant expertise: - serverless - aws
Предположим, я хочу изменить location.city
и вставить новое поле occupation.company
. Посмотрите, что произойдет, если я применю переопределения до и после привязки:
AFAIK, единственный способ сделать эту работу - объявить несколько якорей:
defaultPerson: &defaultPerson location: &defaultLocation city: Amsterdam country: Netherlands occupation: &defaultOccupation title: independent consultant expertise: - serverless - aws Yan: <<: *defaultPerson location: <<: *defaultLocation city: Amstelveen occupation: <<: *defaultOccupation company: theburningmonk ltd
Хотя становится немного беспорядочно.
Объекты JS Proxy
Бессерверный фреймворк также позволяет ссылаться на внешний JS-файл. Но вы можете ссылаться только на свойства, но не вызывать методы. Это затрудняет создание настраиваемой шаблонной конфигурации.
Например, если я хочу создать шаблон для конфигурации источника событий HTTP, но позволяю настраивать метод. В идеале я бы хотел сделать что-то вроде этого:
index: handler: index.handler events: - http: ${file(defaultHttp.js):withMethod("get")} - http: ${file(defaultHttp.js):withMethod("post")}
К сожалению, поскольку я не могу вызывать методы, мне пришлось бы заключить их в свойства, например
const generateConfig = (method) => ({ path: '/', method }); module.exports.get = () => generateConfig('get'); module.exports.post = () => generateConfig('post');
Тогда я смогу сослаться на них в serverless.yml
:
index: handler: index.handler events: - http: ${file(defaultHttp.js):get} - http: ${file(defaultHttp.js):post}
Это двухэтапный процесс. К счастью, с ES6 Proxy мы можем добиться большего!
Мы можем вернуть Proxy
, который блокирует любую попытку доступа к свойству экспортируемого объекта. Имя запрашиваемого свойства (например, get
) используется для создания фактического объекта конфигурации, который мы вернем.
const handler = { get: function (obj, method) { return () => ({ path: '/', method }); } } module.exports = new Proxy({}, handler);
И вот что происходит, когда я ссылаюсь на ${file(xyz.js):get}
:
С помощью этой простой техники я могу создать шаблонную конфигурацию, в которой вы можете настроить поле, даже если оно глубоко вложено. Например:
const handler = { get: function (obj, city) { return () => ({ location: { city, // customize a nested field country: 'Netherlands' }, occupation: { title: "independent consultant", expertise: ["serverless", "aws"] } }); } } module.exports = new Proxy({}, handler);
И импортируйте конфиг вот так:
custom: yan: ${file(defaultPerson.js):Amstelveen}
Но ждать! Могу ли я вставить / обновить свойство в произвольном месте, как в примере defaultPerson
ранее?
Ну да, это можно сделать, вернув еще Proxy
из первого Proxy
.
Например, следующий объект конфигурации позволяет вам обновить path
или method
или вставить новое поле.
const _ = require('lodash'); const template = { path: '/', method: 'get' }; const handler = { get: function (obj, path) { const x = _.cloneDeep(obj); return () => new Proxy(x, { get: function (obj, value) { _.set(obj, path, value); return obj; } }); } } module.exports = new Proxy(template, handler);
Затем вы можете ссылаться на него в serverless.yml
следующим образом:
functions: index: handler: index.handler events: - http: ${file(defaultHttp.js):path./index} - http: ${file(defaultHttp.js):method.post}
При этом конечные точки создаются так, как вы и ожидали:
endpoints: GET -https://xxx.execute-api.us-east-1.amazonaws.com/dev/index POST -https://xxx.execute-api.us-east-1.amazonaws.com/dev/
Вот что происходит, когда я ссылаюсь на ${file(xyz.js}:method.post}
:
Но подождите еще раз! Можете ли вы настроить конфигурацию с более чем одной переменной? Например. что, если я хочу настроить и path
, и method
?
У вас может быть Proxy
, который возвращает другой Proxy
, который возвращает еще Proxy
, и так далее. Возможно, это возможно.
Как предложил Филипп Бо, вы также можете создать схему для поддержки пар "ключ-значение", разделенных запятыми. Например, ${file(xyz.js):key0_value0-key1_value1}
Я оставлю это вам, читатели, в качестве упражнения. Дайте волю своему воображению и дайте мне знать, какие практические проблемы вы пытаетесь решить. (Я люблю хорошие хаки, но решение реальных проблем всегда приносит больше удовольствия ;-))
Привет, меня зовут Ян Цуй. Я AWS Serverless Hero и автор книги Production-Ready Serverless. Я выполнял масштабную производственную нагрузку в AWS почти 10 лет, и я был архитектором или главным инженером в различных отраслях, от банковского дела, электронной коммерции, спортивных трансляций до мобильных игр. В настоящее время я работаю независимым консультантом, специализирующимся на AWS и бессерверных технологиях.
Вы можете связаться со мной через Электронная почта, Twitter и LinkedIn.
Ознакомьтесь с моим новым курсом Полное руководство по AWS Step Functions.
В этом курсе мы расскажем все, что вам нужно знать, чтобы эффективно использовать сервис AWS Step Functions. Включая базовые концепции, HTTP и триггеры событий, действия, шаблоны проектирования и передовые методы.
Получите свой экземпляр здесь.
Узнайте об операционных ЛУЧШИХ ПРАКТИКАХ для AWS Lambda: CI / CD, локальные функции тестирования и отладки, ведение журнала, мониторинг, распределенная трассировка, стандартные развертывания, управление конфигурацией, аутентификация и авторизация, VPC, безопасность, обработка ошибок , и больше.
Вы также можете получить скидку 40% от номинальной стоимости, используя код ytcui.
Получите свой экземпляр здесь.
Первоначально опубликовано на https://theburningmonk.com 5 августа 2019 г.