Будучи членом команды доставки Cloud Elements, я вижу много интеграций; как те, которые мы строим сами (от имени клиентов), так и те, которые строят наши клиенты. И часто, думая об этих интеграциях, я также думаю о том, как мы можем сделать их лучше / быстрее / проще / надежнее-э / т. Д.
Меня особенно тянет к легче. В некоторой степени это потому, что я немного ленив (просто спросите мою жену).
Одним из аспектов программирования, который может показаться, что это больше работы, чем должно быть, является развертывание. Вариантов развертывания почти столько же, сколько и программистов, которые спорят о лучшем из них. Одним из подходов к развертыванию, который обещает облегчить задачу, является безсерверная архитектура или FaaS (функция как услуга). Отказ от выделенного сервера имеет ряд преимуществ — потенциальная экономия затрат, масштабирование по умолчанию, сокращение системного администрирования и упрощение процесса развертывания.
Есть еще ряд вариантов, таких как AWS Lambdas, Google Cloud Functions и Azure Functions. Cloud Elements даже предлагает наш собственный FaaS — средство графического программирования с низким кодом, называемое Формулы , которое может быть отличным выбором для создания интеграции. Я лично использовал Формулы много раз. Но я программист старой школы, которому действительно нравится код, поэтому я ищу способы сделать его столь же простым для создания и развертывания кода, как и для развертывания Формул.
Одна вещь, которая в последнее время заинтересовала меня, — это Serverless Framework . Serverless Framework — это CLI с открытым исходным кодом для создания и развертывания бессерверных приложений. Он поддерживает ряд различных серверных архитектур и обеспечивает в основном унифицированный способ развертывания и тестирования безсерверных приложений. Это также позволяет расширение через механизм плагина . Поэтому было трудно удержаться от создания специального плагина Cloud Elements, чтобы увидеть, насколько он помог сделать мою жизнь проще. Таким образом, этот эксперимент в интеграции родился.
Затем возник вопрос: «Как я хочу, чтобы это работало?» В Serverless Framework есть концепция ресурсов, которые вы определяете, и она управляет ими за вас. Примеры поддерживаемых ресурсов включают (для AWS) таблицы DynamoDB, сегменты S3 и темы SNS. Казалось разумным использовать эту возможность, добавляя типы для Elements (наша идея соединителя для конкретного поставщика, такого как Salesforce, Marketo или DropBox). Когда вы указываете ресурс в файле конфигурации serverless.yml, плагин будет предоставлять Javascript SDK (используя наш инструмент SDKifier ), который может использоваться кодом для доступа к элементу.
В Serverless Framework также есть концепция событий, которые можно настроить и затем доставить в ваш код. Облачные элементы имеют похожую концепцию событий, которые могут быть доставлены из экземпляра. Плагин настроит конечную точку шлюза API для получения события, а затем подключит правильный URL-адрес после развертывания, чтобы экземпляр вызывал код при возникновении событий.
Пример простой синхронизации контактов с указанием кода и файла конфигурации показан ниже.
service: salesforce-finance-contact-sync
provider:
name: aws
runtime: nodejs8.10
plugins:
- serverless-cloud-elements-plugin
functions:
sync:
handler: contactSync.eventHandler
timeout: 30
memorySize: 256
events:
- instance:
resource: sfdc
resources:
Resources:
sfdc:
Type: CE::Element::sfdc
Properties:
id: ${env:SFDC_ID}
dest:
Type: CE::Hub::general
Properties:
id: ${env:DEST_ID}
account:
Type: CE::Account
Properties:
userToken: ${env:USER_TOKEN}
orgToken: ${env:ORG_TOKEN}
baseUrl: ${env:BASE_URL}
const {configurator} = require('./configurator');
async function eventHandler() {
const {trigger, config, done} = configurator(arguments);
for (let event of trigger.events) {
const myContact = await config.sfdc.getObjectNameByObjectId_myContact(event.objectId).run();
if (myContact.Email) {
let foundContacts = await config.dest.getByObjectName('myContact').where(`Email='${myContact.Email}'`).run();
if (foundContacts.length === 1) {
await config.dest.updateObjectNameByObjectId('myContact', foundContacts[0].Id, myContact).run();
console.log(`${foundContacts[0].Id} updated`);
} else {
const newContact = await config.dest.createByObjectName('myContact', myContact).run();
console.log(`${newContact.Id} created`);
}
}
}
done();
}
module.exports.eventHandler = eventHandler;
Если вы хотите поэкспериментировать с этим плагином, вы можете скачать его с помощью npm .
У этого подхода есть ограничения, например, максимальное время выполнения составляет около 5 минут для продуктов FaaS, доступных в настоящее время. У меня есть некоторые мысли по поводу адресации, о которых я расскажу в своем следующем посте, озаглавленном, что неудивительно, «Эксперименты в интеграции», часть 2
Пока что я чувствую, что это перспективное направление, хотя YMMV. Я хотел бы услышать ваши мысли о том, что сложно делать интеграции и что вы думаете, может сделать это проще.
Так что я могу украсть твои идеи.
Потому что я ленивый.