Кері үйлесімділік
Кері үйлесімділік дегеніміз не?
Кері үйлесімділік (backward compatibility) - жүйенің ескі клиенттерді/тұтынушыларды қабылдау және дұрыс өңдеу қасиеті, жүйе жаңартылғанда. Оңай: сіз сервистің/оқиғалардың жаңа нұсқасын шығарасыз, ал бұрыннан бар интеграциялар өзгеріссіз жұмыс істеуді жалғастырады.
Кілт: келісімдерді бұзбау. Кез келген эволюция - шығарылғанды қайта жасау емес, қосу арқылы.
Базалық қағидаттар
1. Additive-first
Жаңа өрістер/әдістер/оқиғалар қосымша қосылады. Бар ештеңе жойылмайды және мәнін өзгертпейді.
2. Ең аз кепілдік келісімшарт (MGC)
Оларсыз сценарий мағынасын жоғалтатын өрістер/әрекеттер жиынын анықтаңыз. Ядро тұрақты. Қалғандары - кеңейту.
3. Tolerant reader
Клиенттер белгісіз өрістерді елемейді және жаңа enum (fallback) мәндерін дұрыс өңдейді.
4. Нұсқа саясаты
Бұзатын өзгерістер тек major-сызығы арқылы ('/v2 ',' payments. v2`, `event. v2`). Шағын - аддитивті.
5. Бақылау - келісімшарттың бір бөлігі
Логтарда/трестерде және метрикаларда клиенттің нұсқасы, пішімі, capability-жалаулары көрінеді. Бұл көші-қонды басқаруға мүмкіндік береді.
Қауіпсіз vs қауіпті өзгерістер
Әдетте қауіпсіз (BC-OK)
Міндетті емес өрістерді қосу (JSON/Euro/Protobuf 'optional '/' nullable').
Жаңа эндпоинттерді/әдістерді/оқиғаларды қосу.
Қосымша мәндермен enum кеңейту (толерант reader кезінде).
Валидацияның әлсіреуі (максимумдарды ұлғайту, баламалы форматтарды қосу).
Мәнге әсер етпейтін тақырыптарды/метадеректерді қосу.
Қауіпті (Breaking)
Өрістерді жою/қайта атау, бар өрістердің түрін немесе міндеттілігін өзгерту.
Мәртебе семантикасын/қате кодтарын ауыстыру.
Protobuf-тегтерді басқа өрістерге қайта пайдалану.
Оқиғаны партияландыру кілтін ауыстыру (агрегат үшін тәртіпті бұзады).
Ескі клиенттердің құлдырауына әкелетін SLA/таймауттарды қатайту.
Өзара әрекеттесу стилі бойынша
REST/HTTP + JSON
Аддитивтілік: жаңа өрістер - 'optional', сервер оларды ескі клиенттерден талап етпейді.
Нұсқалары: major - жолда ('/v2 ') немесе медиатипте; minor - '? include = '/'? fields ='.
Қателер: бірыңғай пішім; major жоқ кодтарды/семантиканы өзгертпеу.
ETag/If-Match: қауіпсіз жарыссыз жаңартулар үшін.
Ұқсастық: POST үшін 'Idempotency-Key' - ескі клиенттер ретраяларда әсерді «екі еселемейді».
gRPC / Protobuf
Тегтер өзгермейді. Жойылған тегтерді қайта пайдалануға болмайды.
Жаңа өрістер - 'optional '/' repeated'; әдепкі мәндер ескі кодпен дұрыс өңделеді.
Стриминг: minor ішіндегі хабарлардың ретін/міндеттілігін өзгертпеу.
Қателер - тұрақты мәртебе жиынтығы; жаңа семантика → жаңа әдіс/қызмет ('.v2').
Event-driven (Kafka/NATS/Pulsar) + Avro/JSON/Proto
Атауы: 'domain. action. v{major}`.
Core vs Enriched: ядро тұрақты; байыту - жекелеген типтер/тақырыптар ('.enriched').
Схемалардың сыйысымдылық режимі: көбінесе BACKWARD; CI сыйыспайтын өзгерістерді бұғаттайды.
Партиялану: кілт (мысалы, 'payment _ id') - келісімшарттың бір бөлігі; оны ауыстыру - breaking.
GraphQL
Өрістерді/түрлерді қосу - ОК; жою/қайта атау - '@deprecated' және көші-қон терезесі арқылы.
majorсыз «nullable → non-nullable» дегенді көтермеңіз.
complexity/depth - лимиттерді өзгерту = келісімшартты өзгерту.
BC сақтауға көмектесетін паттерндер
Кері пирамида моделі: ядроны тұрақтандырыңыз, қосымша кеңейтіңіз.
Capability negotiation: клиент қолдау көрсетілетін мүмкіндіктерді хабарлайды ('X-Capabilities '/handshake), сервер бейімделеді.
Dual-run/dual-emit: көшіру кезінде бір уақытта 'v1' және 'v2' -ні сақтаңыз.
Адаптерлер: прокси/гейтвей «ауыр» клиенттер үшін 'v1 v2' сұрауларын аударады.
Expand-and-contract (DB үшін): алдымен жаңасын қосыңыз, жазуды/оқуды бастаңыз, тек содан кейін ескісін жойыңыз.
Governance және процесс
1. Келісімшарттар каталогы (схемалар тізілімі): үйлесімділік саясатымен ақиқаттың бірыңғай көзі.
2. CI/CD-дегі линтерлер мен дифф-чектер: OpenAPI-diff, Buf-breaking, Euro/JSON Schema үйлесімділігін тексеру.
3. CDC/Consumer-Driven Contracts: провайдер тұтынушылардың нақты келісімшарттарына тексеріледі.
4. Golden samples: эталондық сұраулар/жауаптар/регресс оқиғалары.
5. Change management: RFC/ADR breaking, sunset жоспарлары, коммуникация.
Депрекейт және ескі нұсқаларын алып тастау
Ескірген белгіні қойыңыз ('@deprecated', сипаттамалар, 'Deprecation', 'Sunset' тақырыптары).
Көші-қон терезесі: алдын ала жарияланған күні, тестілеу стенді, код үлгілері.
Телеметрия пайдалану: тағы кім 'v1'? параметрлерді/логтарды нұсқа бойынша сегменттеңіз.
Dual-run трафиктің нөліне дейін, содан кейін - жою.
Бақылау және операциялық метриктер
Нұсқалар бойынша сұраулар/хабарлар пайызы.
Шығарылғаннан кейінгі қателер/таймауттар үлесі.
Сыйыспайтын payload үлесі (шлюздегі/стрим-сүзгідегі схемамен валидациялау).
Тұтынушылардың көші-қон лагі (әлі қанша 'v1' тыңдайды).
Кері үйлесімділікті тестілеу
Schema-diff: fail при remove/rename/type-change.
Келісімшарт-тесттер: ескі SDK/клиенттер жаңа іске асыруға қарсы.
E2E-канарейка: жаңа нұсқадағы ескі трафиктің бір бөлігі, p95/p99, кодтар, ретрайлерді салыстыру.
Оқиғалар репликасы: проекциялар алшақтықсыз ескі логикадан жаңа логикамен жиналады.
Fault-injection: кідірістер/ішінара жауаптар - ескі клиенттер құлдырамайды.
Мысалдар
REST (аддитивті)
Болды:json
{ "id": "p1", "status": "authorized" }
Болды:
json
{ "id": "p1", "status": "authorized", "risk_score": 0. 12 }
Ескі клиенттер 'risk _ score' дегенді елемей, жұмысын жалғастырады.
Protobuf (тегтер)
proto message Payment {
string id = 1;
string status = 2;
optional double risk_score = 3 ;//new field, safe
}
//Tags 1 and 2 cannot be changed/deleted without v2
Оқиғалар (ядро + байыту)
`payment. authorized. v1 '- өзек (минималды фактілер).
`payment. enriched. v1 '- бөлшектер; негізгі тұтынушылар байытуға тәуелді емес.
Антипаттерндер
Swagger-wash: сұлбаны жаңарттық, бірақ сервис бұрынғыдай (немесе керісінше).
Жасырын сынулар: өрістің/мәртебенің мәнін нұсқасыз өзгертті.
Protobuf-тегтерді қайта пайдалану: деректердің «тыныш» жемқорлығы.
Қатты клиенттер: беймәлім өрістерге құлайды/enum; толерант reader жоқ.
Mega-endpoint: бір-бірінде - кез келген өзгеріс әлеуетті сынуға айналады.
Шығару алдындағы чек парағы
- Өзгерістер аддитивті; ядро (MGC) қозғалған жоқ.
- Линтерлер/дифф-чектер өтті; breaking-жалаушалары жоқ.
- Клиенттік SDK жаңартылған (немесе аддитивті кеңейту үшін талап етілмейді).
- Клиенттерде tolerant reader қосылған; enum-fallback тексерілді.
- Метриктер/логтар нұсқасын және capability-жалауларын қамтиды.
- Әлеуетті сыну үшін '/v2 ', dual-run және sunset жоспары бар.
- Құжаттама/мысалдар жаңартылды, алтын жиынтықтар бар.
FAQ
Backward vs forward - айырмашылығы қандай?
Backward - жаңа серверлер ескі клиенттермен жұмыс істейді. Forward - жаңа клиенттер ескі серверлермен дұрыс жұмыс істейді (толерант reader және ұқыпты дефолттар есебінен). Толық шеңбер - full compatibility.
Үлкен өзгерістер үшін әрқашан '/v2 'жасау керек пе?
Иә, егер инварианттар/типтер/кілттер/семантика бұзылса. Әйтпесе, сызықты сақтаңыз және аддитивті түрде дамыңыз.
Enum туралы не істеу керек?
Ескілерінің мәнін өзгертпей, жаңа мәндер қосыңыз. Клиенттерде белгісіз мәнде fallback болуы керек.
Егер «сынған» болса не істеу керек?
Кері қайту, hot-fix адаптері, 'v2' шығарылымы dual-run, коммуникация және көші-қон гиді.
Жиынтығы
Кері үйлесімділік - бұл эволюция пәні: ядроны тұрақтандырыңыз, аддитивті кеңейтіңіз, толерантты reader енгізіңіз, тексерулерді автоматтандырыңыз және саналы түрде депрекейт жүргізіңіз. Осылайша сіз клиенттерді «көзге көрінбейтін» өзгерістердің қалдырмай платформаны жылдам дамыта аласыз.