IT-инфраструктура для бизнеса и творчества
Разработка
Pavel Osadchuk

Технические рекомендации и инструменты для создания SaaS

Перевод Twitter-треда с ценными техническими рекомендациями и инструментами, крайне полезными при создании SaaS приложения.

Цели

  • Предоставить фантастический пользовательский опыт.
  • Чем меньше разработки тем лучше.
  • Быстрая разработка.
  • Устойчивость системы.
  • Простота для одного разработчика.

Первая часть будет для определенного стека технологий, вторая — не зависящая от стека.

Используйте React или Vue

Пользователи ожидают красивый и удобный интерфейс, который проще и быстрее построить и поддерживать с помощью React. Сегодня это проверенная и скучная технология, используемая везде — от корпораций до стартапов. Если вам когда-нибудь понадобятся мобильные приложения, можно использовать React Native for Web, чтобы запускать ваш код на всех платформах.

Используйте мета-библиотеки React или Vue

Next.js (React) или Nuxt.js (Vue) предоставляют потрясающие окружение для построения пользовательских интерфейсов. Нет необходимости ругаться на Webpack и кричать на Babel. Команда Chrome активно работает, чтобы сделать то, что уже быстро работает в Next.js, ещё быстрее.

Используйте утилитарный (utility‑first) CSS

Вы можете построить весь пользовательский интерфейс без написания кода CSS, потому что он предоставляет вам похожие на Lego блоки CSS, которые вы можете скомпоновать в любом виде. @tailwindcss или CSS‑in‑JS комбинация Emotion + Theme‑UI делает использование CSS в вашем приложении очень простым.

Используйте GraphQL

GraphQL — это современная замена REST, которая упрощает разработку на всех уровнях и позволяет легко связать все источники данных необходимых для вашего приложения. Он намного лучше чем REST для партнёров и пользователей, поэтому GitHub, Shopify и многие другие стали использовать его вместо REST.

Используйте Low‑Code GraphQL — сервер

Эти серверы автоматически генерируют каждую CRUD-операцию для ваших данных, обрабатывают миграции и обеспечивают тонкую настройку прав — все это без дополнительного кода! Дни, когда надо было писать каждый REST‑endpoint отдельно, давно уже в прошлом.

Варианты:@HasuraHQ, AWS AppSync, @8base

Используйте serverless functions для бизнес-логики

Они более надёжные, их легче поддерживать, они лучше масштабируются, чем образы EC2. Также GraphQL-серверы, упомянутые выше, спроектированы для работы с serverless functions, поэтому работа с ними очень проста.

Используйте Typescript для фронтэнда и бэкэнда

Typescript — это статически типизированный JavaScript, который сейчас активно используется. Его использование равноценно 1000 юнит-тестам. Вы сможете писать код быстрее и увереннее. А автодополнение кода в IDE позволит оставаться в «потоке» без необходимости искать методы или атрибуты.

Используйте генерацию кода

GraphQL и Typescript позволяют автоматически генерировать код для получения данных. Вы определяете, какие данные вам необходимы, и они генерируют функцию для получения, включая строго типизированные классы для автодополнения и компиляции.

Базовая модель данных

Вам потребуются модели для пользователя, команды и аккаунта. Пользователь может входить в систему. Аккаунт оплачивает счёт. Команда владеет ресурсами. На старте необязательно предоставлять функциональность для команды, но она точно потребуется в будущем.

Используйте среды развертывания

Вам нужна тестовая среда, максимально идентичная среде эксплуатации — за исключением другой базы данных. Это позволит тестировать изменения в изолированном окружении, не боясь что-то сломать и потерять клиентов.

Пишите тесты: не слишком много, по большей части интеграционные

Настройте тестирование с самого начала. Для каждой крупной фичи напишите хотя бы один интеграционный end-to-end-тест. Добавьте git hook, чтобы запускать тесты при git push и отлавливать проблемы заранее. Для JS используйте Jest для запуска тестов — и Cypress для end-to-end-тестов.

CI/CD

Вам нужно, чтобы каждый коммит в master запускал автотесты и, если они успешны, запускалось автоматическое развертывание в продакшн. Аналогично: настройте ветку git для разработки (dev), с автотестами и автоматическим развертыванием. Таким образом публикация в продакшн будет простым git merge из ветки dev в master

Обрабатывайте вебхуки асинхронно

Когда вы используете вебхуки сторонних сервисов, сохраняйте их в собственную таблицу в базе данных и запускайте по событию асинхронно с помощью serverless function. Это минимизирует шанс, что кто-то сможет выполнить успешную DoS-атаку на ваше приложение.

Использование собственной базы данных оставляет возможность для DoS-атаки. Лучшим вариантом будет использование очередей.

Не делайте собственную аутентификацию

Для аутентификации используйте сервисы вроде @auth0 или AWS Cognito. Такой подход намного безопаснее. Эти сервисы позволяют моментально подключить двухфакторную аутентификацию, вход через социальные сети и многое другое.

Не делайте собственный биллинг

