Наше стремление найти 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 вносит мир в хаос, наша команда по разработке контента довольна, а мы счастливы, беспроигрышный вариант!