Наше стремление найти CMS без головы, чтобы угодить команде разработчиков контента и команде разработчиков.
Почему Airtable
Airtable - это онлайн-сервис, который понравился Google Sheet, который имеет мощь базы данных и электронную таблицу. В нем есть все возможности гибкой реляционной модели данных и многое другое, где мы можем добавлять поля для вложений, длинные текстовые заметки, флажки, раскрывающиеся списки и ссылки.
Airtable поставляется с простым в использовании графическим интерфейсом и REST API, что позволяет нам создавать, читать, обновлять и уничтожать записи графически и программно. Вот почему Airtable часто является хорошей автономной CMS для небольшого проекта.
Проблемы
Не настоящая база данных
Очевидно, что Airtable - это не «настоящая база данных», поэтому мы не можем писать SQL для запроса данных и объединения таблиц. У него есть простая функция резервного копирования, но это далеко не то, что может быть для репликации базы данных и ведения журнала транзакций.
Ограничение скорости
Его REST API также имеет ограничение в 5 запросов в секунду, что может быть легко достигнуто при высоком трафике.
Мы используем Airtable в качестве CMS / базы данных для сайта с курируемым контентом Staycation, который ежедневно просматривает 40 000 страниц. Теперь предположим, что для каждого просмотра страницы необходимо 5 запросов к Airtable, нам нужно сделать в общей сложности 200 000 запросов к Airtable!
Разрешение доступа немного суетливо
В Airtable у каждого пользователя может быть только один ключ доступа к API. И у него есть полный доступ ко всем вашим базам и записям Airtable. Чтобы получить более качественные и ограниченные права доступа, вам нужно будет создать нового пользователя (то есть вам также нужно будет заплатить за дополнительные места, если вы выберете платный план, что мы делаем) и назначить ему особые разрешения.
Чтобы избежать потенциальных проблем с безопасностью, мы никогда не используем ключ доступа к API на стороне клиента. Мы делаем это только на сервере.
Решение
Чтобы решить проблемы, с которыми мы столкнулись, мы придумали идею создания прокси-службы для прокси-сервера всех наших запросов в Airtable.
Первая попытка с Nginx
Наша первая попытка - разработать прокси с Nginx. Мы написали простой Dockerfile, добавили собственный прокси Nginx и конфигурацию ограничения скорости.
Это вроде как работает, он может кэшировать данные из Airtable, но в итоге мы ограничили скорость самостоятельно, а не Airtable.
Вторая попытка с NodeJS
На этот раз мы используем ExpressJS и библиотеку NodeJS от Airtable. JS-библиотека Airtable поставляется со встроенной логикой для управления ограничением скорости, и это одна из решаемых проблем.
Для кеширования мы реализуем очень простую службу кеширования памяти. Видимо, здесь не нужна никакая библиотека, просто простой класс с 30 строками кода.
Для гибкости и простоты настройки он использует файл конфигурации для определения маршрутизации, базу Airtable, таблицу и таблицу просмотра, фильтр, какие поля нужно получить, поля и даже настраиваемую функцию сопоставления полей.
А вот реальный код для получения данных из Airtable с помощью библиотеки Airtable NodeJS.
И репозиторий находится здесь:
Наши варианты использования
Управляя сайтом с тщательно подобранным контентом, мы выполняем множество функций фильтрации и сортировки контента по нашим данным Airtable. Вместо того, чтобы выполнять выборку и фильтрацию на стороне клиента, мы делаем это на сервере и кэшируем их. Для простоты настройки мы определяем их в нашем airtableConfig.ts
файле конфигурации.
Скажем, если мы хотим получить избранные отели из нашего Airtable, мы создадим следующую конфигурацию:
export const airtableConfigs: Array<AirtableConfig> = [ { route: "hotels-featured", base: "app123456", table: "Hotels", filter: "Status = 'Featured'", fields: [ 'ID', 'Name', ], }, ];
Чтобы получить отфильтрованные и проксированные данные, просто отправьте GET
запрос на /hotels-featured
.
Более сложную логику можно также реализовать, используя filter
и fieldMappings
. Например, мы можем сделать что-то вроде этого:
export const airtableConfigs: Array<AirtableConfig> = [ { route: "users", base: "app123456", table: "Table Name", filter: "Status = 'Approved'", fields: [ 'ID', 'First Name', 'Last Name', 'Age', ], fieldMappings: ((records: any[]) => { return records.map( (record: any) => { return { id: record.ID, name: `${record['First Name']} ${record['Last Name']}`, gea: record.Age, } }) }), }, ]
Мы также хотели, чтобы наш прокси-сервер возвращал данные как можно быстрее, поэтому даже если срок действия кеша истечет, он все равно будет сначала обслуживать истекший кеш, а затем пытаться получить данные из Airtable и кешировать в фоновом режиме.
Лучшее из обоих миров
Перед тем, как перейти на Airtable, мы изучали такие возможности, как Laravel Nova, чтобы сократить время разработки и создать CMS, простую в использовании для нашей контент-команды, но в то же время достаточно мощную и быструю для обслуживания API-интерфейсов для наших веб-сайтов.
Да, Laravel + Nova - это мощный инструмент с точки зрения разработчика, но для команды контента управлять большими объемами данных - кошмар. Им также не имеет смысла думать и обрабатывать данные «реляционно», поскольку пользовательский интерфейс по умолчанию им слишком сложно управлять.
Переход на Airtable вносит мир в хаос, наша команда по разработке контента довольна, а мы счастливы, беспроигрышный вариант!