paint-brush
Աղյուսակը որպես API: Պատրանքներ և իրականությունկողմից@truewebber
Նոր պատմություն

Աղյուսակը որպես API: Պատրանքներ և իրականություն

կողմից Aleksei Kish9m2025/03/05
Read on Terminal Reader

Չափազանց երկար; Կարդալ

Հեղինակը պնդում է, որ տվյալների բազայի ընդհանուր աղյուսակի օգտագործումը որպես ծառայություն-ծառայություն հաղորդակցության միջոց, հակաօրինաչափություն է: Թեև դա կարող է թվալ արագ լուծում, այն հանգեցնում է տարբերակման գլխացավերի, անհասկանալի սեփականության և մասշտաբայնության և անվտանգության հետ կապված դժվարությունների: Փոխարենը, հոդվածը պաշտպանում է «Պայմանագիր առաջինը» մոտեցումը, որտեղ յուրաքանչյուր ծառայություն պաշտոնապես սահմանում է իր միջերեսները և պահպանում է սեփական տվյալների նկատմամբ սեփականությունը: Այս մեթոդը խթանում է ավելի հստակ հաշվետվողականություն, ավելի հարթ էվոլյուցիա և թիմերի միջև ավելի ամուր ինտեգրում:
featured image - Աղյուսակը որպես API: Պատրանքներ և իրականություն
Aleksei Kish HackerNoon profile picture
0-item
1-item

Ներածություն

Ի՞նչ է «պայմանագիրը» ծառայության փոխազդեցության համատեքստում:

Ծառայությունների փոխազդեցության մոդուլների համատեքստում առաջանում է անխուսափելի հարցը. Ի՞նչ կանոններով է իրականացվում հաղորդակցությունը: ՏՏ արտադրանքներում «պայմանագիրը» ներկայացնում է պաշտոնական պատկերացում, թե ինչ տվյալներ են հոսում համակարգերի միջև և ինչպես են դրանք փոխանցվում: Սա ներառում է տվյալների ձևաչափը (JSON, Protobuf և այլն), կառուցվածքային տարրեր (դաշտեր, տվյալների տեսակներ), կապի արձանագրություն (REST, gRPC, հաղորդագրությունների հերթեր) և այլ բնութագրեր:


Պայմանագիրը ապահովում է բացություն (բոլորը գիտեն, թե ինչ է ստացվել և ուղարկվել), կանխատեսելիություն (մենք կարող ենք թարմացնել պայմանագիրը և պահպանել տարբերակները) և հուսալիություն (մեր համակարգը չի ձախողվի, եթե մենք լավ կառավարվող փոփոխություններ կատարենք):

Ինչու են մարդիկ հակված տվյալների բազայում աղյուսակ ընտրել որպես «պայմանագիր»:

Գործնականում, թեև բոլորը խոսում են միկրոծառայությունների, «պայմանագրերի» և API-ների մասին, մենք հաճախ տեսնում ենք, որ մարդիկ որդեգրում են այն մոտեցումը.


  • Պատմական կամ կազմակերպչական սովորություն. Երբ ամեն ինչ միշտ պահվել է մեկ DB համակարգում մեկ ընկերության ներսում, ինչո՞ւ նորից հորինել անիվը:


  • «Արագ ուղղման» մտածելակերպը. մենք կգրենք, դուք կկարդաք առանց թույլտվության կանոններ սահմանելու և API-ի առանձնահատկությունները նախագծելու:


  • «Մեծ տվյալներ» փաստարկ. Տասնյակ կամ նույնիսկ հարյուրավոր գիգաբայթ տվյալների հետ աշխատելիս ընդհանուր աղյուսակում ուղղակի փոխանցումն ավելի պարզ, արագ և խնայող է թվում, բայց գործնականում այն ստեղծում է մասշտաբայնության և կատարողականի խնդիրներ, ինչպես նաև տվյալների սեփականության հետ կապված խնդիրներ:


