
Запах кода 303 - Как предотвратить нарушение существующих клиентов при внесении изменений
14 июня 2025 г.Когда вы нарушаете API без предупреждения, вы нарушаете доверие
TL; DR: Вы должны вернуть свои API, чтобы предотвратить нарушение существующих клиентов, когда вы вносите изменения.
Проблемы 😔
- Клиентские приложения сбоя
- Интеграционные сбои
- Наименьшее минимальное неожиданное нарушение принципа
- Время простоя
- Сломан доверие
- Необходимы откаты в развертывании
- Время развития потрачено впустую
- Унижение пользователя
Решения 😃
- Добавить семантическую версию
- Реализовать обратную совместимость
- Создать предупреждения об испаке
- Создать дорожные карты
- Используйте переговоры о контенте
- Поддерживать параллельные версии
- Сообщите изменения рано
- Постепенно обрести особенности
- Четкие изменения в документе
- Проверьте устаревшие параметры с журналом
- Тщательно тестируйте новые версии
- Удалить устаревшую функциональность после солнца
Контекст 💬
Когда вы изменяете API без надлежащего устранения версий, вы создаете нарушающие изменения, которые влияют на всех существующих клиентов.
Вы заставляете потребителей немедленно обновить свой код или сбои системы.
Вы нарушаете неявный договор между поставщиками API и потребителями.
Современное программное обеспечение в значительной степени зависит от стабильности API, и внедрение нарушающих изменений без предупреждения может создать каскадные сбои между зависимыми системами.
Это сегодня важнее, чем когда -либо с тех порМногие IAS создают свои решения, используя существующую документацию APIПолем
Когда вы обновляете API без поддержания обратной совместимости, вы рискуете разбить все приложения, которые от него зависят.
Это создает нестабильность, разочарование и дорогостоящие исправления для пользователей.
Клиенты часто терпятдефектыВ новых функциях, но никогда не разбито ранее стабильное поведение.
Правильное управление версиями обеспечивает плавные переходы и поддерживает надежность вашей системы.
Пример кода 📖
Неправильно ❌
// user-api-v1.json - Original API response
{
"id": 317,
"name": "Mr Nimbus",
"email": "nimbus@atlantis.com",
"nationalities": "Brazilian,Canadian,Oceanic"
}
// Later changed to this without versioning:
{
"userId": 317,
"fullName": "Mr Nimbus",
"emailAddress": "nimbus@atlantis.com",
"createdAt": "2018-12-09T18:30:00Z",
"nationalities": ["Brazilian", "Canadian", "Oceanic"]
}
fetch('/api/users/317')
.then(response => response.json())
.then(user => {
// This breaks when API changes field names and data types
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
// This breaks when nationalities changes from string to array
document.getElementById('nationalities').textContent
= user.nationalities;
});
Справа 👉
// user-api-v1.json - Version 1 (maintained)
{
"id": 317,
"name": "Mr Nimbus",
"email": "nimbus@atlantis.com",
"nationalities": "Brazilian,Canadian,Oceanic"
}
// user-api-v2.json - Version 2
// (new structure, backward compatible)
{
"id": 317,
"userId": 317,
"name": "Mr Nimbus",
"fullName": "Mr Nimbus",
"email": "nimbus@atlantis.com",
"emailAddress": "nimbus@atlantis.com",
"createdAt": "2018-12-09T18:30:00Z",
"nationalities": "Brazilian,Canadian,Oceanic"
"nationalitiesList": ["Brazilian", "Canadian", "Oceanic"]
}
// user-api-v3.json - Version 3
// (new structure, backward not compatible)
{
"userId": 317,
"fullName": "Mr Nimbus",
"emailAddress": "nimbus@atlantis.com",
"createdAt": "2018-12-09T18:30:00Z",
"nationalitiesList": ["Brazilian", "Canadian", "Oceanic"]
}
// client-code-versioned.js
const API_VERSION = 'v1';
fetch(`/api/${API_VERSION}/users/317`)
.then(response => response.json())
.then(user => {
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
// V1 handles comma-separated string
document.getElementById('nationalities').textContent
= user.nationalities;
});
// Or with content negotiation
fetch('/api/users/317', {
headers: {
'Accept': 'application/vnd.api+json;version=1'
}
})
.then(response => response.json())
.then(user => {
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
document.getElementById('nationalities').textContent
= user.nationalities;
});
Обнаружение 🔍
- [x]Полуавтоматический
Вы можете обнаружить этот запах, когда вы найдете API, которые изменяют имена поля, удаляют поля или изменяют структуры данных, не поддерживая обратную совместимость.
Ищите клиентские приложения, которые ломаются после развертывания API.
Проверьте наличие пропущенных заголовков версий или схем управления версиями URL.
Мониторинг журналов ошибок для внезапных всплесков в сбоях клиентов после выпусков.
Теги 🏷
- Апис
Уровень 🔋
- [x]Средний
Почему биение важна 🗺
Вы должны поддерживать конюшнюКартмежду вашим контрактом API и ожиданиями клиентов.
Когда вы сломаете этоБиениеИзменив API без версий, вы нарушаете фундаментальный принцип, который клиенты могут полагаться на последовательные интерфейсы.
Вы создаете несоответствие между тем, что клиенты ожидают получить, и тем, что предоставляет ваш API.
Это нарушает переписку один к одному между обещаниями API и доставкой API, что приводит к сбоям системы и потерянности доверия.
Модель APIS реальные услуги. Когда вы нарушаете картирование между вашим API и бизнес -логикой, которую он представляет, клиенты не могут надежно взаимодействовать с вашей системой.
Это несоответствие приводит к дефектам, простоям, отсутствию доверия и плохому опыту пользователя.
Поколение AI 🤖
Генераторы ИИ часто создают этот запах, когда вы просите их «улучшить» или «обновить» существующие API.
Они сосредоточены на том, чтобы сделать API «лучше», не рассматривая обратную совместимость.
Вам необходимо явно обучать инструменты ИИ для поддержания существующих имен поля и добавления в версий при внесении изменений.
Они часто предпочитают чистый дизайн по сравнению с стабильностью, если толькоявносказал иначе.
Обнаружение ИИ 🧲
Генераторы ИИ могут исправить этот запах, когда вы предоставляете четкие инструкции по стратегиям управления версиями API.
Вы должны попросить их реализовать семантическое управление версиями, поддерживать обратную совместимость и создать пути миграции для устаревших функций.
Попробуйте их! 🛠
Помните: помощники ИИ делают много ошибок
Предлагаемое подсказка: создать версию API, чтобы предотвратить нарушение изменений
Без надлежащих инструкций | С конкретными инструкциями |
---|---|
Чатгпт | Чатгпт |
Клод | Клод |
Недоумение | Недоумение |
Второй пилот | Второй пилот |
Близнецы | Близнецы |
DeepSeek | DeepSeek |
Meta ai | Meta ai |
Грок | Грок |
Qwen | Qwen |
Заключение 🏁
Вы всегда должны вернуть свои API, чтобы предотвратить нарушение изменений от влияния клиентских приложений.
Даже из вашей первой версии.
Когда вы поддерживаете стабильные контракты с помощью надлежащего управления версиями, вы укрепляете доверие с потребителями API и обеспечиваете плавную эволюцию ваших систем.
Разрушение изменений неизбежно, но они не должны нарушать ваших клиентов.
Всегда верните свои API, осторожно выходите в формирование и проактивно общайтесь, чтобы избежать ненужных нарушений.
Отношения 👩❤
https://hackernoon.com/misusing-http-status-codes-wrecks-your-api-monitoring-and-client-logic
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-iv-7sc3w8n
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-xii
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-xxii
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-xxxiv
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-xxxv
Отказ от ответственности 📘
Кодовые запахи - моимнениеПолем
Кредиты 🙏
ФотоДжанкарло RevolledoнаНеспособный
API навсегда, так что проектируйте их тщательно
Мартин Фаулер
https://hackernoon.com/400-thought-предвидение-software-engineering-quotes?embedable=true
Эта статья является частью серии Codesmell.
https://hackernoon.com/how-to-find-the-shooky-parts-of-your-code-part-i-xqz3evd?embedable=true
Оригинал