Shanraq.org Shanraq.org

Свой фреймворк на Go: как устроен shanraq.org

Этот сайт не работает ни на готовой CMS, ни на веб-фреймворке. Публикации, объявления, реклама, переводы, рассылки и платежи собраны из модулей, написанных здесь же, на Go.

Цифры

43 031 строка кода и 16 581 строка тестов в 271 файле. 14 модулей, 143 миграции базы, 36 шаблонов.

И 589 строк JavaScript в двух файлах — на весь сайт. Ни React, ни Vue, ни сборщика. Оформление — 3 478 строк собственного CSS, без Bootstrap и Tailwind. Страница, которую вы читаете, не загружает ни одного стороннего скрипта.

Что такое модуль

Ядро — интерфейс из одного метода:

type Module interface {
    Name() string
}

Дальше модуль добавляет то, что ему нужно: Routes — если у него есть страницы, Init — если нужна подготовка до старта сервера, Start — если он держит фонового работника. Приложение собирает модули в список и на запуске выдаёт каждому Runtime: конфигурацию, логер, пул соединений к базе и роутер.

Отсюда правило, которое держит систему целой: модуль не знает про соседей. Статьи не импортируют объявления, объявления не импортируют почту. Убрать модуль — значит убрать одну строку регистрации.

Сегодня их четырнадцать: ai, apikeys, articles, auth, health, jobs, media, migrations, notifier, ratings, sms, syndicate, telemetry, webui.

Что взято готовым

Список приводим полностью, потому что «свой фреймворк» часто означает «свой поверх чужого» — и это нормально ровно до тех пор, пока сказано прямо.

Маршрутизация — chi. Postgres — pgx. Логи — zap. Конфигурация — viper. Миграции — goose. Markdown — goldmark. Метрики и трассировка — Prometheus и OpenTelemetry.

Чего нет: ORM. Все запросы к базе написаны на SQL и лежат рядом с кодом, который их выполняет.

Почему почти без JavaScript

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

Поэтому HTML собирается на сервере и приходит готовым. JavaScript остаётся только там, где без него нельзя: карусель, карта осадков, переключение языка. Выбор места в прогнозе погоды сделан обычной формой — без единой строки скрипта.

Три языка

Казахский, русский и английский — не перевод интерфейса, а три равноправные версии контента. У статьи три текста, у каждого свой адрес и свой canonical. Машинный перевод есть, но он предлагает, а решает автор.

Код открыт: https://github.com/DauletBai/shanraq.org