В этом туториале мы реализуем ~~Real World App~~ — подписку на обновления с помощью гугл таблиц, бессерверных функций и реакта. Основной функционал нашего приложения будет следующим: Дополнительный функционал: В первой части туториала мы реализуем основной функционал, во второй — дополнительный. Сначала мы реализуем основной функционал локально, затем развернем приложение на Netlify (в данном случае мы ограничены этим хостингом, поскольку от него зависит ключевой функционал приложения) и будет его постепенно дорабатывать. Демо приложения, которое мы создадим, можно посмотреть здесь (оно вполне работоспособное, если хотите, можете подписаться на обновления). Код приложения находится здесь. Для реализации приложения мы будем использовать следующие технологии: Разумеется, на вашей машине должен быть установлен Node.js и, желательно, yarn (после того, как вы поработаете с этим пакетным менеджером, вы едва ли вернетесь к npm). Также будьте готовы к тому, что придется создать несколько аккаунтов и, возможно, кое-что погуглить в случае, если я забуду об этом упомянуть в туториале (постараюсь этого не делать). Надеюсь, мне удалось вас заинтриговать, и вы с нетерпением ждете, когда мы начнем писать код. Скоро, но сначала давайте создадим и настроим таблицу, а также свяжем ее с Google Cloud Platform. Заходим в Google Cloud Platform (по ссылке, приведенной выше) и выполняем следующие действия: .  .  .  .  .  .  .  .  .  .  .  .  .  Заходим в Google Speadsheets и создаем новую таблицу (Пустой файл) с двумя графами: username и email. .  Открываем настройки доступа, находим созданный нами сервис-аккаунт и добавляем его в качестве Редактора. .  В поисковой строке между d/ и /edit находится идентификатор таблицы, также где-нибудь его сохраните. На этом настройка нашей таблицы завершена. Приложение, реализацией которого мы занимаемся, представляет собой отличный пример использования бессерверных вычислений: нам не нужен полноценный сервер, мы всего лишь хотим отправлять данные из заполненной пользователем формы в гугл таблицу, читать эти данные и рассылать уведомления подписчикам. Netlify Functions — это лишь один из вариантов использования AWS Lambda Functions для выполнения такого рода задач. О том, что такое Netlify Functions, можно почитать здесь. Функции, как правило, размещаются в директории functions в корне проекта. Создаем новый React-проект (mail-list — название нашего проекта): Пьем чай в ожидании завершения создания проекта, переходим в созданную директорию и устанавливаем необходимые зависимости: В корне проекта создаем файл .env (touch .env) и записываем в него сохраненные данные в следующем формате: Создаем директорию functions, переходим в нее, создаем файл subscribe.js и открываем его в редакторе кода: В данном файле мы получаем доступ к сервис-аккаунту, загружаем таблицу, получаем данные от клиента (имя и адрес электронной почты пользователя) и записываем эти данные в таблицу. Перед записью данных пользователя, мы проверяем, что указанный пользователем email отсутствует в таблице. Если это не так, то мы сообщаем пользователю, что он уже подписан на обновления. Бессерверные функции имеют такую сигнатуру: Если очень коротко, то event, как было отмечено ранее, это объект запроса (данные, поступающие от клиента), context — любая дополнительная информация, связанная с запросом, например, статус пользователя, callback нужен в случае синхронной (блокирующей) функции для возврата ответа (мы используем асинхронную функцию, поэтому нам данный аргумент не нужен, впрочем, как и аргумент context). Что касается этих заголовков ответа: То они связаны с внутренними настройками Netlify (с выполняемыми перенаправлениями при обращении к функции из клиента). Перенаправления блокируются CORS (Cross-Origin Resource Sharing — доступ к ресурсу из другого источника), потому что бессерверные функции не совсем бессерверные, под капотом они работают на основе централизованного сервера. Эти заголовки не требуются для локальной разработки, но развернуть приложение на хостинге без них не получится. В официальной документации про это ни слова. Возможно, к тому моменту, когда вы будете читать данную статью, этот недостаток будет устранен. Следует отметить, что эти заголовки можно указать для всех ответов в файле netlify.toml. Итак, мы реализовали функцию для подписки на обновления. Вторую функцию мы реализуем позже, когда выясним, какие данные нам для этого нужны, как нам получить эти данные на клиенте и передать их в функцию. Устанавливаем зависимости для клиента: Код клиента находится в директории src. Удаляем из нее лишние файлы (оставляем только index.js и index.css), создаем директорию pages для страниц и hooks для пользовательских хуков. В директории pages создаем следующие файлы: В директории hooks создаем три файла: Структура директории src: В index.css мы подключаем кастомный шрифт и вносим небольшие правки в стили semantic-ui: В index.js мы импортируем компоненты приложения и реализуем разделение кода на уровне маршрутов с помощью lazy и Suspense: Рассмотрим, что из себя представляют пользовательские хуки. Хук useDeferredRoute добавляет искусственную задержку при начальной загрузке приложения и переходе пользователя к другой странице. Это совершенно не обязательно, возможно, кто-то даже скажет, что это плохая практика, но мне показалось, что так приложение будет более "живым". Кроме того, не так давно при работе над одним из проектов я столкнулся с необходимостью скрытия от пользователя позиционирования элементов фона отрендеренного компонента через искусственную задержку отображения компонента (вот где бы пригодился хук useTransition, но он пока еще экспериментальный). Хук useTimeout, как было отмечено, это всего лишь обертка над нативным setTimeout: А вот как выглядит hooks/index.js: Теперь займемся страницами. В Home.js нет ничего особенного. После скрытия индикатора загрузки, мы приветствуем пользователя и предлагаем ему подписаться на (кнопка "Подписаться" — это на самом деле ссылка на страницу Subscribe): В Success.js также нет ничего особенного. После скрытия индикатора загрузки, мы благодарим пользователя за подписку и выполняем автоматическое перенаправление на главную страницу через 3 секунды с помощью нашего хука useTimeout. На случай, если автоматического перенаправления не произошло, имеется кнопка-ссылка на страницу Home: Еще одна простая страница — NotFound — пользователь попадает на эту страницу при отсутствии совпадения с маршрутами приложения: На странице Subscribe используется компонент react-google-recaptcha, которому в качестве пропа передается ключ сайта (sitekey). Данный ключ можно получить в административной консоли Google ReCAPTCHA, но для этого приложение надо сначала развернуть на Netlify. К счастью, для локальной разработки можно использовать этот тестовый ключ (это официальный ключ для тестирования): 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI. Позже мы вернемся к этому вопросу. Еще один важный момент — это конечная точка отправки пользовательских данных. Она должна начинаться с /.netlify/, затем указывается путь к соответствующей функции: functions/subscribe — /.netlify/functions/subscribe (название функции — часть пути). Следует отметить, что часть пути /.netlify/functions можно изменить в netlify.toml. В остальном, все просто: после скрытия индикатора загрузки, мы предлагаем пользователю ввести свое имя и адрес электронной почты, а также подтвердить, что он "не робот". После заполнения всех полей и прохождения проверки с кнопки "Подписаться" снимается блокировка. При нажатии этой кнопки данные пользователя отправляются в функцию, которая записывает их в таблицу. Итак, у нас имеется клиентская часть приложения и функция для записи данных пользователя в таблицу. Пришло время проверить работоспособность приложения. Если вы еще не установили netlify-cli, самое время это сделать: Все, что нужно сделать для запуска приложения и инициализации функции, это выполнить следующую команду: После выполнения указанной команды клиент будет запущен по адресу localhost:3000, а сервер — также на локальном хосте, но с портом 8888. Прелесть в том, что netlify-cli умеет автоматически определять, какой фреймворк используется в проекте, и выполнять нужные команды для его запуска. Нажимаем на кнопку "Подписаться", заполняем поля формы, проходим проверку и снова нажимаем на "Подписаться". Выполняется перенаправление на страницу с сообщением об успехе операции, затем еще одно перенаправление на главную страницу. Открываем таблицу, видим введенные нами данные. .  .  .  Отлично, приложение работает, как ожидается. В следующей части туториала мы развернем приложение на Netlify, закончим настройку капчи, реализуем автоматическую рассылку уведомлений и отписку от обновлений. Благодарю за внимание и хорошего дня! Облачные серверы от Маклауд быстрые и безопасные. Зарегистрируйтесь по ссылке выше или кликнув на баннер и получите 10% скидку на первый месяц аренды сервера любой конфигурации!