Հետևաբար, թեև տվյալների փոխանակման համար ընդհանուր աղյուսակի օգտագործումը կարող է արդյունավետ և օպտիմիզացված թվալ արագ արդյունքների համար, այն երկարաժամկետ հեռանկարում առաջացնում է տարբեր տեխնիկական և կազմակերպչական մարտահրավերներ: Այնուամենայնիվ, երբ թիմերը ընտրում են ընդհանուր աղյուսակներ տվյալների փոխանակման համար, նրանք կարող են բախվել բազմաթիվ խնդիրների իրականացման ընթացքում:

Ինչու՞ «Տվյալների բազայում աղյուսակը» պայմանագիր չէ (և ինչու է այն հակաօրինաչափություն):

Հստակ սահմանված ինտերֆեյսի բացակայություն

Երբ ծառայությունները հաղորդակցվում են REST/gRPC/GraphQL-ի միջոցով, դրանք ունեն պաշտոնական սահմանում՝ OpenAPI (Swagger), պրոտոբուֆ սխեմաներ կամ GraphQL սխեմաներ: Սրանք մանրամասնորեն սահմանում են, թե որ ռեսուրսները (վերջնական կետերը) են հասանելի, որ դաշտերը սպասվում են, դրանց տեսակները և հարցում/պատասխանի ձևաչափերը: Երբ «ընդհանուր աղյուսակը» գործում է որպես պայմանագիր, չկա պաշտոնական նկարագրություն. չկա պայմանագրի պաշտոնական նկարագրություն. հասանելի է միայն աղյուսակի սխեման (DDL), և նույնիսկ դա լավ փաստագրված չէ: Աղյուսակի կառուցվածքի ցանկացած աննշան փոփոխություն (օրինակ՝ սյունակի ավելացում կամ ջնջում, տվյալների տեսակների փոփոխություն) կարող է ազդել այլ թիմերի վրա, որոնք կարդում կամ գրում են այս աղյուսակից:

Տարբերակման և էվոլյուցիայի խնդիրներ

API-ի տարբերակավորումը սովորական պրակտիկա է. մենք կարող ենք ունենալ v1, v2 և այլն, և մենք կարող ենք պահպանել հետընթաց համատեղելիությունը, այնուհետև աստիճանաբար հաճախորդներին տեղափոխել ավելի նոր տարբերակներ: Տվյալների բազայի աղյուսակների համար մենք ունենք միայն DDL գործողություններ (օրինակ՝ ALTER TABLE ), որոնք սերտորեն կապված են որոշակի DB շարժիչի հետ և պահանջում են միգրացիաների մանրակրկիտ մշակում:


Չկա կենտրոնացված համակարգ, որը կարող է ծանուցումներ ուղարկել սպառողներին սխեմայի փոփոխությունների մասին, որոնք պահանջում են թարմացնել իրենց հարցումները: Արդյունքում կարող են տեղի ունենալ «սեղանի տակ» գործարքներ . ինչ-որ մեկը կարող է չաթում տեղադրել «Վաղը մենք X սյունակը կփոխենք Y-ի», բայց երաշխիք չկա, որ բոլորը ժամանակին պատրաստ կլինեն:

Չկա հստակ սեփականություն

Երբ կա հստակ սահմանված API, ակնհայտ է, թե ում է պատկանում այն՝ ծառայությունը, որը ծառայում է որպես API հրատարակիչ: Երբ մի քանի թիմեր օգտագործում են տվյալների բազայի միևնույն աղյուսակը, շփոթություն է առաջանում, թե ով կարող է որոշել կառուցվածքը և որ դաշտերը պահել և ինչպես մեկնաբանել դրանք: Արդյունքում, աղյուսակը կարող է դառնալ «ոչ մեկի սեփականությունը», և յուրաքանչյուր փոփոխություն դառնում է որոնում. «Մենք պետք է ստուգենք մյուս թիմը, եթե նրանք օգտագործում են հին սյունակը»:

Անվտանգության և մուտքի վերահսկման խնդիրներ

Դժվար է հետևել, թե ով կարող է կարդալ և գրել սեղանի վրա, եթե շատ թիմեր մուտք ունեն DB: Հնարավորություն կա, որ չարտոնված ծառայությունները կարող են մուտք գործել տվյալներ, թեև դրանք նախատեսված չեն նրանց համար: Ավելի հեշտ է կառավարել նման խնդիրները API-ով. Դուք կարող եք վերահսկել մուտքի իրավունքները (ով կարող է զանգահարել, թե որ մեթոդներին), օգտագործել նույնականացում և թույլտվություն և վերահսկել, թե ով ինչ է զանգահարել: Սեղանի դեպքում դա շատ ավելի բարդ է:

Կախվածությունը ներքին կառուցվածքից

Տվյալների ցանկացած ներքին փոփոխություն (ինդեքսների վերակազմավորում, աղյուսակի բաժանում, DB-ի փոփոխություն) դառնում է գլոբալ խնդիր: Եթե աղյուսակը գործում է որպես հանրային ինտերֆեյս, սեփականատերը չի կարող ներքին փոփոխություններ կատարել՝ առանց վտանգի ենթարկելու բոլոր արտաքին ընթերցողներին և գրողներին:

Ցավի կետերը և տիպիկ խնդիրները գործնականում

Համակարգող փոփոխություններ

Սա ամենացավալին կողմն է. ինչպե՞ս կարելի է մեկ այլ թիմին տեղեկացնել, որ հաջորդ օրը սխեման փոխվելու է:

  • Աղյուսակի տարբերակի թարմացման հաջողված սցենար. սեփականատերը հինին զուգահեռ ստեղծում է նոր աղյուսակ՝ թարմացված սխեմայով: Հին տարբերակը հասանելի է մնում ներկայիս սպառողներին, և սեփականատերը նրանց հաղորդագրություն է ուղարկում, որտեղ ասվում է. «Նոր կառուցվածքը հասանելի է. ստուգեք փաստաթղթերը և ժամկետները: Խնդրում ենք տեղափոխել, քանի դեռ երկու տարբերակներն էլ կան»։


  • Այնուամենայնիվ, OLAP-ի սցենարում կամ տվյալների մեծ ծավալով, երկու զուգահեռ աղյուսակների պահպանումը աննշան խնդիր չէ: Դուք նաև պետք է որոշեք, թե ինչպես տեղափոխել տվյալները հին սխեմայից նոր: Սա երբեմն կարող է պահանջել պլանավորված պարապուրդ կամ շատ բարդ ենթակառուցվածք: Այս գործընթացն անպայման ենթադրում է և՛ ռիսկ, և՛ լրացուցիչ աշխատանք:

Տվյալների ամբողջականության խնդիրներ

Երբ մի քանի թիմեր օգտագործում են ընդհանուր աղյուսակը կարևոր տվյալներ ընտրելու և թարմացնելու համար, այն հեշտությամբ կարող է դառնալ «ռազմի դաշտ»: Արդյունքն այն է, որ բիզնեսի տրամաբանությունն ավարտվում է ցրված տարբեր ծառայություններում, և տվյալների ամբողջականության կենտրոնացված վերահսկողություն չկա: Շատ դժվար է դառնում իմանալ, թե ինչու է որոշակի դաշտը պահվում որոշակի ձևով, ով կարող է թարմացնել այն և ինչ է տեղի ունենում, եթե այն դատարկ մնա:

Վրիպազերծման և մոնիտորինգի մարտահրավերներ

Օրինակ, ենթադրենք, որ աղյուսակը կոտրվում է. ասենք, վատ տվյալներ կան կամ ինչ-որ մեկը կողպել է որոշ կարևոր տողեր: Խնդրի աղբյուրը բացահայտելու համար հաճախ կարող է պահանջվել DB մուտք ունեցող յուրաքանչյուր թիմից խնդրել՝ որոշելու, թե որ հարցումն է առաջացրել խնդիրը: Դա հաճախ ակնհայտ չէ. սա նշանակում է, որ մի թիմի հարցումը կարող է արգելափակել տվյալների բազան, մինչդեռ մյուս թիմի հարցումն առաջացնում է նկատելի սխալ:

Մեկ հանգույցի ձախողումը բոլորին քաշում է ներքեւ:

Համօգտագործվող տվյալների բազան ձախողման մեկ կետ է: Եթե այն իջնի, ապա դրա հետ շատ ծառայություններ կիջնեն։ Երբ տվյալների բազան աշխատանքի հետ կապված խնդիրներ ունի մեկ ծառայության ծանր հարցումների պատճառով, բոլոր ծառայությունները խնդիրներ են ունենում: Հստակ API-ներով և տվյալների սեփականություն ունեցող մոդելում յուրաքանչյուր թիմ տիրապետում է իր ծառայության հասանելիությանը և կատարողականին, ուստի մի բաղադրիչի ձախողումը չի տարածվում մյուսների վրա:

Միայն կարդալու համար առանձին կրկնօրինակ տրամադրելը խնդիրը չի լուծում:

Ընդհանուր փոխզիջումը հետևյալն է. «Մենք ձեզ կտրամադրենք միայն կարդալու կրկնօրինակ, որպեսզի կարողանաք հարցումներ կատարել՝ առանց մեր հիմնական տվյալների բազայի վրա ազդելու»: Սկզբում դա կարող է լուծել ծանրաբեռնվածության որոշ խնդիրներ, բայց.

  • Տարբերակման խնդիրները մնում են: Հիմնական խնդիրն այն է, որ երբ հիմնական աղյուսակի կառուցվածքը փոխվում է, կրկնօրինակի կառուցվածքը նույնպես փոխվում է, պարզապես որոշ ուշացումով:


  • Կրկնօրինակման հետաձգումը կարող է հանգեցնել տվյալների վիճակների անկանխատեսելի լինելուն, հատկապես մեծ տվյալների հավաքածուների դեպքում:


  • Սեփականության իրավունքը դեռևս պարզ չէ. ո՞վ է սահմանում ձևաչափը, կառուցվածքը և օգտագործման կանոնները: Կրկնօրինակը դեռևս ուրիշի տվյալների բազայի «մի կտոր» է:

Ինչպես ճիշտ ձևավորել ծառայության փոխազդեցությունը (առաջին պայմանագիրը)

Պայմանագրի հստակ սահմանում.

Դիզայնի ժամանակակից պրակտիկան (օրինակ՝ «API First» կամ «Contract First») սկսվում է ինտերֆեյսի պաշտոնական սահմանմամբ: Օգտագործվում են OpenAPI/Swagger, protobuf կամ GraphQL սխեմաներ: Այսպիսով, և՛ մարդիկ, և՛ մեքենաները գիտեն, թե որ վերջնակետերն են հասանելի, որ դաշտերն են պահանջվում և ինչ տվյալների տեսակներ են օգտագործվում:

Ծառայություն որպես տվյալների սեփականատեր

Միկրոծառայությունների (կամ նույնիսկ մոդուլային) ճարտարապետության մեջ ենթադրվում է, որ յուրաքանչյուր ծառայություն ամբողջությամբ տիրապետում է իր տվյալներին: Այն սահմանում է կառուցվածքը, պահեստավորումը և բիզնես տրամաբանությունը և ապահովում է API՝ այդ API-ի բոլոր արտաքին մուտքի համար: Ոչ ոք չի կարող դիպչել «ուրիշի» տվյալների բազային. միայն պաշտոնական վերջնական կետերը կամ իրադարձությունները: Սա հեշտացնում է կյանքը, երբ փոփոխությունները հարցականի տակ են, և միշտ պարզ է, թե ով է մեղավոր:

Իրականացման օրինակներ

  • REST/HTTP. Ծառայությունը հրապարակում է վերջնակետեր, ինչպիսիք են GET /items , POST /items , և այլն, և հաճախորդները հարցումներ են կատարում տվյալների հստակ սահմանված սխեմայով (DTO):


  • gRPC / երկուական արձանագրություններ. gRPC/protobuf-ում ծառայությունը և հաղորդագրությունները պաշտոնապես սահմանվում են .proto ֆայլերում, և փոփոխությունները պարզապես կատարվում են .proto ֆայլերում, որտեղ սահմանված են մեթոդը, հարցումը և պատասխանը:


  • Իրադարձությունների վրա հիմնված. Տվյալների սեփականատեր ծառայությունը հրապարակում է իրադարձություններ այնպիսի բրոքերի, ինչպիսիք են Kafka-ն կամ RabbitMQ-ն, և բաժանորդները սպառում են դրանք: Պայմանագիրն այստեղ միջոցառման ձևաչափն է: Կառուցվածքային փոփոխությունները կատարվում են տարբերակված թեմաների կամ հաղորդագրությունների միջոցով:

