Что я делаю
У меня возникла идея создать приложение для кроссфит-тренировок для спортзалов и спортсменов. Я назвал его Dreamwod и запустил в App Store и Google Play. Я сделал два приложения, одно для iOS и одно для Android, внутренний API и веб-страницу компании.
В этой статье будет рассказано о стеке технологий, способах работы, чему я научился и какие ошибки допустил.
Выбор стека технологий
Требования к стеку технологий у меня были следующими.
Бэкенд и поддержка
- Быстрое время разработки и итераций.
- Легкий локальный запуск.
- Легкое масштабирование бэкенда/в состоянии справляться с высокой нагрузкой.
- Простота развертывания.
- Наибольшая проста.
Разработка приложений
Простота в освоении (у меня не было опыта разработки iOS-приложений).
Стек
Бэкенд — Golang
Языком для бэкенда был выбран Golang . Я хотел что-то, что легко освоить, быстро компилировать, с хорошей производительностью и малым потреблением памяти и процессора в производственной среде.
Приложения — Flutter
У меня не было большого опыта работы ни с iOS, ни с Android, и мне нужны были приложения для обеих платформ, поэтому решение было довольно простым: попробовать Flutter и посмотреть, сработает ли он.
База данных — PostgreSQL
У меня было несколько вариантов при выборе базы данных. Предположения, на которых я основывал решение, были такие:
- Данные будут совместно использоваться пользователями, т. е. данные в приложении не только просматриваются и редактируются загружающим их пользователем.
- У меня было бы несколько объединений данных и взаимосвязанных таблиц.
- Я предполагал, что хочу поддержку полнотекстового поиска и не хочу тратить время и силы на ElasticSearch или что-то подобное.
Было принято решение использовать Postgres. В нем есть поддержка полнотекстового поиска из коробки с расширением pg_trgm. Он также имеет хорошую поддержку PostGIS с расширением postgis, поэтому легко рассчитать координаты и расстояние от пользователя, например, до спортзала.
Облако — GCP ☁
Я рассмотрел два варианта хостинга: Google Cloud Platform (GCP) и AWS. Я выбрал GCP, потому что затем мог запускать API для бэкенда в Cloud Run и платить только за время обработки, которое в основном во время разработки и бета-тестирования было нулевым.
Некоторые другие полезные инструменты
Cloud Build для создания контейнеров. Поскольку я единственный разработчик и не создаю много контейнеров, я легко уложусь в их свободные 120 минут в день.
Облачное хранилище Cloud Storage используется для контента, загруженного пользователями.
Pub/sub используется для асинхронной обработки, посмотрите статью о том, как я использую подход, при котором я могу разрабатывать локально, а потом легко развертывать это в GCP.
Ежемесячный счет сейчас составляет около 30 долларов, из которых две крупнейшие статьи затрат — балансировщика нагрузки для CDN (18 долларов) и база PostgreSQL (10 долларов). Этот счет, конечно, увеличится, когда я получу больше пользователей и мне потребуется использовать большие базы данных, но для некоторого количества пользователей стоимость все равно будет довольно низкой.
Электронная почта — Mailgun
Есть много вариантов, я просто выбрал Mailgun, так как я использовал их в прошлом.
Платежи — Stripe
Я добавляю поддержку подписок в приложение, и использование Stripe было хорошим решением, поскольку у них есть портал подписки для пользователей, где они могут отменять и изменять подписки.
Веб-страница компании — Webflow
Я выбрал webflow в качестве фреймворка/инструмента для веб-страницы компании. Я искал что-то простое, что я мог бы настроить, а затем забыть. Веб-страница доступна по адресу www.dreamwod.app.
Как я работал
Никаких тестов
Такой подход встречается нечасто, и, возможно, позже это окажется ошибкой, но вот основные причины, по которым я не добавил более 5-10 тестов в бэкенд-проект.
- Как разработчик-одиночка (Backend, Frontend, QA), я буду тестировать бэкенд-код, когда буду реализовывать интерфейс.
- Добавление тестов занимает много времени. При создании этого приложения было много экспериментов и испытаний идей, а добавление тестов для чего-то, что я бы не стал использовать, замедлило бы скорость разработки.
- Вещи, для которых у меня есть тесты, в основном связаны с разбором регулярных выражений, поэтому писать тесты было быстрее, чем напрямую тестировать API.
Монолит вместо микросервисов
Всегда немного спорно использовать один сервис вместо набора микросервисов, но причина, по которой у меня есть только один серверный API/сервис, заключается в следующем.
- Я не хочу тратить время на определение контрактов/API и решение проблем, связанных с хостингом, которые возникают при мультисервисном подходе.
- При запуске нового проекта сложно понять, где разделить один сервис на разные. Держу пари, что это легче сделать позже, если/когда это понадобится.
- У меня нет большой нагрузки на систему, поэтому у меня нет проблем с узкими местами в производительности или особыми потоками в серверной части, которые необходимо оптимизировать.
С учетом сказанного, конечно, хорошо бы разделить код на разные области/домены и не иметь в кодовой базе «спагетти-кода».
Чему я научился?
- «Последние 20% занимают 80% времени» — известная цитата, но она оказалась правдой для меня. Последние вещи заняли намного больше времени, чем предполагалось.
- Самостоятельная работа означает, что у меня нет строгих сроков, но мне бывает трудно сосредоточиться. Я узнал, что для меня лучше всего работает наличие рутины, когда дело доходит до программирования, обучения и т. д., как на обычной работе с 9 до 5. Мой обычный день состоит из одного сеанса программирования перед обедом, более продолжительного обеденного перерыва с занятием в спортзале, а затем сеанса работы во второй половине дня.
Что бы я сделал по-другому в стеке технологий
В целом я очень доволен техническим стеком, и не так много вещей, которые я бы изменил. Но есть вещи, которые я бы сделал по-другому:
- Я бы исследовал, стал бы GraphQL API лучшим вариантом вместо REST API.
- Я немного обеспокоен тем, что может быть сложно масштабировать (давайте посмотрим, понадобится ли это когда-нибудь) решение в глобальном масштабе. База данных и сервисы прямо сейчас размещены в центре обработки данных в Бельгии, и будет большая задержка, если кто-то будет использовать ее, например, из США или Бразилии.
Что бы я сделал по-другому с продуктовой точки зрения
Иногда было бы лучше принять «быстрое и простое» решение, а не «правильное».
- Например, Cloud Run был чем-то новым, когда я начинал, и они не поддерживали некоторые вещи, такие как получение данных из GCP Secrets Manager. Я потратил некоторое время на реализацию этого, и было бы лучше, если бы я просто сделал несколько быстрых и простых хаков, а затем дождался надлежащей поддержки от Google Cloud.
Выводы
Всегда легко оглянуться назад и подумать о тех вещах, которые пошли не так, как вы планировали. Тем не менее важно думать о вещах, которые на самом деле сработали очень хорошо. Это одна из причин, почему я написал эту короткую статью — чтобы подумать о том, что сработало хорошо.
Если вы думаете о создании компании в качестве индивидуального разработчика, перестаньте думать и сделайте это! Это очень весело!