În lumea dinamică a microserviciilor, orice componentă poate fi rescrisă într-o altă limbă, folosind cadre și arhitecturi diferite. Contractele ar trebui să rămână constant, astfel încât microserviciile să poată interacționa extern pe o bază constantă, indiferent de metamorfozele interne. Astăzi, vom vorbi despre dilema noastră în privința alegerii formatului de descriere a contractelor și vom împărtăși artefactele descoperite.

Postarea a fost pregătită și
Microservicii. În dezvoltarea Acronis Cyber Cloud, am realizat că nu ne putem feri de ele. Proiectarea unui microserviciu este imposibilă fără formalizarea contractului, care reprezintă interfața microserviciului.
Dar când produsul conține mai mult decât o singură componentă și dezvoltarea contractului devine o activitate regulată, începi să te gândești inevitabil la optimizarea procesului. Devine evident că interfața (contractul) și implementarea (microserviciul) trebuie să corespundă, că diferite componente trebuie să facă aceleași lucruri în mod uniform și că, fără o decizie centralizată, fiecare echipă va fi nevoită să își piardă timpul repetat în obținerea acestor decizii.

Schema microserviciilor Amazon din al lui Werner Vogels, CTO Amazon
Care este dilema? De facto, există două moduri de interacțiune între microservicii – HTTP Rest și gRPC de la Google. Neavând dorința de a fi implicați în tehnologiile Google, am ales HTTP Rest. Anotările pentru contractele HTTP REST sunt, de obicei, descrise într-unul dintre cele două formate: RAML și OAS, anterior cunoscut ca Swagger. Prin urmare, fiecare echipă de dezvoltatori se confruntă cu necesitatea de a alege unul dintre standarde. Dar, după cum s-a dovedit, această alegere poate fi foarte complicată.
De ce sunt necesare anotările?
O notă explicativă este necesară pentru ca utilizatorul extern să poată înțelege cu ușurință ce se poate face cu serviciul dvs. prin intermediul interfeței HTTP. Astfel, la un nivel de bază, nota trebuie să conțină cel puțin o listă a resurselor disponibile, metodele HTTP, trupurile cererilor, enumerarea parametrilor, specificarea antetelor necesare și acceptate, precum și codurile de răspuns și formatele răspunsurilor. Un element extrem de important al notei contractului este și descrierea verbală a acestora („ce se va întâmpla dacă adăugăm acest parametru de interogare în cerere?”, „în ce caz va reveni codul 400?”)
Cu toate acestea, atunci când vine vorba de dezvoltarea unui număr mare de microservicii, se dorește extragerea de beneficii suplimentare din notele scrise. De exemplu, pe baza RAML/Swagger se pot genera atât coduri client, cât și server pentru un număr uriaș de limbaje de programare. De asemenea, se poate obține automat documentația pentru microserviciu și o poate încărca pe portalul dvs. de dezvoltatori :).

