Experiența noastră în crearea unui API Gateway

Unele companii, inclusiv clientul nostru, își dezvoltă produsele printr-o rețea de parteneri. De exemplu, magazinele online mari sunt integrate cu serviciile de livrare — comanzi un produs și, în curând, primești un număr de urmărire pentru pachet. Un alt exemplu ar fi că, împreună cu biletul de avion, achiziționezi o asigurare sau un bilet pentru aerotren.

Pentru aceasta se folosește un singur API, pe care trebuie să-l oferim partenerilor prin API Gateway. Aceasta a fost sarcina pe care ne-am propus să o realizăm. În acest articol, vom oferi detalii.

Dat: un ecosistem și un portal API cu o interfață unde utilizatorii sunt înregistrați, primesc informații etc. Trebuie să construim un API Gateway convenabil și fiabil. În proces, trebuie să ne asigurăm de

  • înregistrare,
  • controlul conexiunii la API,
  • monitorizarea modului în care utilizatorii folosesc sistemul final,
  • înregistrarea indicatorilor de afaceri.

Experiența noastră în crearea unui API Gateway

În articol, vom vorbi despre experiența noastră în crearea API Gateway, în cadrul căreia am abordat următoarele sarcini:

  • autentificarea utilizatorului,
  • autorizarea utilizatorului,
  • modificarea cererii inițiale,
  • proximarea cererii,
  • post-procesarea răspunsului.


Există două tipuri de management API:

1. Standard, care funcționează astfel. Înainte de conectare, utilizatorul testează funcționalitățile, apoi plătește și integrează pe site-ul său. Este folosit cel mai frecvent în micile și mijloacele întreprinderi.

2. Management API B2B de mari dimensiuni, când compania ia mai întâi o decizie de business pentru conectare, devine partener al companiei cu obligații contractuale, după care se conectează la API. Și doar după ce se încheie toate formalitățile, compania primește acces de testare, trece prin teste și intră în producție. Dar acest lucru nu este posibil fără o decizie managerială de conectare.

Experiența noastră în crearea unui API Gateway

Soluția noastră

În această parte, vom discuta despre crearea API Gateway.

Utilizatorii finali ai gateway-ului API creat sunt partenerii clientului nostru. Pentru fiecare dintre ei, deja avem contractele necesare. Va trebui doar să extindem funcționalitatea, marcând accesul oferit la gateway. Prin urmare, este nevoie de un proces controlat de conectare și gestionare.

Desigur, ar fi putut fi utilizată o soluție gata pregătită pentru a rezolva sarcina de management API și crearea API Gateway în particular. De exemplu, aceasta ar putea fi Azure API Management. Nu ne-a fost potrivit, deoarece în cazul nostru aveam deja un portal API și un ecosistem vast construit în jurul său. Toți utilizatorii erau deja înregistrați, știau deja unde și cum pot obține informațiile necesare. Portalul API avea deja interfețele necesare, noi aveam nevoie doar de un API Gateway. Practic, asta am dezvoltat.

Ceea ce numim API Gateway este un fel de proxy. Aici am avut din nou alegerea — putem să scriem propriul nostru proxy sau să alegem ceva deja existent. În acest caz, am ales a doua variantă și am optat pentru combinația nginx+Lua. De ce? Aveam nevoie de un software fiabil, testat, care să suporte scalarea. Nu voiam, după implementare, să verificăm și corectitudinea logicii de business, și corectitudinea funcționării proxy-ului.

Orice server web are un pipeline de procesare a cererilor. În cazul nginx, acesta arată astfel:

Experiența noastră în crearea unui API Gateway

(schema din GitHub Lua Nginx)

Scopul nostru a fost să ne integrăm în acest pipeline în acel moment în care putem modifica cererea inițială.

Dorim să creăm un proxy transparent, astfel încât cererea să rămână funcțional aceeași cu cea care a venit. Noastră doar controlăm accesul la API-ul final, ajutăm cererea să ajungă la acesta. În cazul în care cererea a fost incorectă, eroarea ar trebui să fie afișată de API-ul final, nu de noi. Singurul motiv pentru care putem respinge o cerere este lipsa accesului clientului.

Pentru nginx există deja extensie pe Lua. Lua este un limbaj de scripting, foarte ușor și simplu de învățat. Astfel, logica necesară a fost implementată folosind Lua.

Configurația nginx-ului (analogia cu rutele aplicației), unde se desfășoară toată munca, este destul de clară. Notabil aici este ultima directivă — post_action.

location /middleware {
      more_clear_input_headers Accept-Encoding;
      lua_need_request_body on;
      rewrite_by_lua_file 'middleware/rewrite.lua';
      access_by_lua_file 'middleware/access.lua';
      proxy_pass https://someurl.com;
      body_filter_by_lua_file 'middleware/body_filter.lua';
      post_action /process_session;
}

Să examinăm ce se întâmplă în această configurație:
more_clear_input_headers — curăță valorile specificate după directivă ale headerelor.
lua_need_request_body — reglează dacă ar trebui să citim corpul inițial al cererii înainte de a executa directivele rewrite/access/access_by_lua sau nu. Implicit, nginx nu citește corpul cererii clientului, iar dacă aveți nevoie de acces la acesta, atunci această directivă ar trebui să fie activată.
rewrite_by_lua_file — calea către script, în care este descrisă logica de modificare a cererii
access_by_lua_file — calea către scriptul, în care este descrisă logica ce verifică existența accesului la resursă.
proxy_pass — url-ul, la care va fi proxificat cererea.
body_filter_by_lua_file — calea către script, în care este descrisă logica pentru filtrarea cererii înainte de a fi returnată clientului.
Și, în sfârșit, post_action — directivă oficial nedocumentată, prin care pot fi efectuate și alte acțiuni după ce răspunsul a fost dat clientului.