Для биллинга используйте сторонние сервисы вроде @Chargebee или @Outseta. Вам нужны все те возможности, которые недоступны в Stripe: визуальный интерфейс биллинга, возможность обновить подключенную карту и изменить тариф, но вы не должны тратить на это свое время. Сфокусируйтесь на продукте.

Используйте сторонний сервис для изображений

Используйте @Imgix или @Cloudinary для загрузки изображений нужного размера и разрешения вместо созданий собственного обработчика.

Для видео рекомендую посмотреть на Cloudflare Stream. Он позволяет загрузить видео, получить тег <stream> и мгновенно начинает проигрывание в отличие от других сервисов.

— Самостоятельный хостинг: медленный запуск видео.

— Встраивание YouTube: перед вашим видео может запуститься рекламный ролик.

— Встраивание Vimeo: медленно начинает проигрывание, если вообще начинает.

Вам нужен инструмент для транзакционных электронных писем

@postmarkapp — один из лучших и достаточно недорогой. Используйте его для сброса паролей, отчётности, обучающих писем, но не используйте для маркетинга.

Я лично предпочитаю использовать @mailgun для этих задач. Одна из самых полезных функций там — HTML-шаблоны сообщений, куда можно подставить свои данные и отправить их пользователю.

Ван нужен инструмент для маркетинговых электронных писем

Вам нужен отдельный сервис для отправки писем и маркетинговых компаний. @Mailchimp или @Userlist вполне подходят для этого.

Вам нужен мониторинг серверов

Используйте @UptimeRobot для постоянного пинга ваших серверов и отправки уведомления, если что-то пошло не так. Добавьте дополнительный эндпойнт, например /health, который проверяет подключения к базе данных и возвращает 200, если все хорошо.

Вам нужна система отслеживания ошибок

Пользователи никогда не сообщат вам о большей части возникших у них проблем. Используйте сервисы @getsentry или @honeybadgerapp для отслеживания фронтенд- и бэкэнд-ошибок.

Вам нужно логирование

@papertrailapp собирает логи из каждого места, где у вас запущен какой-либо код. Подобные сервисы позволят с лёгкостью найти в логах проблемные моменты. Без этих сервисов отладка продакшн-проблем станет серьезной головной болью.

Вам нужен чат для поддержки пользователей

В первые месяцы после запуска чат поддержки значительно улучшает взаимодействие с пользователем и отладку проблемных ситуаций. Можно использовать такие сервисы, как @Intercom, @Crisp_im или @Outseta

Вам нужна пользовательская аналитика

Вы должны понимать, как пользователи используют ваше приложение. Как много делают это каждый день? Каждую неделю? Кто перестал заходить в приложение? Какие покупатели наиболее активны? Какую фичу следует улучшать дальше? Используйте сервисы @Amplitude_HQ или @Outseta.

Вам нужен публичный changelog

Ваши пользователи должны знать, какие возможности вы добавляете в приложения, чтобы начать их использовать. Используйте такие сервисы, как Beamer, Headway или @changefeedapp.