Exemplu de descriere structurată a contractului
Practica testării microserviciilor pe baza descrierilor contractelor este mai rar întâlnită. Dacă ați scris atât nota, cât și componenta, atunci se poate crea un test automat care să verifice adecvarea funcționării serviciului cu diferite tipuri de date la intrare. Serviciul întoarce un cod de răspuns nerecunoscut în notă? Poate să proceseze corect datele evident greșite?
Mai mult decât atât, o implementare de calitate nu doar a contractelor, ci și a instrumentelor pentru vizualizarea notelor permite simplificarea lucrului cu microserviciul. Adică, dacă arhitectul a descris cu rigurositate contractul, pe baza acestuia, designerii și dezvoltatorii vor integra serviciul în alte produse fără cheltuieli de timp suplimentare.
Pentru funcționarea instrumentelor suplimentare, atât RAML, cât și OAS au capacitatea de a adăuga metadate, neprevăzute de standard ().
În general, câmpul pentru creativitate în aplicarea contractelor pentru microservicii este imens… cel puțin teoretic
Compararea ariciului cu șarpele
În prezent, direcția prioritară de dezvoltare la Acronis este Acronis Cyber Platform. Acronis Cyber Platform reprezintă noi puncte de integrare pentru servicii externe cu Acronis Cyber Cloud și partea agentului. Deși API-urile noastre interne, descrise în RAML, erau satisfăcătoare, necesitatea publicării API-ului a readus în discuție alegerea: care standard de anotare ar fi mai bun pentru naștere?
Inițial, părea că există două soluții — cele mai comune dezvoltări sunt RAML și Swagger (sau OAS). Dar, de fapt, s-a dovedit că alternativele sunt cel puțin 2, ba chiar 3 sau mai multe.
Pe de o parte, există RAML — un limbaj puternic și eficient. Acesta are o ierarhie și moștenire bine implementate, astfel încât acest format se potrivește mai bine companiilor mari, care necesită multe descrieri — adică nu un singur produs, ci multe microservicii care au părți comune ale contractelor — scheme de autentificare, tipuri de date identice, corpuri de erori.
Dar dezvoltatorul RAML, compania Mulesoft, s-a alăturat consorțiului Open API, care se ocupă cu evoluția . Așadar, RAML și-a oprit dezvoltarea. Pentru a-ți imagina formatul evenimentului, imaginează-ți că mentenanii componentelor de bază Linux au plecat să lucreze la Microsoft. Această situație creează premisele pentru utilizarea Swagger, care se dezvoltă dinamic și, în ultima — a treia versiune — aproape ajunge la RAML în ceea ce privește flexibilitatea și funcționalitatea.
Dacă nu ar fi un aspect…
După cum s-a dovedit, nu toate utilitarele open-source s-au actualizat la versiunea OAS 3.0. Pentru microservicii pe Go, lipsa adaptării la noua versiune a standardului va fi cea mai critică. Totuși, diferența dintre Swagger 2 și Swagger 3 este . De exemplu, în a treia versiune, dezvoltatorii:
- au îmbunătățit descrierea schemelor de autentificare
- suportul pentru JSON Schema
- au îmbunătățit capabilitatea de a adăuga exemple
Situația devine amuzantă: atunci când alegeți un standard, trebuie să luați în considerare RAML, Swagger 2 și Swagger 3 ca alternative separate. În acest context, doar Swagger 2 are un bun suport pentru uneltele OpenSource. RAML este foarte flexibil… și complex, iar Swagger 3 este slab susținut de comunitate, așa că va trebui să folosiți unelte dezvoltate intern sau soluții comerciale, care, în general, sunt destul de costisitoare.
În același timp, deși Swagger oferă multe oportunități plăcute, cum ar fi un portal gata pregătit , unde se poate încărca o adnotare și obține vizualizarea acesteia cu o descriere detaliată, linkuri și relații; însă pentru RAML, care este mai fundamental și mai puțin prietenos, nu există o asemenea posibilitate. Da, poți căuta ceva printre proiectele de pe GitHub, să găsești un analog și să îl implementezi singur. Totuși, în orice caz, cineva va trebui să sprijine portalul, ceea ce nu este foarte convenabil pentru utilizarea de bază sau pentru nevoile de testare. În plus, swagger este mai „imparțial”, sau mai liberal - poate fi generat din comentarii în cod, ceea ce, bineînțeles, contravine principiului API first și nu este suportat de niciunul dintre instrumentele RAML.
Noi am început să lucrăm cu RAML, ca fiind un limbaj mai flexibil, și în cele din urmă a trebuit să facem multe lucruri manual. De exemplu, într-unul dintre proiecte se utilizează instrumentul în teste unitare, care suportă doar RAML 0.8. Așadar, a fost nevoie să adăugăm soluții provizorii pentru ca instrumentul să poată „procesa” RAML versiunea 1.0.
Și este nevoie să alegem?
După ce ne-am obisnuit cu completarea ecosistemului de soluții pe baza RAML, am ajuns la concluzia că trebuie să convertim RAML în Swagger 2 și să realizăm automatizarea, verificarea, testarea și optimizarea ulterioară în acesta. Este o metodă bună de a utiliza atât flexibilitatea RAML, cât și suportul instrumentelor din comunitate oferit de Swagger.
Pentru această sarcină există două instrumente OpenSource care ar trebui să asigure conversia contractelor:
- – un instrument care nu mai este întreținut. În timpul lucrului cu acesta, am descoperit că întâmpină o serie de probleme cu RAML sofisticate, care sunt „întinse” pe un număr mare de fișiere. Această aplicație este scrisă în JavaScript și realizează o navigare recursivă în arborele sintactic. Din cauza tipizării dinamice, a devenit dificil să înțelegem acest cod, așa că am decis să nu pierdem timp scriind patch-uri pentru un instrument în declin.
- — un instrument de la aceeași companie, care pretinde că este gata să convertească tot și orice, în orice direcție. Până în prezent, este susținut RAML 0.8, RAML 1.0 și Swagger 2.0. Totuși, la momentul cercetării noastre, instrumentul era încă nefinisat și nepotrivit pentru utilizare. Dezvoltatorii creează un soi de , ceea ce le va permite să adauge rapid noi standarde în viitor. Dar, până acum, toate acestea pur și simplu nu funcționează.
Și aceasta nu este tot, ci doar o parte din dificultățile cu care ne-am confruntat. Unul dintre pașii din pipeline-ul nostru este să verificăm dacă RAML-ul din repository este corect în raport cu specificația. Am încercat mai multe utilitare. Uimitor, dar toate s-au plâns de anotările noastre în diferite locuri și cu cuvinte complet diferite. Și nu de fiecare dată pe bună dreptate :).
În cele din urmă, ne-am oprit la un proiect acum învechit, care are, de asemenea, o serie de probleme (uneori se prăbușește fără niciun motiv, are dificultăți în a lucra cu expresii regulate). Astfel, nu am găsit o modalitate de a rezolva problemele de validare și conversie bazându-ne pe instrumente gratuite și am decis să utilizăm o utilitate comercială. În viitor, când instrumentele OpenSource vor deveni mai avansate, poate că rezolvarea acestei probleme va deveni mai ușoară. Până atunci, costul în muncă și timp pentru „finisare” ne-a părut mai semnificativ decât costul serviciului comercial.
Concluzie
După toate acestea, ne-am dorit să împărtășim experiența și să subliniem că înainte de a alege un instrument pentru descrierea contractelor, trebuie să vă stabiliți clar ce doriți de la acesta și ce buget sunteți dispuși să investiți. Dacă uităm de OpenSource, deja există o mulțime de servicii și produse care pot ajuta să efectuezi verificări, să convertești, să validezi. Dar acestea sunt scumpe, iar uneori — foarte scumpe. Pentru o mare companie, astfel de cheltuieli sunt acceptabile, dar pentru un startup pot constitui o povară semnificativă.
Definiți setul de instrumente pe care le veți folosi mai târziu. De exemplu, dacă trebuie doar să afișați un contract, va fi mai simplu să folosiți Swagger 2, care are o API frumoasă, pentru că în RAML va trebui să ridicați și să mențineți serviciul pe cont propriu.
Cu cât aveți mai multe sarcini, cu atât va crește nevoia de instrumente, iar acestea sunt diferite pentru diferite platforme, așa că este mai bine să vă familiarizați din timp cu versiunile disponibile pentru a face o alegere care să minimizeze cheltuielile în viitor.
Trebuie să recunoaștem că toate ecosistemele existente astăzi sunt imperfecte. Așadar, dacă în companie sunt fani care adoră să lucreze cu RAML pentru că „îi permite să își exprime gândurile mai flexibil”, sau, dimpotrivă, preferă Swagger pentru că „este mai clar”, cel mai bine este să îi lăsăm să lucreze în ceea ce sunt obișnuiți și doresc, deoarece instrumentele fiecărui format necesită ajustări fine.
În ceea ce privește experiența noastră, în postările viitoare vom vorbi despre ce verificări statice și dinamice efectuăm pe baza arhitecturii noastre RAML-Swagger, precum și despre documentația pe care o generăm din contracte și despre cum funcționează totul.
Numai utilizatorii înregistrați pot participa la sondaj. , vă rugăm.
Ce limbaj folosiți pentru anotarea contractelor microserviciilor?
RAML 0.8
RAML 1.0
Swagger 2
OAS3 (cunoscuta și sub numele de)
Blueprint
Altele
Nu folosesc
Au votat 100 de utilizatori. S-au abținut 24 de utilizatori.
Sursa: habr.com