Mai jos vom explica în ordine cum ne-am rezolvat sarcinile.

Autentificare și modificare a cererii

Autorizare

Autentificarea și autentificarea le-am realizat prin acces bazat pe certificat. Există un certificat rădăcină. Fiecărui nou client al contractorului îi este generat un certificat personal, cu care poate accesa API-ul. Acest certificat este configurat în secțiunea server a setărilor nginx.

ssl on;
ssl_certificate /usr/local/openresty/nginx/ssl/cert.pem;
ssl_certificate_key /usr/local/openresty/nginx/ssl/cert.pem;
ssl_client_certificate /usr/local/openresty/nginx/ssl/ca.crt;
ssl_verify_client on;

Modificare

Se poate pune o întrebare legitimă: ce să facem cu clientul certificat, dacă am dorit brusc să-l deconectăm de la sistem? Nu putem să reemitem certificate pentru toți ceilalți clienți.

Așa am ajuns treptat la următoarea sarcină — modificarea cererii inițiale. Cererea inițială a clientului, în general, nu este validă pentru sistemul final. Una dintre sarcini constă în a completa cererea cu părțile lipsă, pentru a o face validă. Substanța este că datele lipsă sunt diferite pentru fiecare client. Știm că clientul vine la noi cu un certificat, al cărui amprente îl putem extrage din baza de date pentru a obține datele necesare clientului.

Dacă la un moment dat va fi necesar să deconectăm clientul de serviciul nostru, datele sale vor dispărea din bază și nu va mai putea face nimic.

Lucrul cu datele clientului

A trebuit să asigurăm o disponibilitate ridicată a soluției, în special în ceea ce privește modul în care obținem datele clientului. Complexitatea constă în faptul că sursa acestor date este un serviciu terț, care nu garantează o funcționare neîntreruptă și o viteză suficient de mare.

Prin urmare, a trebuit să asigurăm o disponibilitate ridicată a datelor clienților. Ca instrument am ales Hazelcast, care ne oferă:

  • acces rapid la date,
  • posibilitatea de a organiza un cluster din mai multe noduri cu date replicate pe noduri diferite.

Am urmat cea mai simplă strategie de livrare a datelor în cache:

Experiența noastră în crearea unui API Gateway

Lucrul cu sistemul final se desfășoară în cadrul sesiunilor și există o limită asupra numărului maxim. Dacă clientul nu a închis sesiunea, va trebui să o facem noi.

Datele despre sesiunea deschisă vin de la sistemul final și sunt procesate inițial pe partea Lua. Am decis să folosim Hazelcast pentru a salva aceste date printr-un job scris în .NET. Apoi, cu o anumită periodicitate, verificăm dreptul de a trăi al sesiunilor deschise și închidem cele expirate.

Accesul la Hazelcast atât din Lua, cât și din .NET

Nu există clienți Lua pentru a lucra cu Hazelcast, dar Hazelcast are un REST API, pe care am decis să-l folosim. Pentru .NET există client, prin care ne-am planificat să obținem acces la datele Hazelcast pe partea .NET. Dar nu a fost așa de simplu.

Experiența noastră în crearea unui API Gateway

La salvarea datelor prin REST și extragerea acestora prin clientul .NET sunt folosite diferite serializatoare-deserializatoare. Prin urmare, nu este posibil să introduci date prin REST și să le extragi prin clientul .NET și invers.

Dacă există persoane interesate, vom vorbi mai în detaliu despre această problemă într-un articol separat. Spoiler — în diagrama.

Experiența noastră în crearea unui API Gateway

Logare și monitorizare

Standardul nostru corporativ pentru logare prin .NET este Serilog, toate logurile ajung în final în Elasticsearch, iar analiza acestora o facem prin Kibana. Ne-am dorit să realizăm ceva similar și în acest caz. Singurul client client găsit pentru a lucra cu Elastic pe Lua s-a defectat la primul require. Și am folosit Fluentd.

Fluentd este o soluție open source pentru asigurarea unui strat unic de logare a aplicației. Permite colectarea logurilor de la diferite niveluri ale aplicației și apoi transmițându-le într-o singură sursă.

API Gateway funcționează în K8S, așa că am decis să adăugăm un container cu fluentd în același pod, pentru a scrie logurile în portul tcp deschis existent pentru fluentd.

De asemenea, am cercetat cum se va comporta fluentd, dacă nu va avea conexiune cu Elasticsearch. Timp de două zile, cererile au venit continuu în gateway, logurile au fost trimise în fluentd, dar fluentd a fost blocat de IP-ul Elastic. După restabilirea conexiunii, fluentd a transferat toate logurile în Elastic.

Concluzie

Abordarea aleasă pentru implementare ne-a permis să livrăm un produs funcțional în mediu de producție în doar 2.5 luni.

Dacă vreodată va trebui să vă ocupați de astfel de lucruri, vă recomandăm să înțelegeți clar ce problemă rezolvați și ce resurse aveți deja. Fiți atenți la dificultățile integrării cu sistemele de gestionare API existente.

Înțelegeți pentru dumneavoastră ce anume intenționați să dezvoltați — doar logica de afaceri pentru procesarea cererilor sau, așa cum a fost în cazul nostru, un proxy întreg. Nu uitați că tot ce faceți singuri trebuie testat în mod riguros ulterior.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster