Blazor та Heroku: як безкоштовно створити інтерактивний додаток
Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті
Мене звати Віталій Дацишин, я працюю .NET розробником в компанії Intellias. В цій статті я поділюсь своїм досвідом створення сайту з Blazor та його розгортання з Heroku.
Цей проект є моїм pet project’ом, тому було всього дві вимоги: спробувати щось нове та зробити все максимально дешево (в ідеалі, безкоштовно). Технології, які я використав, відповідають цим вимогам — це Blazor, SQLite і Heroku.
Blazor
Blazor — це UI-фреймворк для створення інтерактивних додатків, які можуть працювати на платформі .NET як на стороні сервера, так і на стороні клієнта. Blazor є відносно молодим фреймворком, перший реліз був у 2018, тому він зазнав значного впливу сучасних фреймворків-гігантів для створення клієнтських додатків — Angular, React, VueJS. Головною перевагою для розробників є використання C# замість JavaScript і можливість використання екосистеми .NET з усіма її бібліотеками.
Є дві моделі розгортання (hosting) — Server і WebAssembly.
WebAssembly
При цьому способі хостингу компоненти Blazor запускаються у браузері, який використовує середовище виконання .NET на базі WebAssembly на стороні клієнта. .NET runtime завантажується разом із додатком Blazor WebAssembly та це дозволяє запускати звичайний код .NET безпосередньо у браузері. Ніяких плагінів або перетворювачів коду не потрібно. Blazor WebAssembly працює з усіма сучасними веббраузерами — як десктопними, так і мобільними. Ці додатки можуть бути розгорнуті як повністю автономні статичні сайти взагалі без будь-якого компонента сервера .NET. Або їх можна поєднати з ASP.NET Core, щоб забезпечити повну веброзробку з .NET, де код можна легко поділити між клієнтом і сервером.
Server
При цьому способі хостингу компоненти Blazor запускаються на сервері як додаток ASP.NET Core. Всі взаємодії та оновлення інтерфейсу обробляються через з’єднання SignalR.
Власне, саме цей спосіб хостингу я і обрав, тому що:
- з ним швидко і просто розпочати розробку;
- все в одному проєкті — дешевше і легше зібрати його в один docker image;
- всі завантажені файли на клієнт мають набагато менший розмір порівняно з Blazor WebAssembly;
- можливий доступ до захищених ресурсів, таких як бази даних або хмарні сервіси.
Серед негативних моментів варто виділити, що буде додаткова затримка через надсилання даних туди і назад. Це може бути особливо критичним при слабкому інтернеті.
Компоненти
Ключовим елементом додатків на Blazor є компоненти. Хто працював з фреймворками клієнтської сторони, такими як Angular, React, VueJS, той стикався з компонентами, які, по суті, структурують додаток. У Blazor застосовується схожа концепція.
Клас компонента зазвичай записується у вигляді сторінки розмітки Razor із розширенням файлу .razor. Синтаксис Razor поєднує розмітку HTML із кодом C#. Замість того, щоб працювати з JavaScript, jQuery чи іншим фреймворком для викликів API, у розділі @code можна реалізувати методи життєвого циклу компонентів та методи компонентів. Компоненти можна повторно використовувати в інших проєктах і переносити у вигляді бібліотеки класів Razor.
Приклад
@page "/news" @inject TopFighterDbContext DbContext @foreach (var news in DbContext.News) { <div class="row"> <div class="col-md-6"> <ImageCarousel ImageNames="@news.ImageNames"/> </div> <div class="col-md-6"> <h1>@news.Caption</h1> <p>@news.Description</p> </div> </div> <hr> }
SQLite
Дійшовши до вибору бази даних, я згадав про початкові вимоги — щось нове і дешеве. В цих пошуках я знайшов реляційну систему керування базами даних — SQLite. Найважливішим фактором для мене було те, що вся база даних — це, по суті, один файл (file based). Крім того, формат файлу є міжплатформеним. Базу даних, створену на одній машині, можна скопіювати та використовувати на іншій машині з іншою архітектурою. Для мене це було важливо, адже мені не потрібен буде окремий ресурс в хмарному середовищі для БД, а все буде разом. Економія — моє все.
Також, це одна з найпоширеніших баз даних, тому було дуже легко інтегруватися з нею в моєму додатку.
services.AddDbContext(options => options.UseSqlite(_configuration.GetConnectionString("TopFighterDb")));
Тут connection string це шлях до файлу.
"ConnectionStrings": { "TopFighterDb": "Data Source=TopFighter.db" }
Так як це є реляційна БД і використовується Entity Framework Core, то і міграції тут підійдуть.
Heroku
Heroku — це хмарна, повністю керована платформа як послуга (PaaS) для створення, запуску та управління програмами. З коробки Heroku підтримує багато різних мов програмування, але не підтримує .NET. Проте завжди є Docker.
Dyno — це linux контейнер, в якому виконуються всі програми, які розгорнуті в Heroku.
Я розглядав тільки безкоштовні dyno, і вони є досить непоганими та повністю задовольняють мої потреби. Серед переваг безкоштовного плану також є можливість додати своє доменне ім’я сайту.
В безкоштовному плані дається 1000 годин роботи dyno на місяць (550 годин одразу + 450 за прив’язку картки). Для мого одного додатку цього вистачає: 31 день * 24 години у добі = 744 години в місяць. Щодо негативної сторони, то це те, що через 30 хвилин неактивності dyno засинає, і це критично для мене, бо:
- усе, що було додано в БД (нагадую, що це просто файл) протягом роботи dyno зникає, адже коли dyno засинає, всі дані програми стираються, а коли dyno прокидається, все відновлюється з моменту останнього деплою;
- запит до сплячого dyno буде оброблятись дуже довго.
Як розв’язати цю проблему? Не дати dyno заснути. Для цього я використав крон джобу (заплановане виконання вебсайтів та скриптів), яку налаштував на виклик мого сайту кожні 30 хвилин. Таким чином dyno ніколи не засинає.
Розгортання сайту
1. Спершу потрібно створити акаунт в Heroku.
2. Далі в проєкт потрібно додати Dockerfile.
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-env WORKDIR /app COPY *\.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/sdk:3.1 WORKDIR /app COPY --from=build-env /app/out . CMD dotnet TopFighter.dll
3. В терміналі вводимо команду heroku login
, яка відкриє в браузері сторінку з формою для логіну.
4. Після успішного логіну створюємо додаток в Heroku.
Тут вже є посилання на додаток і виділений гіт, куди потрібно запушити код.
5. Та перед цим, потрібно сказати heroku, що додаток потрібно збирати як контейнер, тому що heroku не підтримує .NET.
6. Також, потрібно сказати heroku, де йому взяти Dockerfile. Для цього створюю heroku.yml на тому ж файловому рівні, що і Dockerfile
build: docker: web: Dockerfile
7. Далі до свого репозиторію (потрібно ініціалізувати якщо немає — git init
) додаю посилання на репозиторій heroku.
git remote add heroku-demo git.heroku.com/topfighter-demo.git
8. До репозиторію потрібно додати Dockerfile і heroku.yml (потрібно й інші файли, якщо до цього вони не були в репозиторії)
git add .
git commit -m “Added heroku support”
9. Нарешті, потрібно запушати все до репозиторію heroku і після цього одразу почнеться розгортання додатку
10. Після успішного розгортання можна перейти за посиланням на додаток (крок 4) і побачити свій сайт.
Також в своєму кабінеті heroku можна подивитись стан свого додатку, логи, налаштування, видалити додаток, і т.д.
Висновки
Повертаючись до вимог, які я поставив до цього проекту, можна сказати, що їх було виконано. Всі три технології, про які йшлося в цій статті, були новими для мене. І все це вийшло абсолютно безкоштовно, не враховуючи доменного імені сайту, яке в разі потреби можна буде взяти в оренду (приблизно
Отже, й справді вийшло дешево та сердито, а такий стек технологій чудово підійде для маленьких додатків-хобі.
7 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів