Microsoft выпустила почти 100 готовых skills для AI-агентов, работающих с .NET
Microsoft без громких анонсов опубликовала набор из 99 готовых skills для AI-агентов, предназначенных для работы с .NET. Все они доступны в открытом доступе и могут использоваться в таких инструментах, как Claude Code, Codex, GitHub Copilot и Cursor.
Skills размещены в репозитории dotnet/skills и сгруппированы в 14 плагинов, включающих около 95 специализированных сценариев. Каждый skill представляет собой набор инструкций, который AI-агент автоматически загружает только при выполнении соответствующей задачи.
Среди наиболее полезных плагинов:
dotnet-data — помогает оптимизировать запросы EF Core, выявляет проблемы N+1, корректирует режимы отслеживания (tracking) и устраняет типичные узкие места производительности.
dotnet-test — крупнейший плагин, содержащий 22 skills для запуска, фильтрации и миграции тестов между различными тестовыми фреймворками.
dotnet-upgrade — автоматизирует миграцию проектов с .NET 8 на .NET 10 и включает поддержку nullable reference types.
dotnet-aspnet — предназначен для создания Web API и endpoints загрузки файлов с использованием Minimal APIs.
dotnet-ai — позволяет создавать, отлаживать и тестировать MCP-серверы с помощью C# SDK.
При этом Microsoft отмечает, что опубликованные skills решают только типовые задачи экосистемы .NET. Они не учитывают особенности конкретного проекта: структуру каталогов, архитектурные соглашения, расположение сущностей, используемые паттерны или внутренние правила разработки.
Для подобных сценариев разработчикам предлагается создавать собственные skills, которые описывают принятые в проекте конвенции и позволяют AI-агентам учитывать специфику конкретной кодовой базы.
Подробное руководство по созданию пользовательских skills, настройке Skill Creator и работе с репозиторием dotnet/skills опубликовано автором статьи на его сайте.
👉 @KodBlog
Microsoft без громких анонсов опубликовала набор из 99 готовых skills для AI-агентов, предназначенных для работы с .NET. Все они доступны в открытом доступе и могут использоваться в таких инструментах, как Claude Code, Codex, GitHub Copilot и Cursor.
Skills размещены в репозитории dotnet/skills и сгруппированы в 14 плагинов, включающих около 95 специализированных сценариев. Каждый skill представляет собой набор инструкций, который AI-агент автоматически загружает только при выполнении соответствующей задачи.
Среди наиболее полезных плагинов:
dotnet-data — помогает оптимизировать запросы EF Core, выявляет проблемы N+1, корректирует режимы отслеживания (tracking) и устраняет типичные узкие места производительности.
dotnet-test — крупнейший плагин, содержащий 22 skills для запуска, фильтрации и миграции тестов между различными тестовыми фреймворками.
dotnet-upgrade — автоматизирует миграцию проектов с .NET 8 на .NET 10 и включает поддержку nullable reference types.
dotnet-aspnet — предназначен для создания Web API и endpoints загрузки файлов с использованием Minimal APIs.
dotnet-ai — позволяет создавать, отлаживать и тестировать MCP-серверы с помощью C# SDK.
При этом Microsoft отмечает, что опубликованные skills решают только типовые задачи экосистемы .NET. Они не учитывают особенности конкретного проекта: структуру каталогов, архитектурные соглашения, расположение сущностей, используемые паттерны или внутренние правила разработки.
Для подобных сценариев разработчикам предлагается создавать собственные skills, которые описывают принятые в проекте конвенции и позволяют AI-агентам учитывать специфику конкретной кодовой базы.
Подробное руководство по созданию пользовательских skills, настройке Skill Creator и работе с репозиторием dotnet/skills опубликовано автором статьи на его сайте.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12❤3🍾3
У твоей очереди нет тормозов.
Если производители добавляют задачи быстрее, чем потребители успевают их обрабатывать, безграничная очередь — это просто отсроченная боль.
Пятничный .NET-совет: используйте ограниченный Channel<t>.
Когда он заполняется, вы выбираете, что делать: ждать, отбрасывать или падать с ошибкой.</t>
https://learn.microsoft.com/ru-ru/dotnet/core/extensions/channels
👉 @KodBlog
Если производители добавляют задачи быстрее, чем потребители успевают их обрабатывать, безграничная очередь — это просто отсроченная боль.
Пятничный .NET-совет: используйте ограниченный Channel<t>.
Когда он заполняется, вы выбираете, что делать: ждать, отбрасывать или падать с ошибкой.</t>
https://learn.microsoft.com/ru-ru/dotnet/core/extensions/channels
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤3🍾2
Ваше приложение запускается без ошибок.
Затем приходит первый настоящий запрос.
Он пытается вызвать GitHub, отправить email, подключиться к сервису или использовать флаг функции.
И только тогда вы узнаёте, что одно значение конфигурации отсутствует или неверно.
Плохой URL.
Пустой токен.
Отсутствующая настройка.
Приложение никогда не было готово к запуску.
Оно просто об этом не сообщило.
ASP.NET Core предоставляет строго типизированную конфигурацию через паттерн Options. Но привязка значений к классу — это только часть работы.
Вам также нужно знать, что эти значения валидны.
И здесь может помочь FluentValidation.
Вместо добавления простых правил в класс настроек, вы можете хранить валидацию в отдельном валидаторе и чётко описать реальные правила:
→ Обязательное значение должно существовать
→ URL должен быть валидным
→ Одна настройка может зависеть от другой
→ Пользовательские проверки можно тестировать независимо
Затем добавьте валидацию при запуске.
Теперь, если конфигурация неверна, приложение падает сразу при старте.
Именно это нужно в контейнере, CI-пайплайне или новом деплое.
Сломанное приложение должно упасть до получения трафика, а не после того, как пользователь найдёт проблему за вас.
👉 @KodBlog
Затем приходит первый настоящий запрос.
Он пытается вызвать GitHub, отправить email, подключиться к сервису или использовать флаг функции.
И только тогда вы узнаёте, что одно значение конфигурации отсутствует или неверно.
Плохой URL.
Пустой токен.
Отсутствующая настройка.
Приложение никогда не было готово к запуску.
Оно просто об этом не сообщило.
ASP.NET Core предоставляет строго типизированную конфигурацию через паттерн Options. Но привязка значений к классу — это только часть работы.
Вам также нужно знать, что эти значения валидны.
И здесь может помочь FluentValidation.
Вместо добавления простых правил в класс настроек, вы можете хранить валидацию в отдельном валидаторе и чётко описать реальные правила:
→ Обязательное значение должно существовать
→ URL должен быть валидным
→ Одна настройка может зависеть от другой
→ Пользовательские проверки можно тестировать независимо
Затем добавьте валидацию при запуске.
Теперь, если конфигурация неверна, приложение падает сразу при старте.
Именно это нужно в контейнере, CI-пайплайне или новом деплое.
Сломанное приложение должно упасть до получения трафика, а не после того, как пользователь найдёт проблему за вас.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🍾2
This media is not supported in your browser
VIEW IN TELEGRAM
НОВИНКА: Устойчивые функции (Durable Functions) в PostgreSQL 🤯
pg_durable — это расширение PostgreSQL. Состояние рабочего процесса, очередь, повторные попытки и восстановление хранятся в Postgres, и оно использует устойчивость Postgres / высокую доступность / резервное копирование / восстановление.
https://techcommunity.microsoft.com/blog/adforpostgresql/introducing-durable-functions-in-postgresql/4526821
👉 @KodBlog
pg_durable — это расширение PostgreSQL. Состояние рабочего процесса, очередь, повторные попытки и восстановление хранятся в Postgres, и оно использует устойчивость Postgres / высокую доступность / резервное копирование / восстановление.
https://techcommunity.microsoft.com/blog/adforpostgresql/introducing-durable-functions-in-postgresql/4526821
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾2👀2
Перестань просто читать книги по системному дизайну и начни тестировать архитектуры на практике (с помощью Chaos Engineering) — это казалось невозможным без огромных трат на AWS.
Но эта платформа, которая уже 2 года работает в продакшене, 100% бесплатна и с открытым кодом.
Познакомьтесь с Dinamos.
Представьте, что вы симулируете инфраструктуру WhatsApp или продажу билетов на грандиозное шоу.
В Dinamos вы загружаете готовые сценарии, видите запросы, падающие на балансировщик нагрузки, и в реальном времени через «Золотые сигналы» (Golden Signals) обнаруживаете узкие места в очереди сообщений (Message Bus).
И вы можете поэкспериментировать с Chaos Engineering.
Можете намеренно добавить задержки или просто «убить» узел в своей инфраструктуре, чтобы увидеть, как система поведёт себя под нагрузкой и сможет ли она масштабироваться автоматически. На практике — без лишних сложностей.
Готовитесь к System Design интервью?
В Dinamos есть симулятор на базе фреймворка System Design Canvas. Вы рисуете схему архитектуры, записываете голосовое объяснение своего решения, а ИИ оценивает ваш ответ, подсвечивая сильные стороны и указывая, что требовало лучшего обоснования. Это бесплатный тьютор.
Проект уже 2 года развивается вместе с комьюнити. Уроки охватывают всё — от Кеширования до теорем CAP / PACELC.
И всё двуязычно (PT/EN): можете прочитать концепцию на португальском и мгновенно переключиться на английский, чтобы выучить точные термины, используемые на международном рынке.
Проект создан разработчиками для разработчиков, чтобы демократизировать доступ к высокому техническому знанию. И он будет бесплатным навсегда.
http://dinamos.net это Open Source!💵
👉 @KodBlog
Но эта платформа, которая уже 2 года работает в продакшене, 100% бесплатна и с открытым кодом.
Представьте, что вы симулируете инфраструктуру WhatsApp или продажу билетов на грандиозное шоу.
В Dinamos вы загружаете готовые сценарии, видите запросы, падающие на балансировщик нагрузки, и в реальном времени через «Золотые сигналы» (Golden Signals) обнаруживаете узкие места в очереди сообщений (Message Bus).
И вы можете поэкспериментировать с Chaos Engineering.
Можете намеренно добавить задержки или просто «убить» узел в своей инфраструктуре, чтобы увидеть, как система поведёт себя под нагрузкой и сможет ли она масштабироваться автоматически. На практике — без лишних сложностей.
Готовитесь к System Design интервью?
В Dinamos есть симулятор на базе фреймворка System Design Canvas. Вы рисуете схему архитектуры, записываете голосовое объяснение своего решения, а ИИ оценивает ваш ответ, подсвечивая сильные стороны и указывая, что требовало лучшего обоснования. Это бесплатный тьютор.
Проект уже 2 года развивается вместе с комьюнити. Уроки охватывают всё — от Кеширования до теорем CAP / PACELC.
И всё двуязычно (PT/EN): можете прочитать концепцию на португальском и мгновенно переключиться на английский, чтобы выучить точные термины, используемые на международном рынке.
Проект создан разработчиками для разработчиков, чтобы демократизировать доступ к высокому техническому знанию. И он будет бесплатным навсегда.
http://dinamos.net это Open Source!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4👍1🍾1
Claude Code постоянно добавлял слой Repository, хотя я его об этом не просил.
Я просил реализовать один endpoint в .NET API. В ответ получал интерфейс репозитория, профиль AutoMapper и структуру папок из чьего-то другого проекта. Код был вполне нормальный. Просто не мой.
Проблема не в недостатке знаний. Claude начинает каждую сессию, ничего не зная о вашем репозитории, поэтому заполняет пробелы самым распространённым вариантом, который встречал в .NET. Controllers, Repositories, AutoMapper.
Я снова и снова расплачивался за это временем на code review. Одни и те же правки, сессию за сессией, потому что всё, что я объяснял, не сохранялось до следующего раза.
Решение — один Markdown-файл в корне репозитория. Claude Code автоматически загружает его в начале каждой сессии, ещё до вашего первого запроса.
В моём файле описаны пять вещей: стек с точными версиями, структура проекта и зоны ответственности каждого слоя, команды для сборки, тестов и миграций, используемые мной паттерны (например, records для DTO и тип Result для обработки ошибок), а также паттерны, которые он не должен предлагать никогда.
Именно последний раздел делает всю работу. Фраза «Никогда не предлагай AutoMapper, используй явное маппирование» кажется мелочью, пока не понимаешь, что она делает: она блокирует неправильное поведение по умолчанию ещё до того, как Claude пойдёт по этому пути. Предотвратить неверный дефолтный выбор гораздо дешевле, чем потом проверять код и откатывать изменения.
Теперь тот же самый однострочный запрос приводит к созданию команды, валидатора и обработчика именно в тех папках, где им и место. Более того, перед тем как сообщить, что задача выполнена, Claude даже запускает тесты.
Файл, показанный на изображении, — это базовый шаблон, который я добавляю в каждый новый .NET-проект. Скопируйте его, замените раздел со стеком на свой и удалите всё, с чем не согласны. Он будет работать только в том случае, если описывает то, как строите проект вы, а не то, как это делаю я.
👉 @KodBlog
Я просил реализовать один endpoint в .NET API. В ответ получал интерфейс репозитория, профиль AutoMapper и структуру папок из чьего-то другого проекта. Код был вполне нормальный. Просто не мой.
Проблема не в недостатке знаний. Claude начинает каждую сессию, ничего не зная о вашем репозитории, поэтому заполняет пробелы самым распространённым вариантом, который встречал в .NET. Controllers, Repositories, AutoMapper.
Я снова и снова расплачивался за это временем на code review. Одни и те же правки, сессию за сессией, потому что всё, что я объяснял, не сохранялось до следующего раза.
Решение — один Markdown-файл в корне репозитория. Claude Code автоматически загружает его в начале каждой сессии, ещё до вашего первого запроса.
В моём файле описаны пять вещей: стек с точными версиями, структура проекта и зоны ответственности каждого слоя, команды для сборки, тестов и миграций, используемые мной паттерны (например, records для DTO и тип Result для обработки ошибок), а также паттерны, которые он не должен предлагать никогда.
Именно последний раздел делает всю работу. Фраза «Никогда не предлагай AutoMapper, используй явное маппирование» кажется мелочью, пока не понимаешь, что она делает: она блокирует неправильное поведение по умолчанию ещё до того, как Claude пойдёт по этому пути. Предотвратить неверный дефолтный выбор гораздо дешевле, чем потом проверять код и откатывать изменения.
Теперь тот же самый однострочный запрос приводит к созданию команды, валидатора и обработчика именно в тех папках, где им и место. Более того, перед тем как сообщить, что задача выполнена, Claude даже запускает тесты.
Файл, показанный на изображении, — это базовый шаблон, который я добавляю в каждый новый .NET-проект. Скопируйте его, замените раздел со стеком на свой и удалите всё, с чем не согласны. Он будет работать только в том случае, если описывает то, как строите проект вы, а не то, как это делаю я.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9🍾3👎1
Запомни: Монолит ≠ Модульный монолит ≠ Микросервисы
Многие команды думают, что путь выглядит так:
Монолит → Микросервисы
Но между ними есть важный этап, который многие пропускают... Модульный монолит.
Вот самый простой способ запомнить разницу:
Монолит ➜ одна кодовая база, одно развёртывание, компоненты тесно связаны между собой.
Модульный монолит ➜ одно развёртывание, но кодовая база разделена на хорошо определённые модули с чёткими границами.
Микросервисы ➜ множество независимых сервисов, которые можно разрабатывать, развёртывать и масштабировать отдельно друг от друга.
Простая шпаргалка 👇
✅ Монолит = одно приложение
✅ Модульный монолит = одно приложение, много модулей
✅ Микросервисы = множество независимых приложений
Когда использовать каждый подход?
🔹 Монолит
стартапы и MVP;
небольшие команды;
быстрая разработка;
простое развёртывание.
🔹 Модульный монолит
растущие приложения;
команды, которым нужна чистая архитектура без сложности распределённых систем;
проще тестировать, сопровождать и развивать.
🔹 Микросервисы
большие инженерные команды;
независимое развёртывание сервисов;
разные требования к масштабированию отдельных доменов;
высокая доступность и масштабируемость организации.
Самое распространённое заблуждение. Микросервисы не становятся автоматически лучшим выбором.
Они привносят распределённые транзакции, сетевые задержки, обнаружение сервисов (service discovery), наблюдаемость (observability), версионирование, пайплайны развёртывания и дополнительные операционные издержки.
Во многих случаях грамотно спроектированный модульный монолит оказывается лучшим долгосрочным решением — до тех пор, пока бизнесу действительно не понадобятся распределённые сервисы.
Фраза, которую стоит запомнить
Сохраните эту рукописную шпаргалку — она пригодится разработчикам, которые готовятся к собеседованиям по System Design или проектируют масштабируемые приложения.
👉 @KodBlog
Многие команды думают, что путь выглядит так:
Монолит → Микросервисы
Но между ними есть важный этап, который многие пропускают... Модульный монолит.
Вот самый простой способ запомнить разницу:
Монолит ➜ одна кодовая база, одно развёртывание, компоненты тесно связаны между собой.
Модульный монолит ➜ одно развёртывание, но кодовая база разделена на хорошо определённые модули с чёткими границами.
Микросервисы ➜ множество независимых сервисов, которые можно разрабатывать, развёртывать и масштабировать отдельно друг от друга.
Простая шпаргалка 👇
✅ Монолит = одно приложение
✅ Модульный монолит = одно приложение, много модулей
✅ Микросервисы = множество независимых приложений
Когда использовать каждый подход?
🔹 Монолит
стартапы и MVP;
небольшие команды;
быстрая разработка;
простое развёртывание.
🔹 Модульный монолит
растущие приложения;
команды, которым нужна чистая архитектура без сложности распределённых систем;
проще тестировать, сопровождать и развивать.
🔹 Микросервисы
большие инженерные команды;
независимое развёртывание сервисов;
разные требования к масштабированию отдельных доменов;
высокая доступность и масштабируемость организации.
Самое распространённое заблуждение. Микросервисы не становятся автоматически лучшим выбором.
Они привносят распределённые транзакции, сетевые задержки, обнаружение сервисов (service discovery), наблюдаемость (observability), версионирование, пайплайны развёртывания и дополнительные операционные издержки.
Во многих случаях грамотно спроектированный модульный монолит оказывается лучшим долгосрочным решением — до тех пор, пока бизнесу действительно не понадобятся распределённые сервисы.
Фраза, которую стоит запомнить
Монолит = простота
Модульный монолит = организованность
Микросервисы = независимость
Лучшая архитектура — не самая сложная, а та, которая решает сегодняшние задачи, не создавая завтрашних проблем.
Сохраните эту рукописную шпаргалку — она пригодится разработчикам, которые готовятся к собеседованиям по System Design или проектируют масштабируемые приложения.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥3❤1🔥1🍾1
Совет по .NET MAUI: перестаньте каждый раз проверять текущую тему приложения, когда нужно получить цвет.
Меньше кода для обработки тем. Меньше ситуаций в духе: «Почему в тёмной теме это вообще невозможно прочитать?»
👉 @KodBlog
AppThemeBinding позволяет XAML автоматически выбирать ресурсы для светлой и тёмной темы, а также обновляет их при смене системной темы во время работы приложения.Меньше кода для обработки тем. Меньше ситуаций в духе: «Почему в тёмной теме это вообще невозможно прочитать?»
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾5🔥1
Инсайд: Я думал, что довольно хорошо знаю PostgreSQL, пока не наткнулся на это.
Оказывается, PostgreSQL способен заменить гораздо больше, чем просто базу данных:
* очереди;
* cron-задачи;
* Redis;
* MongoDB;
* векторные базы данных;
* журналы аудита;
* и даже некоторые сценарии использования Kafka.
Я не говорю, что нужно заменить Postgres'ом каждый инструмент в вашем стеке.
Но мне кажется, что большинство стартапов начинают использовать Redis, Kafka, MongoDB и ещё десяток других сервисов гораздо раньше, чем в них действительно возникает необходимость.
Определённо стоит прочитать, если вы разрабатываете backend-системы. Этот материал заставил меня пересмотреть многие свои представления.
👉 @KodBlog
Оказывается, PostgreSQL способен заменить гораздо больше, чем просто базу данных:
* очереди;
* cron-задачи;
* Redis;
* MongoDB;
* векторные базы данных;
* журналы аудита;
* и даже некоторые сценарии использования Kafka.
Я не говорю, что нужно заменить Postgres'ом каждый инструмент в вашем стеке.
Но мне кажется, что большинство стартапов начинают использовать Redis, Kafka, MongoDB и ещё десяток других сервисов гораздо раньше, чем в них действительно возникает необходимость.
Определённо стоит прочитать, если вы разрабатываете backend-системы. Этот материал заставил меня пересмотреть многие свои представления.
Please open Telegram to view this post
VIEW IN TELEGRAM
Eduardo's blog
All you need is PostgreSQL
Introduction The setup Laying the foundation The foundation: schemas and user roles for modularity Domains Accounts, managed and external Transfers, constrained by a state machine and temporal periods Transfer state history Account auditing Transactions,…
👍12❤2🍾1
Создавать новый HttpClient для каждого запроса — не решение.
HttpClient владеет пулом соединений. Если постоянно его освобождать (Dispose), вы будете постоянно пересоздавать соединения и расходовать порты.
Используйте один из следующих вариантов:
- долгоживущий HttpClient + PooledConnectionLifetime;
- недолгоживущие экземпляры HttpClient, создаваемые через IHttpClientFactory.
https://learn.microsoft.com/ru-ru/dotnet/fundamentals/networking/http/httpclient-guidelines
👉 @KodBlog
HttpClient владеет пулом соединений. Если постоянно его освобождать (Dispose), вы будете постоянно пересоздавать соединения и расходовать порты.
Используйте один из следующих вариантов:
- долгоживущий HttpClient + PooledConnectionLifetime;
- недолгоживущие экземпляры HttpClient, создаваемые через IHttpClientFactory.
https://learn.microsoft.com/ru-ru/dotnet/fundamentals/networking/http/httpclient-guidelines
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🍾2
Как создать собственную социальную сеть на .NET
Это отличный проект для самостоятельной реализации.🤓
Базовая реализация платформы может включать следующие сущности:
↳ Пользователи
↳ Посты и категории
↳ Лайки и комментарии
↳ Лента
↳ Уведомления
Рассмотрим реальный кейс:
Пользователь открывает сайт соцсети и видит:
↳ Ленту с актуальными постами
↳ Свои собственные публикации
↳ Уведомления о новых постах, комментариях и лайках к интересующим его записям
Типичное frontend-приложение делает три отдельных запроса к серверу:
Получение ленты
Получение уведомлений
Получение постов пользователя
У этой реализации два ключевых недостатка:
❌ Клиенту приходится делать три отдельных запроса к серверу
❌ Клиенты получают все поля, которые возвращает сервер. Для веба это приемлемо, но для мобильных приложений — избыточно и может замедлять работу
Решение — GraphQL
GraphQL был создан как альтернатива REST, чтобы решить эти проблемы.
Hot Chocolate это самый эффективный и функциональный open-source GraphQL-сервер в экосистеме .NET. Он позволяет легко строить масштабируемые GraphQL API и шлюзы.
Преимущества Hot Chocolate по сравнению с REST API:
✅ Клиент сам выбирает, какие поля ему нужны — никакого
✅ Все данные можно запросить одним запросом, без лишних round-trip’ов
✅ Автогенерация документации, генерация кода и автодополнение в IDE синхронизируют frontend и backend
✅ Встроенные фильтрация, сортировка и пагинация — middleware всё берёт на себя, причём делает это лучше и проще, чем OData
✅ Интерфейс Nitro GraphQL позволяет визуально исследовать типы, собирать запросы и тестировать их за секунды
Автор собрал простую реализацию социальной сети на базе Hot Chocolate GraphQL, и сегодня поделился пошаговой инструкцией с разработчиками, как сделать это правильно с учётом best practices.
Исходный код доступен бесплатно.
👉 @KodBlog
Это отличный проект для самостоятельной реализации.
Базовая реализация платформы может включать следующие сущности:
↳ Пользователи
↳ Посты и категории
↳ Лайки и комментарии
↳ Лента
↳ Уведомления
Рассмотрим реальный кейс:
Пользователь открывает сайт соцсети и видит:
↳ Ленту с актуальными постами
↳ Свои собственные публикации
↳ Уведомления о новых постах, комментариях и лайках к интересующим его записям
Типичное frontend-приложение делает три отдельных запроса к серверу:
Получение ленты
GET /api/feed?userId=1&count=10
Получение уведомлений
GET /api/notifications?userId=1&count=10
Получение постов пользователя
GET /api/users/1/posts?count=10
У этой реализации два ключевых недостатка:
Решение — GraphQL
GraphQL был создан как альтернатива REST, чтобы решить эти проблемы.
Hot Chocolate это самый эффективный и функциональный open-source GraphQL-сервер в экосистеме .NET. Он позволяет легко строить масштабируемые GraphQL API и шлюзы.
Преимущества Hot Chocolate по сравнению с REST API:
overfetch/underfetchЯ использую Hot Chocolate GraphQL в продакшене уже более трёх лет, и это сильно прокачало мои подходы к построению API.
Автор собрал простую реализацию социальной сети на базе Hot Chocolate GraphQL, и сегодня поделился пошаговой инструкцией с разработчиками, как сделать это правильно с учётом best practices.
Исходный код доступен бесплатно.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥴6❤3🍾2❤🔥1😐1
Немного разобрался с тем, как работают блокировки в PostgreSQL. Главный вывод: разные SQL-команды захватывают разные режимы блокировок, и многие из них специально сделаны совместимыми друг с другом, чтобы минимизировать конкуренцию за блокировки.
Даже обычный SELECT захватывает блокировку, которая препятствует выполнению некоторых «тяжёлых» операций (например, VACUUM FULL, REINDEX и т. п.). Оказалось, существует удивительно много сочетаний SQL-команд, которые могут или не могут выполняться одновременно.
И ещё: вот отличный сайт, который наглядно показывает в виде графа, какие SQL-команды могут выполняться параллельно.
👉 @KodBlog
Даже обычный SELECT захватывает блокировку, которая препятствует выполнению некоторых «тяжёлых» операций (например, VACUUM FULL, REINDEX и т. п.). Оказалось, существует удивительно много сочетаний SQL-команд, которые могут или не могут выполняться одновременно.
И ещё: вот отличный сайт, который наглядно показывает в виде графа, какие SQL-команды могут выполняться параллельно.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4🔥2🍾1
Если версии NuGet-пакетов в вашем .NET-решении разбросаны по файлам проектов, в будущем вам неизбежно придётся заниматься их приведением в порядок.
Central Package Management позволяет вынести версии пакетов в
Проекты просто ссылаются на пакет. Версия хранится в одном файле.
Меньше археологии в зависимостях.
👉 @KodBlog
Central Package Management позволяет вынести версии пакетов в
Directory.Packages.props.Проекты просто ссылаются на пакет. Версия хранится в одном файле.
Меньше археологии в зависимостях.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🍾2
This media is not supported in your browser
VIEW IN TELEGRAM
Создавайте первоклассную документацию для своего API или проекта.
Starlight предлагает всё необходимое: высокую скорость благодаря Astro, встроенную оптимизацию для SEO, доступность и поиск, а также поддержку Markdown, MDX и нескольких языков.
→ http://starlight.astro.build/es
👉 @KodBlog
Starlight предлагает всё необходимое: высокую скорость благодаря Astro, встроенную оптимизацию для SEO, доступность и поиск, а также поддержку Markdown, MDX и нескольких языков.
→ http://starlight.astro.build/es
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🍾1
Масштабирование веб-приложений до 1 000 000 пользователей
Мне довелось работать над крупной системой, которой пользовались более миллиона человек. Вот как мы масштабировали её, чтобы она справлялась с таким объёмом трафика.
Изначально приложение представляло собой классический монолит: один сервер приложений и один сервер базы данных. Такая архитектура отлично работала несколько лет, но по мере роста числа пользователей система начала замедляться. Стало ясно, что нужны изменения.
Следующим этапом стало горизонтальное масштабирование Web API, чтобы обрабатывать большее количество запросов. Экземпляр базы данных при этом масштабировали вертикально (scale up), увеличивая его вычислительные ресурсы. Однако вскоре именно база данных стала узким местом.
Кэширование уже использовалось, но это был простой локальный кэш в памяти каждого сервера приложений. Поэтому мы внедрили распределённое кэширование на базе Redis. После этого нагрузка на базу данных значительно снизилась, поскольку большая часть запросов начала обслуживаться из кэша. Дополнительным преимуществом стало заметное улучшение производительности и отзывчивости системы.
Главная мысль, которую я хочу донести: решайте ту проблему, которая существует сейчас. Разработчики часто склонны к избыточному проектированию , пытаясь заранее подготовить систему к масштабам, которых она ещё не достигла.
И ещё один важный момент: зачем вообще масштабировать приложение, которое не приносит прибыли? Разработчики редко задумываются о финансовой стороне вопроса. Не забывайте, что приложение обычно существует для решения бизнес-задач. А бизнес сложно назвать успешным, если он не приносит прибыль.
👉 @KodBlog
Мне довелось работать над крупной системой, которой пользовались более миллиона человек. Вот как мы масштабировали её, чтобы она справлялась с таким объёмом трафика.
Изначально приложение представляло собой классический монолит: один сервер приложений и один сервер базы данных. Такая архитектура отлично работала несколько лет, но по мере роста числа пользователей система начала замедляться. Стало ясно, что нужны изменения.
Следующим этапом стало горизонтальное масштабирование Web API, чтобы обрабатывать большее количество запросов. Экземпляр базы данных при этом масштабировали вертикально (scale up), увеличивая его вычислительные ресурсы. Однако вскоре именно база данных стала узким местом.
Кэширование уже использовалось, но это был простой локальный кэш в памяти каждого сервера приложений. Поэтому мы внедрили распределённое кэширование на базе Redis. После этого нагрузка на базу данных значительно снизилась, поскольку большая часть запросов начала обслуживаться из кэша. Дополнительным преимуществом стало заметное улучшение производительности и отзывчивости системы.
Главная мысль, которую я хочу донести: решайте ту проблему, которая существует сейчас. Разработчики часто склонны к избыточному проектированию , пытаясь заранее подготовить систему к масштабам, которых она ещё не достигла.
И ещё один важный момент: зачем вообще масштабировать приложение, которое не приносит прибыли? Разработчики редко задумываются о финансовой стороне вопроса. Не забывайте, что приложение обычно существует для решения бизнес-задач. А бизнес сложно назвать успешным, если он не приносит прибыль.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👍2🍾2
Чёрт… Это может перевернуть всё представление об эмуляторах AWS.
Команда разработчиков отказалась от привычного подхода к созданию эмуляторов AWS и представила Floci.
Это один исполняемый файл на Go размером всего 13 МиБ, который менее чем за 1 секунду запускает 45 сервисов AWS (S3, Lambda, DynamoDB, SQS, SNS, IAM, CloudFormation, Step Functions и другие). Никакого Docker. Никакого LocalStack. Никаких счетов за AWS. Никаких 4 ГБ оперативной памяти, занятых контейнерами. Никакого ожидания по 30 секунд.
Достаточно скачать исполняемый файл, запустить его — и у вас локально работает практически вся инфраструктура AWS.
https://github.com/floci-io/floci
👉 @KodBlog
Команда разработчиков отказалась от привычного подхода к созданию эмуляторов AWS и представила Floci.
Это один исполняемый файл на Go размером всего 13 МиБ, который менее чем за 1 секунду запускает 45 сервисов AWS (S3, Lambda, DynamoDB, SQS, SNS, IAM, CloudFormation, Step Functions и другие). Никакого Docker. Никакого LocalStack. Никаких счетов за AWS. Никаких 4 ГБ оперативной памяти, занятых контейнерами. Никакого ожидания по 30 секунд.
Достаточно скачать исполняемый файл, запустить его — и у вас локально работает практически вся инфраструктура AWS.
https://github.com/floci-io/floci
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2🍾2
А кто-о-о это сделал: они полностью переписали PostgreSQL на Rust и он уже проходит 100% официальных тестов PostgreSQL 😔
Важно: это не форк, а полностью новая реализация с нуля на Rust, которая на данный момент:
• Проходит все 46 066 запросов из regression suite PostgreSQL 18.3.
• Совместима на уровне диска (можно запустить её напрямую с вашим текущим каталогом данных).
• Имеет рабочее демо в браузере.
Цель проекта — сделать одну из самых сложных баз данных в мире значительно проще для модификации, расширения и оптимизации изнутри, используя Rust и AI-assisted programming.
И самое безумное: уже существует WIP-версия (пока не опубликована), которая обещает быть на 50% быстрее на транзакционных нагрузках и примерно в 300 раз быстрее на аналитических нагрузках.
РЕПО 👇
https://github.com/malisper/pgrust
👉 @KodBlog
Важно: это не форк, а полностью новая реализация с нуля на Rust, которая на данный момент:
• Проходит все 46 066 запросов из regression suite PostgreSQL 18.3.
• Совместима на уровне диска (можно запустить её напрямую с вашим текущим каталогом данных).
• Имеет рабочее демо в браузере.
Цель проекта — сделать одну из самых сложных баз данных в мире значительно проще для модификации, расширения и оптимизации изнутри, используя Rust и AI-assisted programming.
И самое безумное: уже существует WIP-версия (пока не опубликована), которая обещает быть на 50% быстрее на транзакционных нагрузках и примерно в 300 раз быстрее на аналитических нагрузках.
РЕПО 👇
https://github.com/malisper/pgrust
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥15🤣5🍾1
Правильно ли вы внедряете зависимости в контроллеры?
Многие разработчики не знают об этом.
Внедрять зависимости в контроллеры можно двумя способами:
- через конструктор;
- через внедрение в метод (method injection).
Приходилось работать с раздутыми контроллерами, в конструктор которых передают слишком много зависимостей?
При этом конкретный endpoint использует лишь часть из них.
❌ В результате память расходуется впустую: все зависимости, переданные через конструктор, создаются в куче при создании контроллера — независимо от того, будут они использоваться или нет.
✅ Так почему бы не внедрять только те зависимости, которые действительно нужны, прямо в метод endpoint?
Теперь это можно делать без атрибута
Внедряя зависимости только там, где они действительно нужны, вы повышаете читаемость, упрощаете поддержку и улучшаете производительность контроллеров.
А какой подход предпочитаете вы? 👇
👉 @KodBlog
Многие разработчики не знают об этом.
Внедрять зависимости в контроллеры можно двумя способами:
- через конструктор;
- через внедрение в метод (method injection).
Приходилось работать с раздутыми контроллерами, в конструктор которых передают слишком много зависимостей?
При этом конкретный endpoint использует лишь часть из них.
❌ В результате память расходуется впустую: все зависимости, переданные через конструктор, создаются в куче при создании контроллера — независимо от того, будут они использоваться или нет.
✅ Так почему бы не внедрять только те зависимости, которые действительно нужны, прямо в метод endpoint?
Теперь это можно делать без атрибута
[FromServices] — он больше не требуется. Всё работает так же, как и в Minimal APIs.Внедряя зависимости только там, где они действительно нужны, вы повышаете читаемость, упрощаете поддержку и улучшаете производительность контроллеров.
А какой подход предпочитаете вы? 👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👎8👍4❤2🍾1
Как мигрировать монолит на микросервисы без полного переписывания системы?
Одна из широко используемых стратегий — Strangler Pattern.
Вместо того чтобы заменять всё приложение целиком, вы переносите функциональность поэтапно — по одному модулю за раз.
Например, уведомления.
Сейчас уведомления обрабатываются внутри монолита.
Вы создаёте микросервис, который берёт эту функциональность на себя.
С этого момента отправка уведомлений выполняется новым сервисом, а остальная часть приложения продолжает работать в монолите.
После того как вы убедились, что всё работает корректно, вы удаляете эту функциональность из монолита и повторяете процесс со следующим модулем.
Как это обычно реализуют?
Один из самых распространённых вариантов — разместить перед приложением API Gateway или Reverse Proxy.
Этот компонент принимает запросы и решает, куда их направить:
в монолит;
в новый микросервис.
Так старая и новая системы могут сосуществовать на протяжении всей миграции.
👉 @KodBlog
Одна из широко используемых стратегий — Strangler Pattern.
Вместо того чтобы заменять всё приложение целиком, вы переносите функциональность поэтапно — по одному модулю за раз.
Например, уведомления.
Сейчас уведомления обрабатываются внутри монолита.
Вы создаёте микросервис, который берёт эту функциональность на себя.
С этого момента отправка уведомлений выполняется новым сервисом, а остальная часть приложения продолжает работать в монолите.
После того как вы убедились, что всё работает корректно, вы удаляете эту функциональность из монолита и повторяете процесс со следующим модулем.
Как это обычно реализуют?
Один из самых распространённых вариантов — разместить перед приложением API Gateway или Reverse Proxy.
Этот компонент принимает запросы и решает, куда их направить:
в монолит;
в новый микросервис.
Так старая и новая системы могут сосуществовать на протяжении всей миграции.
Please open Telegram to view this post
VIEW IN TELEGRAM
🍾3
Совет по GitHub Actions: не предоставляйте
Задаче сборки обычно достаточно прав на чтение.
Задаче публикации релиза могут потребоваться права на запись.
Боту, работающему с issues или комментариями, нужен уже другой набор разрешений.
Настраивайте
https://docs.github.com/en/actions/tutorials/authenticate-with-github_token
👉 @KodBlog
GITHUB_TOKEN больше прав доступа, чем действительно требуется конкретной задаче Задаче сборки обычно достаточно прав на чтение.
Задаче публикации релиза могут потребоваться права на запись.
Боту, работающему с issues или комментариями, нужен уже другой набор разрешений.
Настраивайте
permissions отдельно для каждого workflow или конкретной задачи. Начинайте с минимально необходимых прав и добавляйте новые только тогда, когда без них действительно что-то перестаёт работать.https://docs.github.com/en/actions/tutorials/authenticate-with-github_token
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🍾1
Модель предметной области (Domain Model) и DTO решают две разные задачи. В тот момент, когда один класс начинает выполнять обе, вы создаете ловушку для самого себя в будущем.
Вот с чего начинается большинство проектов. Один класс
Именно эта надежда и является проблемой.
Добавили новый столбец в базу данных, забыли про атрибут — и внутренний
Разделите их — и конфликт исчезнет.
Оставьте в доменной модели класс
Теперь внутренние поля не могут «утечь», потому что их просто нет в классе, который возвращает API. Доменная модель может свободно меняться в соответствии с требованиями бизнеса. Контракт API изменяется только тогда, когда вы сами принимаете такое решение. А версионирование становится предсказуемым и скучным в хорошем смысле слова: вы просто добавляете новый DTO.
Главное различие заключается в вопросе, на который отвечает каждый класс. Доменная модель отвечает на вопрос: «Какие здесь действуют бизнес-правила?». DTO отвечает на вопрос: «Что должен видеть внешний мир?». И почти никогда это не один и тот же ответ.
Два класса кажутся лишней работой в первый день, но могут избавить вас от ломающего изменения на девяностый.
Стоит поделиться этим, если ваше API хоть раз случайно отдавало данные, которые не должно было.
👉 @KodBlog
Вот с чего начинается большинство проектов. Один класс
Product. В нем есть Id, Name и Price, а также InternalSku и CostPrice, которые внешний мир никогда не должен видеть. Поэтому вы ставите [JsonIgnore] на внутренние поля и надеетесь, что никто не добавит новое свойство, забыв его скрыть.Именно эта надежда и является проблемой.
Добавили новый столбец в базу данных, забыли про атрибут — и внутренний
CostPrice уходит клиенту. Достаточно одной миграции EF Core, чтобы контракт вашего публичного API незаметно изменился. Один класс выполняет две разные задачи, и они начинают конфликтовать каждый раз, когда вы что-то меняете.Разделите их — и конфликт исчезнет.
Оставьте в доменной модели класс
Product, который содержит InternalSku и CostPrice как init-only свойства, а также всю бизнес-логику. Отдельно создайте record ProductDto, в котором будут только Id, Name и Price. Именно этот тип и должен возвращаться наружу.Теперь внутренние поля не могут «утечь», потому что их просто нет в классе, который возвращает API. Доменная модель может свободно меняться в соответствии с требованиями бизнеса. Контракт API изменяется только тогда, когда вы сами принимаете такое решение. А версионирование становится предсказуемым и скучным в хорошем смысле слова: вы просто добавляете новый DTO.
Главное различие заключается в вопросе, на который отвечает каждый класс. Доменная модель отвечает на вопрос: «Какие здесь действуют бизнес-правила?». DTO отвечает на вопрос: «Что должен видеть внешний мир?». И почти никогда это не один и тот же ответ.
Два класса кажутся лишней работой в первый день, но могут избавить вас от ломающего изменения на девяностый.
Стоит поделиться этим, если ваше API хоть раз случайно отдавало данные, которые не должно было.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍4🍾2