{ "author_name": "Pavel Osadchuk", "author_type": "self", "tags": [], "comments": 3, "likes": 2, "favorites": 33, "is_advertisement": false, "subsite_label": "dev", "id": 102967, "is_wide": true, "is_ugc": true, "date": "Fri, 24 Jan 2020 14:32:34 +0300", "is_special": false }
(function () { let cdnUrl = `https://specialsf378ef5-a.akamaihd.net/SelectelBranding/images/` let previousArticleNumber = null let currentArticleNumber = 0 let platform = 'Desktop' let articles = [ // { // name: 'camera', // url: `${cdnUrl}CameraCat`, // text: 'умную камеру для\u00A0наблюдения за\u00A0котиками', // link: '1', // }, { name: 'chill', url: `${cdnUrl}ChillCat`, text: 'трекер, который подскажет, когда пора отдохнуть', link: 'https://vc.ru/promo/288561-eye-tracker', }, // { // name: 'cloud', // url: `${cdnUrl}CloudCat`, // text: 'котика: даёшь ему «пять», а\u00A0он делает бэкап в облако', // link: '3', // } ] let buttonCycle = document.querySelector('.button--cycle') let textField = document.querySelector('.selectel-footer-subtitle') let imageAgent = document.querySelector('.image--agent') let banner = document.querySelector('.selectel-footer') buttonCycle.addEventListener('click', cycleClick) let media = window.matchMedia("(max-width: 570px)") media.addEventListener('change', matchMedia) function matchMedia() { if (media.matches) { platform = 'Mobile' } else { platform = 'Desktop' } update() } matchMedia() function cycleClick(event) { if (event) { event.preventDefault() event.stopPropagation() } window.open('https://vc.ru/tag/selectelDIY', '_blank') //cycle(event) } function cycle(event) { // incrementArticleNumber() textField.innerHTML = generatedText() imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?5' imageAgent.setAttribute("class", "") imageAgent.classList.add('image--agent', articles[currentArticleNumber].name) banner.href = articles[currentArticleNumber].link } function update() { banner.href = articles[currentArticleNumber].link imageAgent.src = articles[currentArticleNumber].url + platform + '.svg?5' textField.innerHTML = generatedText() } function incrementArticleNumber() { previousArticleNumber = currentArticleNumber if (currentArticleNumber >= articles.length - 1) { currentArticleNumber = 0 } else { currentArticleNumber++ } } function generatedText() { let defaultText if (platform === 'Desktop') { defaultText = `Мы тут собрали %text%. Хотите почитать?` } else { defaultText = `Мы тут собрали %text%.` } return defaultText.replace('%text%', articles[currentArticleNumber].text) } function getRandom(min, max) { min = Math.ceil(min) max = Math.floor(max) return Math.floor(Math.random() * (max - min + 1)) + min } (function create() { currentArticleNumber = getRandom(0, articles.length - 1) cycle() let page = document.querySelector('.page--entry') if (page) { function insertAfter() { let parents = page.querySelectorAll('[data-id="7"]') let referenceNode = parents[0] referenceNode.parentNode.insertBefore(banner, referenceNode.nextSibling); loaded() } setTimeout(() => insertAfter(), 0) } }()) function loaded() { banner.classList.add('loaded') } loadImages([ `${cdnUrl}CameraCatDesktop.svg`, `${cdnUrl}ChillCatDesktop.svg`, `${cdnUrl}CloudCatDesktop.svg`, `${cdnUrl}CameraCatMobile.svg`, `${cdnUrl}ChillCatMobile.svg`, `${cdnUrl}CloudCatMobile.svg`, ]) function loadImages(urls) { return Promise.all(urls.map(function (url) { return new Promise(function (resolve) { var img = document.createElement('img'); img.onload = resolve; img.onerror = resolve; img.src = url; }); })); } }())
0
3 комментария
Популярные
По порядку

Очень годно

3

Вам нужен не только мониторинг, но и инцидент-менеджмент, а еще GraphQL — супер стремная штука с точки зрения производительности.

0

Что за бесвязный поток бреда ни о чем?

0
Читать все 3 комментария
Облажались с аудиторией и производством в Китае, но вышли на 55 млн рублей за 2020 год: история ошибок компании Atmeex

Мы начали производить и продавать приборы по очищению воздуха в конце 2019 года. Первое время всё шло наперекосяк, но мы переосмыслили все процессы и за год увеличили выручку в 2 раза.

В отдельном помещении мы тестируем устройства на брак
Электричество из солёной воды, «напечатанные» дома и беговые приборы для незрячих — лидеры премии Innovation by Design Статьи редакции

А также светодиодные системы для роста сельскохозяйственных культур и браслеты с «тревожной» кнопкой для женщин. Эти и другие инновационные проекты наградило издание Fast Company.

Как охватить 98% сотрудников кадровым электронным документооборотом

Кейс Альфа-Лизинга и EasyDocs

Разворотная фигура Бриллиант в техническом анализе

Фигуру «Бриллиант» (с англ. – «Diamond») называют также «Кристалл», «Алмаз», «Ромб». Формация состоит из двух конфигураций — расходящегося и симметричного (сходящегося) треугольников. Этот паттерн в теории служит сигналом для смены тренда или как минимум коррекцией в средне- или долгосрочном движении актива.

IKEA в Британии рассказала о снятии с производства плюшевых акул — в России они останутся в продаже Статьи редакции

Акула Blåhaj (по-русски «Блохэй») в 2018 году стала хитом в России. Её было невозможно купить в магазинах, перекупщики завышали цены в два раза, а соцсети заполнили фотографии с ней.

Aviasales запустил «Короче» — карты с обзорами городов и контактами местных гидов и фотографов Статьи редакции

В сервисе уже есть 49 российских и зарубежных городов.

«Короче» добавили в приложениях и на сайте Aviasales. Если в городе есть сервис, он появится рядом с выдачей билетов Aviasales
Двойная польза: Премия HR-бренд и Рейтинг работодателей — в чем разница и зачем участвовать в обоих проектах

Какой компании не хочется, чтобы ее считали работодателем мечты? Пусть лучшие кандидаты делают выбор в вашу пользу, а конкуренты ломают голову — что с ними не так. Продемонстрировать силу своего HR-бренда компаниям уже более 10 лет помогает hh.ru: ежегодно мы проводим Рейтинг работодателей России и Премию HR-бренд. И как показывает анализ…

Батарея, камера, но не экран: обзор iPhone 13 и iPhone 13 mini Статьи редакции
Whoosh, Urent и «Яндекс Go» нашли злоумышленников, которые повредили 800 электросамокатов в Москве Статьи редакции

Они отделались выплатой компенсации.

Сделай сам: котик манеки-неко, который сделает бэкап в облако

Сопровождаем сохранение резервных копий протяжным «мяу».

«Дочка» Volvo по производству электромобилей выйдет на биржу через слияние со SPAC-компанией при оценке в $21 млрд — WSJ Статьи редакции

Действующие акционеры смогут получить $250 млн после сделки.

Polestar 2 Polestar
null