Տարբերակի վերահսկում

Անկախ նրանից, թե որ մոդելն է, ինտերֆեյսի վրա տարբերակի վերահսկումն իրականացնելը և՛ հնարավոր է, և՛ կարևոր: Օրինակ՝

  • REST-ում մենք ունենք /api/v1/… և /api/v2/:


  • GRPC/protobuf-ի հետ կան հզոր մեխանիզմներ հետընթաց/առաջընթաց համատեղելիության համար. նոր դաշտեր, հաղորդագրություններ և մեթոդներ կարող են ավելացվել առանց հին հաճախորդները կոտրելու, մինչդեռ մյուսները նշված են որպես հնացած:


  • Իրադարձությունների վրա հիմնված ճարտարապետություններում դուք կարող եք զուգահեռաբար հրապարակել իրադարձությունների հին և նոր ձևաչափերը, մինչև բոլոր սպառողները տեղափոխվեն:

Բաշխված պատասխանատվություն

Հիմնարար սկզբունքն այն է, որ թիմը, որը տիրապետում է տվյալներին, պետք է որոշի, թե ինչպես պահել և կառավարել դրանք, բայց նրանք չպետք է ուղղակիորեն մուտքագրեն այլ ծառայություններ: Մյուսները պետք է անցնեն API-ի միջոցով՝ ի տարբերություն օտարերկրյա տվյալների խմբագրման: Սա հանգեցնում է պատասխանատվության ավելի հստակ բաշխման. Եթե A ծառայությունը խափանված է, ապա դա շտկելու ծառայության պարտականությունն է ոչ թե հարևանները:

Ծառայությունների փոխազդեցության օրինակներ

Մեկ թիմում

Առաջին հայացքից, եթե ամեն ինչ մեկ թիմում է, ինչո՞ւ բարդացնել ամեն ինչ API-ով: Իրականում, նույնիսկ եթե դուք ունեք մեկ արտադրանք, որը բաժանված է մոդուլների, ընդհանուր աղյուսակը կարող է հանգեցնել նույն խնդիրների:


  • Ավելի լավ է ստեղծել «ֆասադ» կամ «միկրոծառայություն», որը պատկանում է «պատվերների» աղյուսակին, օրինակ, և այնուհետև այլ մոդուլներ (օրինակ՝ վերլուծականները) կոչեն այս ֆասադ/ծառայություն:


  • Սա պարզ է դարձնում պայմանագրի սկզբունքը և հեշտացնում է վրիպազերծումը:


Օրինակ՝ Պատվերների ծառայությունը պատվերների աղյուսակի սեփականատերն է, և Billing ծառայությունն ուղղակիորեն մուտք չի գործում այդ աղյուսակը. այն զանգեր է կատարում պատվերների ծառայության վերջնակետեր՝ պատվերի մանրամասները ստանալու կամ պատվերը որպես վճարված նշելու համար:

Երկու թիմերի միջև

Ավելի բարձր մակարդակում, երբ երկու կամ ավելի թիմեր պատասխանատու են տարբեր ոլորտների համար, սկզբունքները մնում են նույնը: Օրինակ՝

  • Ա թիմը պատասխանատու է ապրանքների կատալոգի ծառայության համար, որը պարունակում է տեղեկատվություն յուրաքանչյուր ապրանքի մասին (գին, մատչելիություն, հատկանիշներ):


  • Բ թիմը հոգ է տանում զամբյուղի սպասարկման մասին:


