День восемьсот восемьдесят второй. #ЧтоНовенького
Горячая Перезагрузка и Другие Обновления ASP.NET Core в .NET 6 Preview 5
Горячая Перезагрузка (Hot Reload) - долгожданная функциональность, позволяющая разработчикам вносить изменения в код во время отладки, которые мгновенно отражаются в работающем приложении без необходимости перезапуска - была представлена на конференции разработчиков May Build. Она поддерживалась в ранней неполной форме в Visual Studio 2019 версии 16.11 Preview 1. С тех пор были добавлены дополнительные улучшения.
Для ASP.NET Core основное улучшение Hot Reload затрагивает
Больше не нужно указывать hotReloadProfile в launchSettings.json. .NET Hot Reload с соответствующим поведением проекта теперь включена по умолчанию. Когда вносится изменение, которое не может быть перезагружено горячим способом («грубое» изменение), dotnet watch теперь спросит, хотите ли вы перезапустить приложение, чтобы применить изменение. «Грубые» изменения в приложениях Blazor WebAssembly будут применены при обновлении браузера или при загрузке приложения в отдельной вкладке или новом окне браузера.
Размеры загружаемых файлов Blazor WebAssembly были уменьшены с помощью функции, известной как повторное связывание (relinking). Она позволяет исключить ненужную логику выполнения - такую как глобализация - из загрузки.
Другие новинки ASP.NET Core .NET 6 Preview 5:
- Шаблоны ASP.NET Core SPA обновлены до Angular 11 и React 17
- Использование синтаксиса Razor в элементах SVG foreignObject
- Настраиваемый порог буфера перед записью на диск в Json.NET
- Подкатегории для лучшей фильтрации журналов Kestrel
- Более быстрое получение и установка заголовков HTTP
- Настраиваемый размер входящего буфера для IIS
Пока существуют известные проблемы с использованием ASP.NET Core в .NET 6 Preview 5:
1. Начиная с .NET 6 Preview 1, существует проблема с запуском приложений Blazor WebAssembly с использованием сервера IIS Express во время разработки в Visual Studio. Чтобы обойти это, рекомендуется использовать Kestrel во время разработки.
2. Начиная с .NET 6 Preview 3, изменения представлений Razor не будут обновляться во время инкрементных сборок. Чтобы обойти это, вы можете:
- Осуществлять сборку из командной строки
- Настроить VS, чтобы всегда вызывать MSBuild при сборке проектов
- Очищать и собирать проекты, чтобы изменения отражались
3. Начиная с .NET 6 Preview 5, при использовании обработчика JWT Bearer в часовом поясе выше, чем UTC (например, UTC+2), вы можете наблюдать исключение
Вы можете обойти это, всегда предоставляя ненулевое и не минимальное значение для параметра
Источник: https://visualstudiomagazine.com/articles/2021/06/18/aspnet-core-updates.aspx
Горячая Перезагрузка и Другие Обновления ASP.NET Core в .NET 6 Preview 5
Горячая Перезагрузка (Hot Reload) - долгожданная функциональность, позволяющая разработчикам вносить изменения в код во время отладки, которые мгновенно отражаются в работающем приложении без необходимости перезапуска - была представлена на конференции разработчиков May Build. Она поддерживалась в ранней неполной форме в Visual Studio 2019 версии 16.11 Preview 1. С тех пор были добавлены дополнительные улучшения.
Для ASP.NET Core основное улучшение Hot Reload затрагивает
dotnet watch
- инструмент командной строки (CLI), который выполняет команду .NET Core при изменении исходных файлов и обновляет браузер при обнаружении изменений в наблюдаемых файлах. Это позволяет перезагружать проекты ASP.NET Core в реальном времени.Больше не нужно указывать hotReloadProfile в launchSettings.json. .NET Hot Reload с соответствующим поведением проекта теперь включена по умолчанию. Когда вносится изменение, которое не может быть перезагружено горячим способом («грубое» изменение), dotnet watch теперь спросит, хотите ли вы перезапустить приложение, чтобы применить изменение. «Грубые» изменения в приложениях Blazor WebAssembly будут применены при обновлении браузера или при загрузке приложения в отдельной вкладке или новом окне браузера.
Размеры загружаемых файлов Blazor WebAssembly были уменьшены с помощью функции, известной как повторное связывание (relinking). Она позволяет исключить ненужную логику выполнения - такую как глобализация - из загрузки.
Другие новинки ASP.NET Core .NET 6 Preview 5:
- Шаблоны ASP.NET Core SPA обновлены до Angular 11 и React 17
- Использование синтаксиса Razor в элементах SVG foreignObject
- Настраиваемый порог буфера перед записью на диск в Json.NET
- Подкатегории для лучшей фильтрации журналов Kestrel
- Более быстрое получение и установка заголовков HTTP
- Настраиваемый размер входящего буфера для IIS
Пока существуют известные проблемы с использованием ASP.NET Core в .NET 6 Preview 5:
1. Начиная с .NET 6 Preview 1, существует проблема с запуском приложений Blazor WebAssembly с использованием сервера IIS Express во время разработки в Visual Studio. Чтобы обойти это, рекомендуется использовать Kestrel во время разработки.
2. Начиная с .NET 6 Preview 3, изменения представлений Razor не будут обновляться во время инкрементных сборок. Чтобы обойти это, вы можете:
- Осуществлять сборку из командной строки
- Настроить VS, чтобы всегда вызывать MSBuild при сборке проектов
- Очищать и собирать проекты, чтобы изменения отражались
3. Начиная с .NET 6 Preview 5, при использовании обработчика JWT Bearer в часовом поясе выше, чем UTC (например, UTC+2), вы можете наблюдать исключение
ArgumentOutOfRangeException
, если токен JWT не содержит значение nbf
(Действует с). Проблема отслеживается здесь и будет исправлена в .NET 6 Preview 6.Вы можете обойти это, всегда предоставляя ненулевое и не минимальное значение для параметра
notBefore
при использовании System.IdentityModel.Tokens.Jwt.JwtSecurityToken или поле 'nbf
' при использовании другой библиотеки JWT.Источник: https://visualstudiomagazine.com/articles/2021/06/18/aspnet-core-updates.aspx
День восемьсот восемьдесят третий. #DesignPatterns #Microservices
Микросервисная Архитектура и Паттерны Проектирования
Существует множество определений микросервисной архитектуры. Вот одно из них:
Микросервисная архитектура представляет собой вертикальное разделение больших сложных систем (по функциональным или бизнес-требованиям) на более мелкие подсистемы, которые являются отдельными процессами (следовательно, могут развёртываться независимо), и эти подсистемы взаимодействуют друг с другом через лёгкие, не зависящие от языка сетевые вызовы либо синхронным (например, через REST, gRPC) или асинхронным (через обмен сообщениями) способом.
Компонентное представление бизнес-веб-приложения с микросервисной архитектурой представлено на рисунке ниже.
Характеристики:
- Всё приложение разделено на отдельные процессы, каждый из которых может содержать несколько внутренних модулей.
- В отличие от модульных монолитов или сервисно-ориентированной архитектуры, микросервисное приложение разделено по вертикали (в соответствии с бизнес-потребностями или доменами).
- Границы микросервисов внешние, то есть микросервисы взаимодействуют друг с другом через сетевые вызовы (RPC или сообщения).
- Поскольку микросервисы являются независимыми процессами, их можно развёртывать независимо.
- Они общаются легко и не нуждаются в каком-то хитром канале связи.
Преимущества:
- Лучшее масштабирование разработки.
- Более высокая скорость разработки.
- Поддерживается итеративная или инкрементная модернизация.
- Возможность использовать преимущества современной экосистемы разработки ПО (облако, контейнеры, DevOps, бессерверная среда).
- Поддерживается как горизонтальное, так и гранулярное масштабирование (возможность масштабировать отдельные микросервисы).
- Благодаря меньшему размеру, снижается нагрузка на разработчиков, которым не приходится держать в голове большую систему.
Недостатки:
- Большее количество элементов (сервисы, базы данных, процессы, контейнеры, фреймворки).
- Сложность переходит от кода к инфраструктуре.
- Большее количество вызовов RPC и сетевого трафика.
- Управление безопасностью всей системы является сложной задачей.
- Проектировать всю систему сложнее.
- Возникают сложности распределённых систем.
Варианты использования:
- Разработка веб-приложений.
- Разработка корпоративных приложений, когда над приложением работают несколько команд.
- В случаях, когда долгосрочный эффект предпочтительнее краткосрочного.
- В команде есть архитекторы ПО, способные разработать микросервисную архитектуру.
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Микросервисная Архитектура и Паттерны Проектирования
Существует множество определений микросервисной архитектуры. Вот одно из них:
Микросервисная архитектура представляет собой вертикальное разделение больших сложных систем (по функциональным или бизнес-требованиям) на более мелкие подсистемы, которые являются отдельными процессами (следовательно, могут развёртываться независимо), и эти подсистемы взаимодействуют друг с другом через лёгкие, не зависящие от языка сетевые вызовы либо синхронным (например, через REST, gRPC) или асинхронным (через обмен сообщениями) способом.
Компонентное представление бизнес-веб-приложения с микросервисной архитектурой представлено на рисунке ниже.
Характеристики:
- Всё приложение разделено на отдельные процессы, каждый из которых может содержать несколько внутренних модулей.
- В отличие от модульных монолитов или сервисно-ориентированной архитектуры, микросервисное приложение разделено по вертикали (в соответствии с бизнес-потребностями или доменами).
- Границы микросервисов внешние, то есть микросервисы взаимодействуют друг с другом через сетевые вызовы (RPC или сообщения).
- Поскольку микросервисы являются независимыми процессами, их можно развёртывать независимо.
- Они общаются легко и не нуждаются в каком-то хитром канале связи.
Преимущества:
- Лучшее масштабирование разработки.
- Более высокая скорость разработки.
- Поддерживается итеративная или инкрементная модернизация.
- Возможность использовать преимущества современной экосистемы разработки ПО (облако, контейнеры, DevOps, бессерверная среда).
- Поддерживается как горизонтальное, так и гранулярное масштабирование (возможность масштабировать отдельные микросервисы).
- Благодаря меньшему размеру, снижается нагрузка на разработчиков, которым не приходится держать в голове большую систему.
Недостатки:
- Большее количество элементов (сервисы, базы данных, процессы, контейнеры, фреймворки).
- Сложность переходит от кода к инфраструктуре.
- Большее количество вызовов RPC и сетевого трафика.
- Управление безопасностью всей системы является сложной задачей.
- Проектировать всю систему сложнее.
- Возникают сложности распределённых систем.
Варианты использования:
- Разработка веб-приложений.
- Разработка корпоративных приложений, когда над приложением работают несколько команд.
- В случаях, когда долгосрочный эффект предпочтительнее краткосрочного.
- В команде есть архитекторы ПО, способные разработать микросервисную архитектуру.
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍1
День восемьсот восемьдесят четвёртый. #DesignPatterns #Microservices
Паттерны в Микросервисах
1. База Данных на Микросервис
Когда компания заменяет большую монолитную систему множеством мелких микросервисов, самое важное решение, с которым она сталкивается, - это база данных. В монолитной архитектуре используется большая централизованная база данных. Многие архитекторы предпочитают сохранять базу данных как есть, даже при переходе на микросервисную архитектуру. Хотя это даёт некоторую краткосрочную выгоду, это анти-шаблон, особенно в крупной системе, поскольку микросервисы будут тесно связаны на уровне базы данных. Весь смысл перехода на микросервисы (расширение возможностей команды, независимая разработка) потеряется.
Лучший подход - предоставить каждому микросервису собственное хранилище данных, чтобы не было сильной связи между службами на уровне базы данных (см. рисунок ниже). Здесь термин «база данных» используется, чтобы показать логическое разделение данных, то есть микросервисы могут совместно использовать одну и ту же физическую базу данных, но они должны использовать отдельную схему/коллекцию/таблицу. Это также гарантирует, что микросервисы правильно разделены в соответствии с предметно-ориентированным проектированием (DDD).
Плюсы
- Полное владение данными для каждого сервиса.
- Слабая связь между командами, разрабатывающими сервисы.
Минусы
- Обмен данными между службами становится проблематичным.
- Предоставление транзакционной гарантии ACID для приложения становится намного сложнее.
- Разделение монолитной базы данных на более мелкие части требует тщательного проектирования и является сложной задачей.
Когда использовать:
- В крупномасштабных корпоративных приложениях.
- Когда команде необходимо полное владение своими микросервисами для масштабирования и скорости разработки.
Когда не использовать:
- В небольших приложениях.
- Если одна команда разработает все микросервисы.
Поддержка
Все базы данных SQL и NoSQL предлагают логическое разделение данных (например, отдельные таблицы, коллекции, схемы, базы данных).
Подробнее:
- Microservices Pattern: Database per service
- Распределённые данные
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
1. База Данных на Микросервис
Когда компания заменяет большую монолитную систему множеством мелких микросервисов, самое важное решение, с которым она сталкивается, - это база данных. В монолитной архитектуре используется большая централизованная база данных. Многие архитекторы предпочитают сохранять базу данных как есть, даже при переходе на микросервисную архитектуру. Хотя это даёт некоторую краткосрочную выгоду, это анти-шаблон, особенно в крупной системе, поскольку микросервисы будут тесно связаны на уровне базы данных. Весь смысл перехода на микросервисы (расширение возможностей команды, независимая разработка) потеряется.
Лучший подход - предоставить каждому микросервису собственное хранилище данных, чтобы не было сильной связи между службами на уровне базы данных (см. рисунок ниже). Здесь термин «база данных» используется, чтобы показать логическое разделение данных, то есть микросервисы могут совместно использовать одну и ту же физическую базу данных, но они должны использовать отдельную схему/коллекцию/таблицу. Это также гарантирует, что микросервисы правильно разделены в соответствии с предметно-ориентированным проектированием (DDD).
Плюсы
- Полное владение данными для каждого сервиса.
- Слабая связь между командами, разрабатывающими сервисы.
Минусы
- Обмен данными между службами становится проблематичным.
- Предоставление транзакционной гарантии ACID для приложения становится намного сложнее.
- Разделение монолитной базы данных на более мелкие части требует тщательного проектирования и является сложной задачей.
Когда использовать:
- В крупномасштабных корпоративных приложениях.
- Когда команде необходимо полное владение своими микросервисами для масштабирования и скорости разработки.
Когда не использовать:
- В небольших приложениях.
- Если одна команда разработает все микросервисы.
Поддержка
Все базы данных SQL и NoSQL предлагают логическое разделение данных (например, отдельные таблицы, коллекции, схемы, базы данных).
Подробнее:
- Microservices Pattern: Database per service
- Распределённые данные
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
День восемьсот восемьдесят пятый. #Оффтоп #97Вещей
97 Вещей, Которые Должен Знать Каждый Программист
90. Навыки, Необходимые Сеньору, Помимо Программирования
Сегодня вашему вниманию несколько шуточный список навыков, которыми должен обладать старший разработчик или тимлид. Предлагайте свои варианты в комментариях.
1. Как провести собрание. И нет, больше всего говорить на собрании, не то же самое, что проводить его.
2. Как написать проектную документацию, получить отзывы и довести её до решения в разумные сроки.
3. Как подсказать товарищу по команде, начинающему карьеру, инженеру в середине карьеры, новому менеджеру, которому нужен технический совет.
4. Как говорить со старшим менеджером о технических вещах, в которых он на самом деле ничего не понимает, не закатывая глаза и не заставляя его чувствовать себя глупо.
5. Как объяснить техническую концепцию важному начальнику, который стесняется признаться, что он её не понимает.
6. Как убедить другую команду использовать ваше решение вместо написания собственного.
7. Как заставить другого инженера сделать что-то для вас, попросив о помощи таким образом, чтобы он почувствовал, что его ценят.
8. Как вести проект, даже если вы не управляете никем из людей, работающих над ним.
9. Как заставить других инженеров прислушиваться к вашим идеям, не заставляя их чувствовать в вас угрозу.
10. Как прислушиваться к идеям других инженеров и не чувствовать в них угрозы.
11. Как отказаться от своего ребёнка (от проекта, который вы превратили во что-то существенное), чтобы заняться чем-то другим.
12. Как научить другого инженера заботиться о том, что вас действительно волнует (операции, форматирование, тестирование, качество кода, производительность, простота и т.д.).
13. Как правильно сообщать о статусе проекта инвесторам.
14. Как убедить руководство в том, что им нужно инвестировать в нетривиальный технический проект.
15. Как создавать программное обеспечение, привнося при этом дополнительную ценность в процессе.
16. Как составить проектное предложение, разрекламировать его и получить поддержку для его реализации.
17. Сколько раз достаточно повторить, чтобы люди начали слушать.
18. Как выбрать правильных бойцов в команду.
19. Как помочь кому-то продвинуться по службе.
20. Как получить информацию о том, что на самом деле происходит (как сплетничать, как найти подход к разным людям).
21. Как найти интересную работу самостоятельно, а не ждать, пока кто-то её вам принесет.
22. Как сказать кому-то, что он неправ, не унизив его.
23. Как правильно воспринимать отрицательные отзывы.
Источник: https://skamille.medium.com/an-incomplete-list-of-skills-senior-engineers-need-beyond-coding-8ed4a521b29f
Автор оригинала – Camille Fournier
97 Вещей, Которые Должен Знать Каждый Программист
90. Навыки, Необходимые Сеньору, Помимо Программирования
Сегодня вашему вниманию несколько шуточный список навыков, которыми должен обладать старший разработчик или тимлид. Предлагайте свои варианты в комментариях.
1. Как провести собрание. И нет, больше всего говорить на собрании, не то же самое, что проводить его.
2. Как написать проектную документацию, получить отзывы и довести её до решения в разумные сроки.
3. Как подсказать товарищу по команде, начинающему карьеру, инженеру в середине карьеры, новому менеджеру, которому нужен технический совет.
4. Как говорить со старшим менеджером о технических вещах, в которых он на самом деле ничего не понимает, не закатывая глаза и не заставляя его чувствовать себя глупо.
5. Как объяснить техническую концепцию важному начальнику, который стесняется признаться, что он её не понимает.
6. Как убедить другую команду использовать ваше решение вместо написания собственного.
7. Как заставить другого инженера сделать что-то для вас, попросив о помощи таким образом, чтобы он почувствовал, что его ценят.
8. Как вести проект, даже если вы не управляете никем из людей, работающих над ним.
9. Как заставить других инженеров прислушиваться к вашим идеям, не заставляя их чувствовать в вас угрозу.
10. Как прислушиваться к идеям других инженеров и не чувствовать в них угрозы.
11. Как отказаться от своего ребёнка (от проекта, который вы превратили во что-то существенное), чтобы заняться чем-то другим.
12. Как научить другого инженера заботиться о том, что вас действительно волнует (операции, форматирование, тестирование, качество кода, производительность, простота и т.д.).
13. Как правильно сообщать о статусе проекта инвесторам.
14. Как убедить руководство в том, что им нужно инвестировать в нетривиальный технический проект.
15. Как создавать программное обеспечение, привнося при этом дополнительную ценность в процессе.
16. Как составить проектное предложение, разрекламировать его и получить поддержку для его реализации.
17. Сколько раз достаточно повторить, чтобы люди начали слушать.
18. Как выбрать правильных бойцов в команду.
19. Как помочь кому-то продвинуться по службе.
20. Как получить информацию о том, что на самом деле происходит (как сплетничать, как найти подход к разным людям).
21. Как найти интересную работу самостоятельно, а не ждать, пока кто-то её вам принесет.
22. Как сказать кому-то, что он неправ, не унизив его.
23. Как правильно воспринимать отрицательные отзывы.
Источник: https://skamille.medium.com/an-incomplete-list-of-skills-senior-engineers-need-beyond-coding-8ed4a521b29f
Автор оригинала – Camille Fournier
День восемьсот восемьдесят шестой. #ЗаметкиНаПолях
Начиная с .NET 5 Изменение Значений в Dictionary в Foreach не Выбрасывает Исключения
Давно известно, что внутри цикла
System.InvalidOperationException: Collection was modified; enumeration operation may not execute. (Коллекция изменена; операция перечисления не может быть выполнена.)
Однако, начиная с .NET 5, он выполняется без проблем. Что случилось?
В исходный код
Удаление из словаря с помощью метода Remove также больше не влияет на перечисление. Это, однако, существует с .NET Core 3.0 и соответствующим образом упоминается в документации метода
«Только .NET Core 3.0+: Этот метод изменения может быть безопасно вызван без аннуляции активных перечислителей экземпляра Dictionary<TKey,TValue>. Но это не подразумевает потокобезопасность.»
Несмотря на то, что вышеупомянутое изменение значений при перечислении просят внести в документацию, на момент выхода этого поста, этого пока не сделано.
Источник: https://stackoverflow.com/questions/66939923/what-changed-in-net-5-that-makes-it-not-throw-when-changing-dictionary-values-i
Начиная с .NET 5 Изменение Значений в Dictionary в Foreach не Выбрасывает Исключения
Давно известно, что внутри цикла
foreach
нельзя изменять элементы коллекции. Однако, рассмотрим следующий код:var d = new Dictionary<string, int>
{ { "a", 0 }, { "b", 0 }, { "c", 0 } };
foreach (var k in d.Keys)
{
d[k]+=1;
}
В .NET Core 3.1 и ранее этот код выдавал ожидаемое исключение:System.InvalidOperationException: Collection was modified; enumeration operation may not execute. (Коллекция изменена; операция перечисления не может быть выполнена.)
Однако, начиная с .NET 5, он выполняется без проблем. Что случилось?
В исходный код
Dictionary<TKey, TValue>
было внесено изменение, позволяющее обновлять значения по существующим ключам во время перечисления. Убрали обновление внутреннего поля _version при изменении элементов. Поле _version (которое используется для обнаружения изменений) теперь обновляется только при определённых условиях, но не при изменении значения по существующему ключу.Удаление из словаря с помощью метода Remove также больше не влияет на перечисление. Это, однако, существует с .NET Core 3.0 и соответствующим образом упоминается в документации метода
Remove
:«Только .NET Core 3.0+: Этот метод изменения может быть безопасно вызван без аннуляции активных перечислителей экземпляра Dictionary<TKey,TValue>. Но это не подразумевает потокобезопасность.»
Несмотря на то, что вышеупомянутое изменение значений при перечислении просят внести в документацию, на момент выхода этого поста, этого пока не сделано.
Источник: https://stackoverflow.com/questions/66939923/what-changed-in-net-5-that-makes-it-not-throw-when-changing-dictionary-values-i
День восемьсот восемьдесят седьмой. #DesignPatterns #Microservices
Паттерны в Микросервисах
2. Источники Событий (Event Sourcing)
В микросервисной архитектуре, особенно с использованием паттерна «База данных на микросервис», микросервисы должны обмениваться данными. Для отказоустойчивых, высокомасштабируемых и отказоустойчивых систем они должны обмениваться данными асинхронно, обмениваясь Событиями. В этом случае вам может понадобиться выполнить атомарные операции, например, обновить базу данных и отправить сообщение. Если у вас есть базы данных SQL и вы хотите иметь распределённые транзакции для большого объема данных, вы не можете использовать двухфазную блокировку (2PL), поскольку она не масштабируется. Если вы используете базы данных NoSQL и хотите иметь распределённую транзакцию, вы не можете использовать 2PL, поскольку многие базы данных NoSQL не поддерживают двухфазную блокировку.
В таких сценариях используйте архитектуру на основе событий. В традиционных базах данных бизнес-объект с текущим «состоянием» сохраняется напрямую. В Event Sourcing любое событие, изменяющее состояние, или другие важные события сохраняются вместо сущностей. Это означает, что изменения бизнес-объекта сохраняются в виде серии неизменяемых событий. Состояние бизнес-объекта высчитывается путём повторной обработки всех событий этого бизнес-объекта в заданное время. Поскольку данные сохраняются в виде серии событий, а не через прямые обновления в хранилищах данных, различные службы могут воспроизводить события из хранилища событий, чтобы вычислить необходимое состояние соответствующих хранилищ данных. См. картинку ниже.
Плюсы
- Обеспечение атомарности высокомасштабируемым системам.
- Автоматическое сохранение истории сущностей, включая функционал «путешествий во времени».
- Возможность создания слабосвязанных микросервисов, управляемых событиями.
Минусы
- Чтение сущностей из хранилища событий становится сложной задачей и обычно требует дополнительного хранилища данных (паттерн CQRS)
- Общая сложность системы возрастает, и обычно требуется доменно-ориентированный дизайн.
- Система должна обрабатывать повторяющиеся события (идемпотентные) или отсутствующие события.
- Миграция схемы событий становится сложной задачей.
Когда использовать:
- Высокомасштабируемые транзакционные системы с базами данных SQL.
- Транзакционные системы с базами данных NoSQL.
- Высоко масштабируемая и устойчивая микросервисная архитектура.
- Типичные системы, управляемые сообщениями или событиями (системы электронной коммерции, бронирования и резервирования).
Когда не использовать:
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В простой микросервисной архитектуре, где микросервисы могут синхронно обмениваться данными (например, через API).
Поддержка
Хранилища: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB.
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- Microservices Pattern: Event sourcing
- Шаблон источников событий
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
2. Источники Событий (Event Sourcing)
В микросервисной архитектуре, особенно с использованием паттерна «База данных на микросервис», микросервисы должны обмениваться данными. Для отказоустойчивых, высокомасштабируемых и отказоустойчивых систем они должны обмениваться данными асинхронно, обмениваясь Событиями. В этом случае вам может понадобиться выполнить атомарные операции, например, обновить базу данных и отправить сообщение. Если у вас есть базы данных SQL и вы хотите иметь распределённые транзакции для большого объема данных, вы не можете использовать двухфазную блокировку (2PL), поскольку она не масштабируется. Если вы используете базы данных NoSQL и хотите иметь распределённую транзакцию, вы не можете использовать 2PL, поскольку многие базы данных NoSQL не поддерживают двухфазную блокировку.
В таких сценариях используйте архитектуру на основе событий. В традиционных базах данных бизнес-объект с текущим «состоянием» сохраняется напрямую. В Event Sourcing любое событие, изменяющее состояние, или другие важные события сохраняются вместо сущностей. Это означает, что изменения бизнес-объекта сохраняются в виде серии неизменяемых событий. Состояние бизнес-объекта высчитывается путём повторной обработки всех событий этого бизнес-объекта в заданное время. Поскольку данные сохраняются в виде серии событий, а не через прямые обновления в хранилищах данных, различные службы могут воспроизводить события из хранилища событий, чтобы вычислить необходимое состояние соответствующих хранилищ данных. См. картинку ниже.
Плюсы
- Обеспечение атомарности высокомасштабируемым системам.
- Автоматическое сохранение истории сущностей, включая функционал «путешествий во времени».
- Возможность создания слабосвязанных микросервисов, управляемых событиями.
Минусы
- Чтение сущностей из хранилища событий становится сложной задачей и обычно требует дополнительного хранилища данных (паттерн CQRS)
- Общая сложность системы возрастает, и обычно требуется доменно-ориентированный дизайн.
- Система должна обрабатывать повторяющиеся события (идемпотентные) или отсутствующие события.
- Миграция схемы событий становится сложной задачей.
Когда использовать:
- Высокомасштабируемые транзакционные системы с базами данных SQL.
- Транзакционные системы с базами данных NoSQL.
- Высоко масштабируемая и устойчивая микросервисная архитектура.
- Типичные системы, управляемые сообщениями или событиями (системы электронной коммерции, бронирования и резервирования).
Когда не использовать:
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В простой микросервисной архитектуре, где микросервисы могут синхронно обмениваться данными (например, через API).
Поддержка
Хранилища: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB.
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- Microservices Pattern: Event sourcing
- Шаблон источников событий
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍4
Конференция по .NET-разработке DotNext ищет спикеров 🎙
Вам есть о чем рассказать и что обсудить с коллегами по цеху? Тогда вам нужно подать заявку на участие в конференции!
Осенью DotNext пройдет 18-21 октября, онлайн (гибридный формат решили отложить из-за непредсказуемости ввода ограничений на офлайн мероприятия).
Темы, которые ждут больше всего:
✔️ Internals;
✔️ Architecture;
✔️ Security;
✔️ Performance;
✔️ DevOps & Tools.
Но не ограничивайте себя этим списком — вы можете подать заявку с любой темой из области .NET-разработки.
Если все-таки сомневаетесь, то программный комитет всегда готов обсудить актуальность темы и помочь выбрать правильный вектор доклада. Плюс, ребята помогут с прокачкой ваших ораторских навыков, если у вас мало опыта в публичных выступлениях.
✅ Подать заявку и узнать подробности можно на сайте.
❓Вопросы присылайте на почту [email protected]
Вам есть о чем рассказать и что обсудить с коллегами по цеху? Тогда вам нужно подать заявку на участие в конференции!
Осенью DotNext пройдет 18-21 октября, онлайн (гибридный формат решили отложить из-за непредсказуемости ввода ограничений на офлайн мероприятия).
Темы, которые ждут больше всего:
✔️ Internals;
✔️ Architecture;
✔️ Security;
✔️ Performance;
✔️ DevOps & Tools.
Но не ограничивайте себя этим списком — вы можете подать заявку с любой темой из области .NET-разработки.
Если все-таки сомневаетесь, то программный комитет всегда готов обсудить актуальность темы и помочь выбрать правильный вектор доклада. Плюс, ребята помогут с прокачкой ваших ораторских навыков, если у вас мало опыта в публичных выступлениях.
✅ Подать заявку и узнать подробности можно на сайте.
❓Вопросы присылайте на почту [email protected]
День восемьсот восемьдесят восьмой. #TypesAndLanguages
4. Проблема Алмаза. Начало
Проблема Алмаза, иногда называемая Смертельным Алмазом Смерти, возникает, когда мы наследуем одно и то же через несколько базовых сущностей. Если вы думаете, что «проблема есть в C++, но её не существует в Java или C#», то вы слишком сосредотачиваетесь на технической части.
Наследование
Обычно мы говорим, что в Java или C# существует одиночное наследование и множественная реализация интерфейсов. Это правда, но за этим скрывается гораздо более широкая картина.
Наследование позволяет наследовать характеристики и функции от базовой сущности (в большинстве случаев от класса или объекта). Есть много вещей, которые мы можем унаследовать, или много уровней наследования:
1. Наследование сигнатуры
В интерфейсе объявлен метод, мы наследуем его и предоставляем реализацию. Сигнатура здесь означает, что это только «заголовок» метода, без тела. Важно понимать, что эта «сигнатура наследования» не обязательно должна совпадать с «сигнатурой вызова». Например, вы не можете изменить тип возвращаемого значения при реализации интерфейса в C#, но тип возвращаемого значения не является частью «сигнатуры вызова». Java допускает это, но это детали реализации. Когда мы говорим о «наследовании сигнатуры», мы имеем в виду только заголовок метода, который мы получаем от базовой сущности.
2. Наследование реализации
При наследовании реализации мы получаем не только сигнатуру, но и всё тело метода. Это не так давно стало доступно в Java или C# через реализации интерфейса по умолчанию. Это можно рассматривать как типажи (traits). И хотя между наследованием реализации и трейтами есть некоторые различия, они довольно близки друг к другу.
3. Наследование состояния
Это наследование полей. При наследовании состояния мы получаем поле из базовой сущности, которое мы можем использовать в подклассе. В некоторой степени это похоже на примеси (mixins). Также стоит отметить, что у нас может быть наследование состояния без наследования реализации, но в большинстве случаев эти два аспекта объединяются.
4. Наследование идентичности
Можно считать «наследованием конструктора» (не вдаваясь в теорию типов). Разница между миксином и наследованием от класса сводится к конструктору. Вы можете создать экземпляр и получить новую идентичность. Обычно мы получаем идентичность, создавая базовую сущность и «удерживая» её внутри подобъекта.
Наследование в C# и Java
C++ имеет множественное наследование и не делает различий между классом и интерфейсом. В C# и Java запрещено всё, кроме наследования сигнатур. Однако важно понимать, что утверждение, что «в C# и Java не существует множественного наследования», неверно. Существует множественное наследование для сигнатур и одиночное наследование для всего остального.
Однако позже создатели языков поняли, что это может быть не лучшая идея, и была добавлена реализация интерфейса по умолчанию, которая по сути является «наследованием реализации».
Продолжение следует…
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Начало
Проблема Алмаза, иногда называемая Смертельным Алмазом Смерти, возникает, когда мы наследуем одно и то же через несколько базовых сущностей. Если вы думаете, что «проблема есть в C++, но её не существует в Java или C#», то вы слишком сосредотачиваетесь на технической части.
Наследование
Обычно мы говорим, что в Java или C# существует одиночное наследование и множественная реализация интерфейсов. Это правда, но за этим скрывается гораздо более широкая картина.
Наследование позволяет наследовать характеристики и функции от базовой сущности (в большинстве случаев от класса или объекта). Есть много вещей, которые мы можем унаследовать, или много уровней наследования:
1. Наследование сигнатуры
В интерфейсе объявлен метод, мы наследуем его и предоставляем реализацию. Сигнатура здесь означает, что это только «заголовок» метода, без тела. Важно понимать, что эта «сигнатура наследования» не обязательно должна совпадать с «сигнатурой вызова». Например, вы не можете изменить тип возвращаемого значения при реализации интерфейса в C#, но тип возвращаемого значения не является частью «сигнатуры вызова». Java допускает это, но это детали реализации. Когда мы говорим о «наследовании сигнатуры», мы имеем в виду только заголовок метода, который мы получаем от базовой сущности.
2. Наследование реализации
При наследовании реализации мы получаем не только сигнатуру, но и всё тело метода. Это не так давно стало доступно в Java или C# через реализации интерфейса по умолчанию. Это можно рассматривать как типажи (traits). И хотя между наследованием реализации и трейтами есть некоторые различия, они довольно близки друг к другу.
3. Наследование состояния
Это наследование полей. При наследовании состояния мы получаем поле из базовой сущности, которое мы можем использовать в подклассе. В некоторой степени это похоже на примеси (mixins). Также стоит отметить, что у нас может быть наследование состояния без наследования реализации, но в большинстве случаев эти два аспекта объединяются.
4. Наследование идентичности
Можно считать «наследованием конструктора» (не вдаваясь в теорию типов). Разница между миксином и наследованием от класса сводится к конструктору. Вы можете создать экземпляр и получить новую идентичность. Обычно мы получаем идентичность, создавая базовую сущность и «удерживая» её внутри подобъекта.
Наследование в C# и Java
C++ имеет множественное наследование и не делает различий между классом и интерфейсом. В C# и Java запрещено всё, кроме наследования сигнатур. Однако важно понимать, что утверждение, что «в C# и Java не существует множественного наследования», неверно. Существует множественное наследование для сигнатур и одиночное наследование для всего остального.
Однако позже создатели языков поняли, что это может быть не лучшая идея, и была добавлена реализация интерфейса по умолчанию, которая по сути является «наследованием реализации».
Продолжение следует…
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот восемьдесят девятый. #TypesAndLanguages
4. Проблема Алмаза. Продолжение
Начало
Википедия определяет проблему алмаза как ситуацию, когда два класса B и C наследуются от класса A, переопределяют что-то, а затем класс D наследуется от классов B и C, не переопределяя член из A. Когда мы теперь хотим использовать член из A в классе D, мы не знаем, какой из них использовать (из B или из C).
Важно понимать, что это не имеет ничего общего с технической реализацией. Это логическая проблема (какой из членов выбрать), а не техническая.
Рассмотрим наследование сигнатуры:
Что же с реализацией интерфейса по умолчанию?
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Продолжение
Начало
Википедия определяет проблему алмаза как ситуацию, когда два класса B и C наследуются от класса A, переопределяют что-то, а затем класс D наследуется от классов B и C, не переопределяя член из A. Когда мы теперь хотим использовать член из A в классе D, мы не знаем, какой из них использовать (из B или из C).
Важно понимать, что это не имеет ничего общего с технической реализацией. Это логическая проблема (какой из членов выбрать), а не техническая.
Рассмотрим наследование сигнатуры:
interface A {Здесь никаких проблем нет, поскольку сигнатуры одинаковые, и неважно, какую из них использовать. Но что, если мы изменим тип результата:
void foo();
}
interface B {
void foo();
}
class C : A, B {
public void foo(){
Console.WriteLine("FOO");
}
}
interface A {В Java это сработает, в C# компилятор выдаст ошибку, требуя реализации
object foo();
}
interface B {
string foo();
}
class C : A, B {
public string foo() {
return "Foo";
}
}
A.foo()
из-за другого типа результата. Здесь «Ситуация Алмаза» решается в Java, но является проблемой в C#.Что же с реализацией интерфейса по умолчанию?
interface A {Следующий код
void foo() => Console.WriteLine("A");
}
interface B {
void foo() => Console.WriteLine("B");
}
class C : A, B { }
C c = new C();Вызовет ошибку компиляции в обоих языках. В Java с сообщением, что интерфейсы
c.foo();
A
и B
несовместимы. В C#, что класс C
не содержит реализации метода foo
. Всё дело в том, что C# заставляет использовать явную реализацию, и выбор остаётся за клиентским кодом (нужно привести экземпляр класса к одному из интерфейсов):C c = new C();Окончание следует…
((A)c).foo();
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот девяностый. #TypesAndLanguages
4. Проблема Алмаза. Окончание
Начало
Продолжение
Так в чём же состоит Проблема Алмаза? Не в наследовании несовместимого, а в выборе, какой унаследованный член использовать. Ситуация усложняется, когда мы вводим состояние в базовый класс. Нам нужно решить, хотим ли мы иметь независимые состояния для каждого подкласса (обычное наследование) или разделять его между подклассами (виртуальное наследование). Если мы делимся состоянием, оно может легко сломаться (поскольку две разные реализации используют одни и те же переменные). Если нет, нам нужно указать, какие переменные мы имеем в виду в самом низком подклассе.
В C# и Java проблема решается ошибкой времени компиляции. Но в других языках есть другие решения, например в Scala приоритет получает член «крайнего правого» унаследованного класса.
Проблема Алмаза в Java и C# с первого дня
По сути Проблема Алмаза была в Java и C# с самого начала. Как мы уже говорили, проблема состоит в том, чтобы решить, какому из членов отдать приоритет. Например:
По сути, это та же Проблема Алмаза, что и раньше. У нас есть две вещи, и мы не можем решить, какую из них использовать. При реализациях интерфейса по умолчанию языки выдают ошибку компиляции, но при перегрузке метода они просто выбирают один метод вместо другого.
Это, кстати, может привести к нарушению совместимости. Представьте, что кто-то добавит ещё один метод
Итого
Хотя правильно сказать, что в Java и C# нет множественного наследования, лучше иметь в виду, что существует много уровней наследования, и мы должны быть конкретными. Мы можем унаследовать реализацию начиная с C# 8 — это множественное наследование или нет?
Хотя правильно сказать, что до 8 версии языка не было Проблемы Алмаза, по сути, проблема существует в перегрузке методов. И это имеет те же последствия.
Стоит помнить, как, казалось бы, совершенно разные языковые элементы приводят к аналогичным проблемам. Мы все «боимся» Проблемы Алмаза, но не боимся перегрузки методов. Более того, считаем что это классная функция, пока однажды не нарушим совместимость.
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
4. Проблема Алмаза. Окончание
Начало
Продолжение
Так в чём же состоит Проблема Алмаза? Не в наследовании несовместимого, а в выборе, какой унаследованный член использовать. Ситуация усложняется, когда мы вводим состояние в базовый класс. Нам нужно решить, хотим ли мы иметь независимые состояния для каждого подкласса (обычное наследование) или разделять его между подклассами (виртуальное наследование). Если мы делимся состоянием, оно может легко сломаться (поскольку две разные реализации используют одни и те же переменные). Если нет, нам нужно указать, какие переменные мы имеем в виду в самом низком подклассе.
В C# и Java проблема решается ошибкой времени компиляции. Но в других языках есть другие решения, например в Scala приоритет получает член «крайнего правого» унаследованного класса.
Проблема Алмаза в Java и C# с первого дня
По сути Проблема Алмаза была в Java и C# с самого начала. Как мы уже говорили, проблема состоит в том, чтобы решить, какому из членов отдать приоритет. Например:
class A {Что выведет следующий код?
public string foo(long l) => "Long";
public string foo(double d) => "Double";
}
A a = new A();У нас есть два метода с разными сигнатурами. Мы хотим вызвать метод и передать недопустимое значение - значение другого типа. Однако Java и C# достаточно «умны», и просто приводят значение к типу, который им больше нравится (в данном случае -
Console.WriteLine(a.foo(123));
long
).По сути, это та же Проблема Алмаза, что и раньше. У нас есть две вещи, и мы не можем решить, какую из них использовать. При реализациях интерфейса по умолчанию языки выдают ошибку компиляции, но при перегрузке метода они просто выбирают один метод вместо другого.
Это, кстати, может привести к нарушению совместимости. Представьте, что кто-то добавит ещё один метод
foo(int i)
. Что будет с вашим кодом? Раньше int
приводился к long
, но после добавления нового метода приведение не требуется, и будет вызван новый метод. Это нарушает совместимость.Итого
Хотя правильно сказать, что в Java и C# нет множественного наследования, лучше иметь в виду, что существует много уровней наследования, и мы должны быть конкретными. Мы можем унаследовать реализацию начиная с C# 8 — это множественное наследование или нет?
Хотя правильно сказать, что до 8 версии языка не было Проблемы Алмаза, по сути, проблема существует в перегрузке методов. И это имеет те же последствия.
Стоит помнить, как, казалось бы, совершенно разные языковые элементы приводят к аналогичным проблемам. Мы все «боимся» Проблемы Алмаза, но не боимся перегрузки методов. Более того, считаем что это классная функция, пока однажды не нарушим совместимость.
Источник: https://blog.adamfurmanek.pl/2021/02/06/types-and-programming-languages-part-4/
День восемьсот девяносто первый. #DesignPatterns #Microservices
Паттерны в Микросервисах
3. Разделение Ответственности Запросов и Команд (CQRS)
При использовании паттерна Источников Событий иногда чтение данных из хранилища событий становится затруднительным. Чтобы получить сущность из хранилища, нам нужно обработать все события сущности. Кроме того, иногда у нас разные требования к согласованности и пропускной способности для операций чтения и записи.
В таких случаях мы можем использовать шаблон CQRS. В шаблоне CQRS функционал изменения данных системы (Команды) отделён от функционала чтения данных (Запросов). Шаблон CQRS имеет две формы: простую и расширенную, что приводит к некоторой путанице среди разработчиков.
В своей простой форме для чтения и записи используется единое хранилище данных, но отдельные сущности или модели ORM, как показано в левой части рисунка ниже. Это помогает обеспечить соблюдение принципов единственной ответственности и разделения ответственности, что приводит к более чистому дизайну.
В расширенной форме (см. в правой части рисунка ниже) для операций чтения и записи используются разные хранилища данных. Расширенный CQRS используется с паттерном Источников Событий. В зависимости от реализации могут использоваться разные типы хранилищ для записи и для чтения. Хранилище для записи - это краеугольный камень всей системы.
Для приложений с интенсивным чтением или микросервисной архитектуры в качестве хранилища для записи используется база данных OLTP (любая база данных SQL или NoSQL, предлагающая гарантию транзакции ACID) или платформа распределённого обмена сообщениями. В приложениях с интенсивной записью (для высокой масштабируемости и пропускной способности записи) используется база данных с возможностью горизонтального масштабирования для записи (глобальные облачные базы данных). В хранилище для записи сохраняются нормализованные данные.
В качестве хранилища для чтения используется база данных NoSQL, оптимизированная для поиска (например, Apache Solr, Elasticsearch) или чтения (хранилище пар ключ-значение, хранилище документов). Во многих случаях, когда требуется SQL-запрос, используются масштабируемые для чтения базы данных SQL. В хранилище для чтения сохраняются денормализованные и оптимизированные данные.
Данные копируются из хранилища для записи в хранилище для чтения асинхронно. В результате хранилище чтения отстает от хранилища записи и имеет место Окончательная Согласованность (Eventual Consistency).
Плюсы
- Более быстрое чтение данных в микросервисах, управляемых событиями.
- Высокая доступность данных.
- Системы чтения и записи могут масштабироваться независимо.
Минусы
- Хранилище для чтения слабо согласовано (окончательная согласованность)
- Общая сложность системы увеличивается. Чрезмерная увлечённость CQRS может поставить под угрозу весь проект.
Когда использовать
- В высокомасштабируемой микросервисной архитектуре, где используется паттерн источников событий.
- В сложной модели предметной области, где для чтения данных требуется запрос в несколько хранилищ данных.
- В системах, где операции чтения и записи имеют разную нагрузку.
Когда не использовать
- В микросервисной архитектуре, где объём событий незначителен, создание моментального снимка хранилища событий для вычисления состояния объекта является лучшим выбором.
- В системах, где операции чтения и записи имеют одинаковую нагрузку.
Поддержка
Хранилища для Записи: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB
Хранилища для Чтения: Elastic Search, Solr, Cloud Spanner, Amazon Aurora, Azure Cosmos DB, Neo4j
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- CQRS
- Что такое шаблон CQRS?
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
3. Разделение Ответственности Запросов и Команд (CQRS)
При использовании паттерна Источников Событий иногда чтение данных из хранилища событий становится затруднительным. Чтобы получить сущность из хранилища, нам нужно обработать все события сущности. Кроме того, иногда у нас разные требования к согласованности и пропускной способности для операций чтения и записи.
В таких случаях мы можем использовать шаблон CQRS. В шаблоне CQRS функционал изменения данных системы (Команды) отделён от функционала чтения данных (Запросов). Шаблон CQRS имеет две формы: простую и расширенную, что приводит к некоторой путанице среди разработчиков.
В своей простой форме для чтения и записи используется единое хранилище данных, но отдельные сущности или модели ORM, как показано в левой части рисунка ниже. Это помогает обеспечить соблюдение принципов единственной ответственности и разделения ответственности, что приводит к более чистому дизайну.
В расширенной форме (см. в правой части рисунка ниже) для операций чтения и записи используются разные хранилища данных. Расширенный CQRS используется с паттерном Источников Событий. В зависимости от реализации могут использоваться разные типы хранилищ для записи и для чтения. Хранилище для записи - это краеугольный камень всей системы.
Для приложений с интенсивным чтением или микросервисной архитектуры в качестве хранилища для записи используется база данных OLTP (любая база данных SQL или NoSQL, предлагающая гарантию транзакции ACID) или платформа распределённого обмена сообщениями. В приложениях с интенсивной записью (для высокой масштабируемости и пропускной способности записи) используется база данных с возможностью горизонтального масштабирования для записи (глобальные облачные базы данных). В хранилище для записи сохраняются нормализованные данные.
В качестве хранилища для чтения используется база данных NoSQL, оптимизированная для поиска (например, Apache Solr, Elasticsearch) или чтения (хранилище пар ключ-значение, хранилище документов). Во многих случаях, когда требуется SQL-запрос, используются масштабируемые для чтения базы данных SQL. В хранилище для чтения сохраняются денормализованные и оптимизированные данные.
Данные копируются из хранилища для записи в хранилище для чтения асинхронно. В результате хранилище чтения отстает от хранилища записи и имеет место Окончательная Согласованность (Eventual Consistency).
Плюсы
- Более быстрое чтение данных в микросервисах, управляемых событиями.
- Высокая доступность данных.
- Системы чтения и записи могут масштабироваться независимо.
Минусы
- Хранилище для чтения слабо согласовано (окончательная согласованность)
- Общая сложность системы увеличивается. Чрезмерная увлечённость CQRS может поставить под угрозу весь проект.
Когда использовать
- В высокомасштабируемой микросервисной архитектуре, где используется паттерн источников событий.
- В сложной модели предметной области, где для чтения данных требуется запрос в несколько хранилищ данных.
- В системах, где операции чтения и записи имеют разную нагрузку.
Когда не использовать
- В микросервисной архитектуре, где объём событий незначителен, создание моментального снимка хранилища событий для вычисления состояния объекта является лучшим выбором.
- В системах, где операции чтения и записи имеют одинаковую нагрузку.
Поддержка
Хранилища для Записи: EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra, Amazon DynamoDB
Хранилища для Чтения: Elastic Search, Solr, Cloud Spanner, Amazon Aurora, Azure Cosmos DB, Neo4j
Фреймворки: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
Подробнее:
- CQRS
- Что такое шаблон CQRS?
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍1
День восемьсот девяносто второй. #ЧтоНовенького
GitHub и OpenAI Запускают Новую Утилиту, Которая Генерирует Код за Вас
GitHub и OpenAI запустили предварительную техническую версию нового инструмента с искусственным интеллектом под названием Copilot, который находится внутри редактора кода Visual Studio и автоматически генерирует фрагменты кода.
Согласно GitHub, Copilot делает больше, чем просто выдаёт код, который где-то видел раньше. Вместо этого он анализирует код, который вы уже написали, и генерирует новый соответствующий код, включая определённые функции, которые ранее использовались. На веб-сайте проекта выложено несколько примеров популярных блоков кода, которые программистам приходится писать раз за разом, вроде получения ответа от API, нахождения количества дней между датами, и даже написания юнит-тестов.
Пока Copilot работает на Python, JavaScript, TypeScript, Ruby и Go.
GitHub рассматривает это как эволюцию парного программирования, когда два программиста работают над одним и тем же проектом, чтобы выявлять ошибки друг друга и ускорять процесс разработки. В Copilot один из этих программистов является виртуальным.
Этот проект - первый крупный результат инвестиций Microsoft в OpenAI, исследовательскую фирму, которую возглавляет Сэм Альтман. С тех пор как Альтман взял бразды правления, OpenAI перешёл от некоммерческого статуса к модели «с ограничением прибыли», принял инвестиции от Microsoft и начал лицензировать свой алгоритм генерации текста GPT-3.
GPT-3 - это флагманский алгоритм генерации текстов от OpenAI, который может генерировать текст, иногда неотличимый от человеческого языка. Он это делает так убедительно из-за огромного массива в 175 миллиардов параметров настройки, которые позволяют алгоритму связывать отношения между буквами, словами, фразами и предложениями.
Copilot построен на новом алгоритме под названием OpenAI Codex, который технический директор OpenAI Грег Брокман описывает как потомка GPT-3. GPT-3 генерирует английский текст, а Codex генерирует код. OpenAI планирует выпустить версию Codex в своём API этим летом, чтобы разработчики могли создавать свои собственные приложения с использованием этой технологии.
Codex был обучен на терабайтах открыто кода, взятого с GitHub, а также на примерах на английском языке. Разработчики говорят, что предложенные варианты кода были верны в 43% случаев с первого раза и в 57% случаев, когда алгоритму давалось до 10 попыток. При этом алгоритм будет становиться умнее со временем.
Хотя первые пользователи на сайте восторженно отзываются о росте продуктивности, который обеспечивает Copilot, GitHub подразумевает, что не весь используемый код был проверен на наличие ошибок, небезопасных действий или защиты личных данных. Компания пишет, что они установили несколько фильтров, чтобы Copilot не генерировал оскорбительные выражения, но фильтры могут быть не идеальны.
Компания также предупреждает, что модель может предлагать адреса электронной почты, ключи API или номера телефонов, но это происходит редко, и эти данные были скорее всего синтетические или псевдослучайно сгенерированные алгоритмом. При этом код, созданный Copilot, во многом оригинален. Тест, проведенный GitHub, показал, что только 0,1% сгенерированного кода можно было точно найти в обучающем наборе.
Прямо сейчас Copilot находится в ограниченной предварительной технической версии, но вы можете зарегистрироваться на веб-сайте проекта, чтобы получить к нему доступ.
Источник: https://www.theverge.com/2021/6/29/22555777/github-openai-ai-tool-autocomplete-code
GitHub и OpenAI Запускают Новую Утилиту, Которая Генерирует Код за Вас
GitHub и OpenAI запустили предварительную техническую версию нового инструмента с искусственным интеллектом под названием Copilot, который находится внутри редактора кода Visual Studio и автоматически генерирует фрагменты кода.
Согласно GitHub, Copilot делает больше, чем просто выдаёт код, который где-то видел раньше. Вместо этого он анализирует код, который вы уже написали, и генерирует новый соответствующий код, включая определённые функции, которые ранее использовались. На веб-сайте проекта выложено несколько примеров популярных блоков кода, которые программистам приходится писать раз за разом, вроде получения ответа от API, нахождения количества дней между датами, и даже написания юнит-тестов.
Пока Copilot работает на Python, JavaScript, TypeScript, Ruby и Go.
GitHub рассматривает это как эволюцию парного программирования, когда два программиста работают над одним и тем же проектом, чтобы выявлять ошибки друг друга и ускорять процесс разработки. В Copilot один из этих программистов является виртуальным.
Этот проект - первый крупный результат инвестиций Microsoft в OpenAI, исследовательскую фирму, которую возглавляет Сэм Альтман. С тех пор как Альтман взял бразды правления, OpenAI перешёл от некоммерческого статуса к модели «с ограничением прибыли», принял инвестиции от Microsoft и начал лицензировать свой алгоритм генерации текста GPT-3.
GPT-3 - это флагманский алгоритм генерации текстов от OpenAI, который может генерировать текст, иногда неотличимый от человеческого языка. Он это делает так убедительно из-за огромного массива в 175 миллиардов параметров настройки, которые позволяют алгоритму связывать отношения между буквами, словами, фразами и предложениями.
Copilot построен на новом алгоритме под названием OpenAI Codex, который технический директор OpenAI Грег Брокман описывает как потомка GPT-3. GPT-3 генерирует английский текст, а Codex генерирует код. OpenAI планирует выпустить версию Codex в своём API этим летом, чтобы разработчики могли создавать свои собственные приложения с использованием этой технологии.
Codex был обучен на терабайтах открыто кода, взятого с GitHub, а также на примерах на английском языке. Разработчики говорят, что предложенные варианты кода были верны в 43% случаев с первого раза и в 57% случаев, когда алгоритму давалось до 10 попыток. При этом алгоритм будет становиться умнее со временем.
Хотя первые пользователи на сайте восторженно отзываются о росте продуктивности, который обеспечивает Copilot, GitHub подразумевает, что не весь используемый код был проверен на наличие ошибок, небезопасных действий или защиты личных данных. Компания пишет, что они установили несколько фильтров, чтобы Copilot не генерировал оскорбительные выражения, но фильтры могут быть не идеальны.
Компания также предупреждает, что модель может предлагать адреса электронной почты, ключи API или номера телефонов, но это происходит редко, и эти данные были скорее всего синтетические или псевдослучайно сгенерированные алгоритмом. При этом код, созданный Copilot, во многом оригинален. Тест, проведенный GitHub, показал, что только 0,1% сгенерированного кода можно было точно найти в обучающем наборе.
Прямо сейчас Copilot находится в ограниченной предварительной технической версии, но вы можете зарегистрироваться на веб-сайте проекта, чтобы получить к нему доступ.
Источник: https://www.theverge.com/2021/6/29/22555777/github-openai-ai-tool-autocomplete-code
День восемьсот девяносто третий. #Оффтоп #КакСтатьСеньором
Когда Дела Идут не по Плану
Когда что-то идёт не так, а такое рано или поздно обязательно случится, золотое правило - свести к минимуму влияние на клиента.
Раньше, когда что-то шло не так, моей первой реакцией было устранить проблему. Оказывается, это не самое оптимальное решение. Вместо того, чтобы исправлять то, что пошло не так, даже если это «изменение одной строки», первое, что нужно сделать, - это откатиться. Вернитесь в предыдущее рабочее состояние. Это самый быстрый способ вернуть клиентов к рабочей версии.
Только после этого можно искать, что пошло не так, и исправлять эти ошибки. Тот же подход, что и с глючащей машиной в вашем кластере: отключите её, отметьте как недоступную, прежде чем пытаться выяснить, что с ней не так.
Странно, как мои естественные склонности и инстинкты расходятся с оптимальным решением. Думаю, что этот инстинкт также ведёт меня по более долгому пути в исправлении ошибок. Иногда мне кажется, что это не работает, потому что что-то не так с тем, что я написал, и я погружаюсь в исходники, просматривая каждую строку кода. Что-то вроде «поиска в глубину».
Когда выясняется, что проблема была в конфигурации, то есть в том, что нужная функция была просто отключена, это меня бесит. Я использовал такой неоптимальный подход в процессе обнаружения ошибок.
Теперь мой подход заключается в том, чтобы выполнять «поиск в ширину» перед «поиском в глубину», чтобы избавиться от узлов верхнего уровня. Что я могу проверить на верхнем уровне?
- Машина работает?
- Установлен правильный код?
- Конфигурация на месте?
- Правильно ли задана конфигурация для конкретного кода, например, правильная ли маршрутизация в коде?
- Обновлена ли база данных?
И только потом можно искать ошибку в коде.
«Мы думали, что nginx некорректно установился на машине, но оказалось, что просто в конфигурации было установлено значение false.»
Конечно, не нужно делать так всегда. Иногда достаточно просто сообщения об ошибке, чтобы сузить пространство поиска и сразу лезть в код.
Когда я не могу понять, в чём проблема, я стараюсь свести к минимуму изменения кода, чтобы выяснить, что не так. Чем меньше изменений, тем быстрее я смогу найти реальную проблему.
Я также теперь веду дневник ошибок, на устранение которых мне потребовалось более 1 часа: Чего мне не хватило? О чём я не подумал? Обычно это какое-нибудь мелкое дерьмо, которое я забыл проверить, например, настройка маршрутизации, соответствие версии схемы и версии сервиса и т. д. Это ещё один шаг знакомства с используемым мной технологическим стеком, и то, что даёт только опыт: интуицию для точного понимания того, почему что-то не работает.
Источник: https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
Когда Дела Идут не по Плану
Когда что-то идёт не так, а такое рано или поздно обязательно случится, золотое правило - свести к минимуму влияние на клиента.
Раньше, когда что-то шло не так, моей первой реакцией было устранить проблему. Оказывается, это не самое оптимальное решение. Вместо того, чтобы исправлять то, что пошло не так, даже если это «изменение одной строки», первое, что нужно сделать, - это откатиться. Вернитесь в предыдущее рабочее состояние. Это самый быстрый способ вернуть клиентов к рабочей версии.
Только после этого можно искать, что пошло не так, и исправлять эти ошибки. Тот же подход, что и с глючащей машиной в вашем кластере: отключите её, отметьте как недоступную, прежде чем пытаться выяснить, что с ней не так.
Странно, как мои естественные склонности и инстинкты расходятся с оптимальным решением. Думаю, что этот инстинкт также ведёт меня по более долгому пути в исправлении ошибок. Иногда мне кажется, что это не работает, потому что что-то не так с тем, что я написал, и я погружаюсь в исходники, просматривая каждую строку кода. Что-то вроде «поиска в глубину».
Когда выясняется, что проблема была в конфигурации, то есть в том, что нужная функция была просто отключена, это меня бесит. Я использовал такой неоптимальный подход в процессе обнаружения ошибок.
Теперь мой подход заключается в том, чтобы выполнять «поиск в ширину» перед «поиском в глубину», чтобы избавиться от узлов верхнего уровня. Что я могу проверить на верхнем уровне?
- Машина работает?
- Установлен правильный код?
- Конфигурация на месте?
- Правильно ли задана конфигурация для конкретного кода, например, правильная ли маршрутизация в коде?
- Обновлена ли база данных?
И только потом можно искать ошибку в коде.
«Мы думали, что nginx некорректно установился на машине, но оказалось, что просто в конфигурации было установлено значение false.»
Конечно, не нужно делать так всегда. Иногда достаточно просто сообщения об ошибке, чтобы сузить пространство поиска и сразу лезть в код.
Когда я не могу понять, в чём проблема, я стараюсь свести к минимуму изменения кода, чтобы выяснить, что не так. Чем меньше изменений, тем быстрее я смогу найти реальную проблему.
Я также теперь веду дневник ошибок, на устранение которых мне потребовалось более 1 часа: Чего мне не хватило? О чём я не подумал? Обычно это какое-нибудь мелкое дерьмо, которое я забыл проверить, например, настройка маршрутизации, соответствие версии схемы и версии сервиса и т. д. Это ещё один шаг знакомства с используемым мной технологическим стеком, и то, что даёт только опыт: интуицию для точного понимания того, почему что-то не работает.
Источник: https://neilkakkar.com/things-I-learnt-from-a-senior-dev.html
Автор оригинала – Neil Kakkar
День восемьсот девяносто четвёртый. #Оффтоп
CUPID
Сегодня посоветую вам очередное видео с просторов Ютуба. В этом видео Дэниел Норт посягает на самое святое. Оказывается SOLID уже не торт!
С некоторым проектами работается легче, чем с другими. Это верно для приложений, сервисов, библиотек, фреймворков и даже самих языков программирования. Это сугубо личный выбор или есть универсальные характеристики программного обеспечения, которые могут сделать работу с кодом приятной?
Дэниел думал об этом очень давно, особенно с тех пор, как несколько лет назад он для развлечения «наехал» на принципы SOLID, и получил в ответ порцию хейта. Его пост о том, почему он считает, что SOLID устарел, оказался на первой странице Hacker News!
Впоследствии он систематизировал свои мысли в виде собственного лаконичного пятибуквенного акронима CUPID. Это не принципы проектирования, а скорее свойства хорошей кодовой базы. То есть их нельзя нарушить, но можно в большей или меньшей степени им соответствовать. Итак, CUPID – означает, что кодовая база обладает следующими свойствами.
1. Composable (Интегрируемый)
Это значит, что модуль или библиотека легко встраивается в проект и может быть использована повторно. Код, который легко использовать повторно, используется повторно снова, и снова, и снова. Некоторые характеристики такого кода:
- Компактный интерфейс – требует меньше изучения, меньше возможностей использовать его неправильно, меньше конфликтов.
- Имя и описание чётко выражают намерение – такую библиотеку или NuGet-пакет легче найти и легче понять, что она делает.
- Имеет минимальное количество зависимостей.
2. Unix философия
Код делает одну вещь, но делает её хорошо. Примером послужили команды консоли в Unix. Например,
Кроме того, Unix философия подразумевает, что результат одной программы будет входными данными для другой и поощряет пайплайны.
3. Predictable (Предсказуемый)
Код делает то, что вы от него ожидаете. Всё равно, что «проходит все тесты», как говорят в TDD, но более обобщённо. Это также относится, например, к структуре проекта, где все вещи названы так и расположены там, где вы этого ожидаете, поэтому даже не знакомый с кодовой базой человек может быстро найти нужный кусок кода.
4. Idiomatic (Идиоматический)
Код легко понимается и использует характерные для языка или проекта конструкции, ключевые слова или выражения, стандарты кодирования и т.п. согласованно во всей кодовой базе.
5. Domain-based (Предметно-ориентированный)
Это означает не только использование в коде характерных для предметной области терминов, но и построение структуры проекта в соответствии с доменом, а не фреймворком.
Таким образом, по задумке Дэниела, чем больше код соответствует каждому из этих свойств, тем приятнее с ним работать программисту.
Подробнее Дэниел рассказывает о CUPID в подкасте DotNet Rocks.
Что скажете?
CUPID
Сегодня посоветую вам очередное видео с просторов Ютуба. В этом видео Дэниел Норт посягает на самое святое. Оказывается SOLID уже не торт!
С некоторым проектами работается легче, чем с другими. Это верно для приложений, сервисов, библиотек, фреймворков и даже самих языков программирования. Это сугубо личный выбор или есть универсальные характеристики программного обеспечения, которые могут сделать работу с кодом приятной?
Дэниел думал об этом очень давно, особенно с тех пор, как несколько лет назад он для развлечения «наехал» на принципы SOLID, и получил в ответ порцию хейта. Его пост о том, почему он считает, что SOLID устарел, оказался на первой странице Hacker News!
Впоследствии он систематизировал свои мысли в виде собственного лаконичного пятибуквенного акронима CUPID. Это не принципы проектирования, а скорее свойства хорошей кодовой базы. То есть их нельзя нарушить, но можно в большей или меньшей степени им соответствовать. Итак, CUPID – означает, что кодовая база обладает следующими свойствами.
1. Composable (Интегрируемый)
Это значит, что модуль или библиотека легко встраивается в проект и может быть использована повторно. Код, который легко использовать повторно, используется повторно снова, и снова, и снова. Некоторые характеристики такого кода:
- Компактный интерфейс – требует меньше изучения, меньше возможностей использовать его неправильно, меньше конфликтов.
- Имя и описание чётко выражают намерение – такую библиотеку или NuGet-пакет легче найти и легче понять, что она делает.
- Имеет минимальное количество зависимостей.
2. Unix философия
Код делает одну вещь, но делает её хорошо. Примером послужили команды консоли в Unix. Например,
ls
, которая всего лишь выводит список файлов, но имеет огромное количество параметров и способов сортировки и обработки получаемого результата.Кроме того, Unix философия подразумевает, что результат одной программы будет входными данными для другой и поощряет пайплайны.
3. Predictable (Предсказуемый)
Код делает то, что вы от него ожидаете. Всё равно, что «проходит все тесты», как говорят в TDD, но более обобщённо. Это также относится, например, к структуре проекта, где все вещи названы так и расположены там, где вы этого ожидаете, поэтому даже не знакомый с кодовой базой человек может быстро найти нужный кусок кода.
4. Idiomatic (Идиоматический)
Код легко понимается и использует характерные для языка или проекта конструкции, ключевые слова или выражения, стандарты кодирования и т.п. согласованно во всей кодовой базе.
5. Domain-based (Предметно-ориентированный)
Это означает не только использование в коде характерных для предметной области терминов, но и построение структуры проекта в соответствии с доменом, а не фреймворком.
Таким образом, по задумке Дэниела, чем больше код соответствует каждому из этих свойств, тем приятнее с ним работать программисту.
Подробнее Дэниел рассказывает о CUPID в подкасте DotNet Rocks.
Что скажете?
👍2
День восемьсот девяносто пятый. #DesignPatterns #Microservices
Паттерны в Микросервисах
4. Saga
Если вы используете микросервисную архитектуру с базой данных на микросервис, то управление согласованностью с помощью распределённых транзакций является сложной задачей. Вы не можете использовать традиционный протокол двухфазной фиксации (2PC), поскольку он либо не масштабируется (базы данных SQL), либо не поддерживается (многие базы данных NoSQL).
Вы можете использовать паттерн Saga для распределённых транзакций в микросервисной архитектуре. Saga - это старый паттерн, разработанный в 1987 году как концептуальная альтернатива длительным транзакциям в базах данных SQL. Но современный вариант этого паттерна отлично работает и для распределённой транзакции. Паттерн Saga - это последовательность локальных транзакций, в которой каждая транзакция обновляет данные в хранилище данных в рамках одного микросервиса и публикует событие или сообщение. Первая транзакция в Saga инициируется внешним запросом (событием или действием). После завершения локальной транзакции (данные сохраняются в хранилище данных, а сообщение или событие публикуются) опубликованное сообщение/событие запускает следующую локальную транзакцию в Saga (см. картинку ниже).
Если локальная транзакция терпит неудачу, Saga выполняет серию компенсирующих транзакций, которые откатывают изменения предыдущих локальных транзакций.
В основном существует два варианта координации транзакций в Saga:
- Хореография: децентрализованная координация, при которой каждый микросервис производит и прослушивает события/сообщения других микросервисов и решает, следует ли предпринять действие или нет.
- Оркестрация: централизованная координация, при которой оркестратор сообщает участвующим микросервисам, какую локальную транзакцию необходимо выполнить.
Плюсы
- Обеспечение согласованности посредством транзакций в высокомасштабируемой или слабо связанной, управляемой событиями микросервисной архитектуре.
- Обеспечение согласованности посредством транзакций в микросервисной архитектуре, где используются базы данных NoSQL без поддержки 2PC.
Минусы
- Необходимо обрабатывать временные отказы и обеспечивать идемпотентность.
- Трудно отлаживать, и сложность растёт по мере увеличения количества микросервисов.
Когда использовать
- В высокомасштабируемой, слабо связанной микросервисной архитектуре, где используются источники событий https://t.iss.one/NetDeveloperDiary/1084.
- В системах, где используются распределённые базы данных NoSQL.
Когда не использовать
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В системах, где существует циклическая зависимость между сервисами.
Поддержка
Axon, Eventuate, Narayana
Подробнее
- Saga — распределённые транзакции
- Microservices Pattern: Saga
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
Паттерны в Микросервисах
4. Saga
Если вы используете микросервисную архитектуру с базой данных на микросервис, то управление согласованностью с помощью распределённых транзакций является сложной задачей. Вы не можете использовать традиционный протокол двухфазной фиксации (2PC), поскольку он либо не масштабируется (базы данных SQL), либо не поддерживается (многие базы данных NoSQL).
Вы можете использовать паттерн Saga для распределённых транзакций в микросервисной архитектуре. Saga - это старый паттерн, разработанный в 1987 году как концептуальная альтернатива длительным транзакциям в базах данных SQL. Но современный вариант этого паттерна отлично работает и для распределённой транзакции. Паттерн Saga - это последовательность локальных транзакций, в которой каждая транзакция обновляет данные в хранилище данных в рамках одного микросервиса и публикует событие или сообщение. Первая транзакция в Saga инициируется внешним запросом (событием или действием). После завершения локальной транзакции (данные сохраняются в хранилище данных, а сообщение или событие публикуются) опубликованное сообщение/событие запускает следующую локальную транзакцию в Saga (см. картинку ниже).
Если локальная транзакция терпит неудачу, Saga выполняет серию компенсирующих транзакций, которые откатывают изменения предыдущих локальных транзакций.
В основном существует два варианта координации транзакций в Saga:
- Хореография: децентрализованная координация, при которой каждый микросервис производит и прослушивает события/сообщения других микросервисов и решает, следует ли предпринять действие или нет.
- Оркестрация: централизованная координация, при которой оркестратор сообщает участвующим микросервисам, какую локальную транзакцию необходимо выполнить.
Плюсы
- Обеспечение согласованности посредством транзакций в высокомасштабируемой или слабо связанной, управляемой событиями микросервисной архитектуре.
- Обеспечение согласованности посредством транзакций в микросервисной архитектуре, где используются базы данных NoSQL без поддержки 2PC.
Минусы
- Необходимо обрабатывать временные отказы и обеспечивать идемпотентность.
- Трудно отлаживать, и сложность растёт по мере увеличения количества микросервисов.
Когда использовать
- В высокомасштабируемой, слабо связанной микросервисной архитектуре, где используются источники событий https://t.iss.one/NetDeveloperDiary/1084.
- В системах, где используются распределённые базы данных NoSQL.
Когда не использовать
- Слабо масштабируемые транзакционные системы с базами данных SQL.
- В системах, где существует циклическая зависимость между сервисами.
Поддержка
Axon, Eventuate, Narayana
Подробнее
- Saga — распределённые транзакции
- Microservices Pattern: Saga
Источник: https://towardsdatascience.com/microservice-architecture-and-its-10-most-important-design-patterns-824952d7fa41
👍2
День восемьсот девяносто шестой. #BestPractices
Лучшие Практики Использования RESTful API. Начало
Сегодня рассмотрим лучшие практики, которые можно использовать при работе с RESTful API.
1. Используйте JSON
В наши дни JSON является общепринятым стандартом для взаимодействия с API. Это предпочтительный выбор по сравнению с XML, поскольку он значительно снижает полезную нагрузку, что приводит к более быстрой передаче данных. Следовательно, ваши REST API должны использовать JSON для связи между клиентом и сервером. Обратите внимание, что REST не зависит от формата, что означает, что вы можете использовать любой формат для обмена данными, например XML, HTML, JSON и даже пользовательские форматы. Чтобы гарантировать, что ваш REST API обменивается данными в JSON, вы можете задать заголовок ответа
2. Версионирование
Версионирование - это процесс управления изменениями в API. Рекомендуется всегда добавлять версии в свой API. При разработке REST API следует помнить, что изменения неизбежны. Возможно, вам придётся внести критические изменения, чтобы удовлетворить потребности клиентов.
Такое критическое изменение может потребоваться из-за изменения формата данных ответа, изменения типа ответа, введения новых функций, редактирования или удаления существующих функций и т. д. Следовательно, крайне важно, чтобы у вас была стратегия реализации изменений.
Версионирование - одна из таких стратегий. Существуют разные варианты реализации версионирования API:
- URI
Это простейшая стратегия передачи информации о версии: поместить номер версии в путь URI. При этом по соглашению номер версии начинается с префикса «v»:
Вы можете указать информацию о версии в параметре запроса. При этом базовый URL останется прежним:
- Заголовок запроса
Ещё один вариант - использовать заголовок Accept:
3. Документация
API неполон без надлежащей документации. Документация должна быть общедоступной и содержать сведения о конечных точках API и циклах запроса/ответа. Помните, что после того, как ваш API станет общедоступным, вы не должны вносить изменений без уведомления.
4. Всегда используйте SSL
Всегда используйте SSL. Здесь вообще не может быть никаких исключений. К вашему API можно получить доступ практически из любого места, где есть подключение к Интернету. Следовательно, вы должны убедиться, что ваши API безопасны. Связь между сервером и клиентом, использующим ваш API, должна быть защищённой и зашифрованной.
Окончание следует…
Источник: https://www.developer.com/web-services/best-practices-restful-api/
Лучшие Практики Использования RESTful API. Начало
Сегодня рассмотрим лучшие практики, которые можно использовать при работе с RESTful API.
1. Используйте JSON
В наши дни JSON является общепринятым стандартом для взаимодействия с API. Это предпочтительный выбор по сравнению с XML, поскольку он значительно снижает полезную нагрузку, что приводит к более быстрой передаче данных. Следовательно, ваши REST API должны использовать JSON для связи между клиентом и сервером. Обратите внимание, что REST не зависит от формата, что означает, что вы можете использовать любой формат для обмена данными, например XML, HTML, JSON и даже пользовательские форматы. Чтобы гарантировать, что ваш REST API обменивается данными в JSON, вы можете задать заголовок ответа
Content-Type: application/json
.2. Версионирование
Версионирование - это процесс управления изменениями в API. Рекомендуется всегда добавлять версии в свой API. При разработке REST API следует помнить, что изменения неизбежны. Возможно, вам придётся внести критические изменения, чтобы удовлетворить потребности клиентов.
Такое критическое изменение может потребоваться из-за изменения формата данных ответа, изменения типа ответа, введения новых функций, редактирования или удаления существующих функций и т. д. Следовательно, крайне важно, чтобы у вас была стратегия реализации изменений.
Версионирование - одна из таких стратегий. Существуют разные варианты реализации версионирования API:
- URI
Это простейшая стратегия передачи информации о версии: поместить номер версии в путь URI. При этом по соглашению номер версии начинается с префикса «v»:
https://www.mywebsite.com/api/v1.0/products- Параметр запроса
https://www.mywebsite.com/api/v2.1/orders
Вы можете указать информацию о версии в параметре запроса. При этом базовый URL останется прежним:
https://www.mywebsite.com/api/products/{id}?version=1.0Это более гибкий подход к запросу версии ресурса.
- Заголовок запроса
Ещё один вариант - использовать заголовок Accept:
Accept: version=1.0В этом случае вам не нужно вносить никаких изменений в URL-адрес.
3. Документация
API неполон без надлежащей документации. Документация должна быть общедоступной и содержать сведения о конечных точках API и циклах запроса/ответа. Помните, что после того, как ваш API станет общедоступным, вы не должны вносить изменений без уведомления.
4. Всегда используйте SSL
Всегда используйте SSL. Здесь вообще не может быть никаких исключений. К вашему API можно получить доступ практически из любого места, где есть подключение к Интернету. Следовательно, вы должны убедиться, что ваши API безопасны. Связь между сервером и клиентом, использующим ваш API, должна быть защищённой и зашифрованной.
Окончание следует…
Источник: https://www.developer.com/web-services/best-practices-restful-api/