Ви вирішили будувати продукт, і перше питання на столі: на чому його будувати. Воно здається найважливішим, бо фреймворк виглядає як те, що найважче поміняти. Фреймворк насправді можна замінити за тижні, і робити це часто доводиться навіть не вам. А ось модель даних, з якою ви стартуєте, визначає, чим продукт взагалі має право стати; через два роки вона досі на місці, коли про стекову суперечку вже ніхто не згадує.
Розмови про стек займають стільки місця, бо їх можна вести ще до появи продукту: бенчмарки опубліковані, історії міграцій відкриті, думки нічого не коштують. Але ніхто в цій розмові не скаже, де лежатиме запис клієнта, яка нічна задача має право до нього торкатися і хто дивитиметься на завислу чергу в неділю. Саме ці відповіді вирішують, чи продукт переживе другого клієнта, і всі їх можна записати на папері, нічого не встановлюючи.
1. Модель даних вирішує більше, ніж фреймворк
Візьміть аркуш і запишіть іменники свого продукту: клієнт, передплата, рахунок, проєкт, звіт, усе, що належить саме вам. Потім проведіть між ними лінії. На це йде година, і це та частина стеку, яку не замінити. Заміна фреймворка: це проєкт із датою. А заміна моделі даних: переписування продукту, яке роками тягне стару форму, бо історичні рядки нікуди не поділися.
Питання, яке треба розв’язати на тому аркуші, зовсім не про швидкість бази даних. Воно про те, кому належить кожен рядок і з ким цей рядок взагалі можна ділитися. Рахунок одного клієнта належить саме йому: у звіті, у вивантаженні, у листі, який задача надсилає вночі. Продукти тут ламаються передбачувано. Спочатку таблиця з’являється без власника, бо клієнт один; потім колонку з власником додають заднім числом і роблять необов’язковою, і з цього дня кожна нова сторінка залежить від того, чи хтось не забув фільтр.
Кому належить рядок, запишіть у саму таблицю, а не в сторінку. А потім поставте два питання, які зазвичай виявляють рішення, сховане під першим: що відбувається, коли клієнт іде, що він при цьому експортує і що видаляється, і що звітові дозволено перетинати.
2. Другий клієнт вимагає межі, а не нової фічі
Якщо за один продукт платитимуть кілька компаній, ви будуєте мультитенантну систему, навіть якщо цього слова ніхто не вживає. Вибір простий: спільні таблиці з колонкою власника або фізично окреме сховище для кожного клієнта. Жоден варіант не є правильним узагалі, і кожен дорого змінюється заднім числом, бо міграції, індекси, резервні копії та фонові задачі успадковують цей вибір.
Розв’яжіть це до першого рядка коду, одним реченням, яке новий розробник прочитає без пояснень, а потім дотримайтеся однієї обіцянки двома входами. Два клієнти, які не повинні бачити один одного, відкривають той самий звіт, і рядки відрізняються. Це і є уся перевірка, і пройдете ви її самі. Найчастіше межа рветься там, де її ніхто не чекає: у вивантаженні, у нічному листі, у полі пошуку, у списку з пунктом «усі компанії». Детально про ці місця: де саме ламається межа між двома клієнтами.
Помітьте: це рішення не про масштаб. Двох клієнтів уже досить, щоб межа стала потрібна. Продукт із десятьма користувачами та чистою межею у кращому стані, ніж продукт із тисячею користувачів і фільтром, про який хтось може забути.
3. Робота поза вебзапитом має бути названа
У кожного SaaS є робота поза запитом: рахунок, який треба виставити, вивантаження на хвилину, імпорт із файлу, лист на кожного клієнта, вебхук, що приходить двічі. Вирішіть уже зараз, чи йде така робота в чергу з повторами, чи в процес за розкладом, і що дозволено повторному запуску. Виставлений двічі рахунок: це розмова з реальним клієнтом. Двічі отримане в понеділок зведення теж.
Поставте три питання до кожної такої задачі. Що її запускає? Якого клієнта вона має право зачіпати? Що робить повтор? Якщо на останнє відповідь «перевіряє», запишіть, що саме перевіряється: це речення і є політикою повтору. Якщо задача зірвалася о третій ночі, вранці ви маєте це побачити без відкритого вручну сервера. Порядок дій, коли черга вже зростає, описано тут: перевірте стани, перш ніж додавати обробників, а ті самі стани варто продумати до першої написаної задачі.
4. Перша тисяча користувачів перевіряє підтримку, не архітектуру
Тисяча платних користувачів не є навантаженням. Такий трафік вміщується на один маленький сервер, і будь-який фреймворк із ним справляється. Ламається тут не фреймворк. Ламається одна машина, де база, файли й пошта стоять разом, без протестованого відновлення, з логами, які ніхто не вміє шукати, і з релізом, який одна людина запускає вручну з термінала ввечері.
Міряйте чотири речі від першого тижня, а не від першої аварії: найповільнішу сторінку на 90-му перцентилі, глибину черги, те, що каже повільний лог запитів, і скільки часу займає відновлення на другу машину. Лише останнє число говорить, чи взагалі у вас є резервна копія. Жодне з цих чисел не залежить від фреймворка, який ви обрали. Усі чотири вирішують, чи залишиться перша тисяча клієнтів ще на рік.
5. Підтримка на другий рік вирішує, що було мудрим
Стек є рішенням про найм, яке приймає людина, що поки що нікого не наймає. Ті, хто підтримуватиме продукт через два роки, підніматимуть його з того, що записано, а не з того, що прозвучало на зустрічі. Екзотичний вибір, який розуміє одна людина, стає тягарем у день, коли ця людина їде у відпустку на місяць, і приводом для переписування тоді, коли вона звільняється.
Віддавайте перевагу тому, у чому новий розробник стане продуктивним за тиждень: поширена мова, поширена база даних, міграції однією командою і хостинг, який не потребує спеціаліста, щоб лишатися на плаву. Це не боязкість, це визнання того, що більша частина життя продукту є підтримкою, і що той, хто успадкує ваш продукт, прогонить його через щось на кшталт технічного аудиту: який сценарій небезпечний, який запит повільний, який обліковий запис бачить усе і яке рішення живе лише в одній голові.
6. Фреймворк вибирайте останнім і за доказами
Фреймворк найлегше змінити з-поміж усіх цих рішень, тому ставте його останнім, після моделі даних, межі, фонової роботи та майбутнього підтримувача. Докази, які варто зібрати, небагато й усі практичні: чи знає його команда, чи вміє він із коробки черги й міграції, чи поставите ви його на десять користувачів без жалю і на десять тисяч без переписування, і чи документація знайдеться для того, хто читатиме код опівночі. Якщо ці відповіді тримаються, відмінності між поширеними варіантами менші за будь-який розділ вище.
До першого рядка коду запишіть ці п’ять речей на одному аркуші:
Саме в такому порядку я працюю, коли продукт тільки починається: спочатку межа і модель даних, потім робота, яка йде з запиту, і наприкінці, коротко, фреймворк. Послуги охоплюють першу версію SaaS або CRM, архітектуру навколо неї та роботу, яка тримає систему після запуску. Роботи показують ті самі рішення на системах, які вже працюють: CRM, розділена по філіях, звіти, де клієнти не змішуються, і фонова робота, що витримала першу тисячу задач. Якщо ви на етапі, де стек ще не обрано, починайте з розробки продукту з нуля або напишіть мені, які іменники має ваш продукт і чому належить кожен рядок. Паролі та клієнтські дані в повідомлення не кладіть.