Եթե B թիմն ուղղակիորեն հարցումներ կատարի A թիմին պատկանող «Կատալոգ» աղյուսակին, A-ում ներքին սխեմայի ցանկացած փոփոխություն (օրինակ՝ դաշտերի ավելացում, կառուցվածքի փոփոխություն) կարող է ազդել Բ թիմի վրա:


Ճիշտ մոտեցումը API-ի օգտագործումն է. A թիմը տրամադրում է վերջնակետեր, ինչպիսիք են GET /catalog/items , GET /catalog/items/{id} և այլն, և B թիմը օգտագործում է այդ մեթոդները: Եթե A-ն ի վիճակի է աջակցել ավելի հին և նոր տարբերակներին, նրանք կարող են թողարկել /v2, ինչը B-ին ժամանակ է տալիս միգրացիայի համար:

Կազմակերպչական ասպեկտներ և առավելություններ

Թափանցիկ հաղորդակցություն

Պաշտոնական պայմանագրով բոլոր փոփոխությունները տեսանելի են՝ Swagger/OpenAPI-ում, .proto ֆայլերում կամ իրադարձությունների փաստաթղթերում: Ցանկացած թարմացում կարող է նախօրոք քննարկվել, պատշաճ կերպով փորձարկվել և պլանավորվել՝ անհրաժեշտության դեպքում հետ համատեղելիության ռազմավարություններով:

Ավելի արագ զարգացում

Մեկ ծառայության փոփոխությունները ավելի քիչ ազդեցություն են ունենում մյուսների վրա: Թիմը չպետք է անհանգստանա մեկ ուրիշին «կոտրելու» մասին, եթե նրանք պատշաճ կերպով կառավարեն նոր և հին դաշտերը կամ վերջնակետերը՝ ապահովելով սահուն անցում:

Մուտքի և անվտանգության կառավարում

API-ի դարպասները, նույնականացումը և թույլտվությունը (JWT, OAuth) ստանդարտ են ծառայությունների համար, բայց գրեթե անհնար է ընդհանուր աղյուսակի դեպքում: Ավելի հեշտ է կարգավորել մուտքը (ով կարող է զանգահարել, որ մեթոդներին), պահել տեղեկամատյանները, հետևել օգտագործման վիճակագրությանը և սահմանել քվոտաներ: Սա համակարգը դարձնում է ավելի անվտանգ և կանխատեսելի:

Եզրակացություն

Տվյալների բազայի համօգտագործվող աղյուսակը ավելի շուտ կատարման դետալ է, քան ծառայությունների միջև համաձայնություն, ուստի պայմանագիր չի համարվում: Բազմաթիվ խնդիրները (բարդ տարբերակների ձևավորում, քաոսային փոփոխություններ, անհասկանալի սեփականության իրավունք, անվտանգություն և կատարողականի ռիսկեր) երկարաժամկետ հեռանկարում այս մոտեցումն անհիմն են դարձնում:


Ճիշտ մոտեցումը Contract First-ն է, որը նշանակում է փոխազդեցության սահմանում պաշտոնական ձևավորման միջոցով և հետևելով այն սկզբունքին, որ յուրաքանչյուր ծառայություն մնում է իր տվյալների սեփականատերը: Սա ոչ միայն օգնում է նվազեցնել տեխնիկական պարտքը, այլև մեծացնում է թափանցիկությունը, արագացնում է արտադրանքի զարգացումը և հնարավորություն է տալիս անվտանգ փոփոխություններ կատարել՝ առանց տվյալների բազայի սխեմաների հրդեհաշիջման:


Դա և՛ տեխնիկական խնդիր է (ինչպես ձևավորել և ինտեգրվել), և՛ կազմակերպչական (ինչպես են թիմերը հաղորդակցվում և կառավարում փոփոխությունները): Եթե ցանկանում եք, որ ձեր արտադրանքը աճի առանց տվյալների բազայի սխեմաների հետ կապված անվերջ արտակարգ իրավիճակների հետ գործ ունենալու, ապա դուք պետք է սկսեք մտածել պայմանագրերի, այլ ոչ թե տվյալների բազայի ուղղակի հասանելիության մասին: