Niektoré spoločnosti, vrátane nášho zákazníka, vyvíjajú produkt prostredníctvom partnerskej siete. Napríklad veľké internetové obchody sú integrované s doručovacou službou – objednáte si produkt a čoskoro dostanete sledovacie číslo balíka. Ďalším príkladom je, keď si spolu s letenkou kúpite poistenie alebo letenku Aeroexpress.
Na to sa používa jedno API, ktoré musí byť vydané partnerom cez API Gateway. Tento problém sme vyriešili. V tomto článku vám povieme podrobnosti.
Dané: ekosystém a API portál s rozhraním, kde sú používatelia registrovaní, dostávajú informácie atď. Musíme vytvoriť pohodlnú a spoľahlivú bránu API. V procese sme potrebovali poskytnúť
- registrácia,
- ovládanie pripojenia API,
- sledovanie toho, ako používatelia používajú koncový systém,
- účtovanie obchodných ukazovateľov.

V článku si povieme o našich skúsenostiach s vytváraním API Gateway, počas ktorých sme riešili nasledovné úlohy:
- autentifikácia užívateľa,
- autorizácia užívateľa,
- úprava pôvodnej žiadosti,
- požiadať o proxy,
- následné spracovanie odpovede.
Existujú dva typy správy API:
1. Štandard, ktorý funguje nasledovne. Pred pripojením používateľ otestuje funkcie, potom zaplatí a vloží na svoju stránku. Najčastejšie sa používajú v malých a stredných podnikoch.
2. Veľký B2B API Management, keď spoločnosť najprv urobí obchodné rozhodnutie o pripojení, stane sa partnerom spoločnosti so zmluvným záväzkom a následne sa pripojí k API. A po vybavení všetkých formalít spoločnosť získa testovací prístup, prejde testovaním a ide do výroby. Ale to nie je možné bez rozhodnutia vedenia o pripojení.

Naše riešenie
V tejto časti si povieme niečo o vytvorení API brány.
Koncovými používateľmi vytvorenej API brány sú partneri nášho zákazníka. Na každú z nich už máme potrebné zmluvy. Funkcionalitu budeme potrebovať len rozšíriť označením udeleného prístupu k bráne. Preto je potrebný riadený proces pripojenia a riadenia.
Samozrejme, bolo možné vziať nejaké hotové riešenie na vyriešenie problému API Management a najmä vytvorenie API Gateway. Napríklad toto môže byť. Nevyhovovalo nám to, pretože v našom prípade sme už mali API portál a okolo neho vybudovaný obrovský ekosystém. Všetci používatelia už boli zaregistrovaní, už pochopili, kde a ako môžu získať potrebné informácie. Potrebné rozhrania už v API portáli existovali, potrebovali sme len API Gateway. V skutočnosti sa podieľame na jeho vývoji.
To, čo nazývame API Gateway, je druh proxy. Tu sme mali opäť na výber – môžete si napísať vlastnú proxy, alebo si vybrať niečo hotové. V tomto prípade sme išli druhou cestou a vybrali sme si balík nginx + Lua. prečo? Potrebovali sme spoľahlivý, testovaný softvér, ktorý podporuje škálovanie. Po implementácii sme nechceli kontrolovať aj správnosť obchodnej logiky a správnosť proxy.
Každý webový server má kanál na spracovanie požiadaviek. V prípade nginx to vyzerá takto:

(schéma z )
Naším cieľom bolo zapadnúť do tohto potrubia v bode, kde môžeme upraviť pôvodnú požiadavku.
Chceme vytvoriť transparentnú proxy, aby požiadavka zostala funkčne taká, ako prišla. Kontrolujeme iba prístup k finálnemu API, pomáhame žiadosti dostať sa k nemu. V prípade, že požiadavka bola nesprávna, konečné API by malo zobraziť chybu, ale nie my. Jediný dôvod, prečo môžeme žiadosť zamietnuť, je ten, že klient nemá prístup.
Pre nginx už existuje na . Lua je skriptovací jazyk, je veľmi ľahký a ľahko sa učí. Preto sme implementovali potrebnú logiku pomocou Lua.
Konfigurácia nginx (analógia trasy aplikácie), kde sa vykonáva všetka práca, je celkom zrozumiteľná. Pozoruhodná je posledná smernica - 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;
}
Zvážte, čo sa stane v tejto konfigurácii:
more_clear_input_headers — vymaže hodnotu hlavičiek špecifikovaných po smernici.
lua_need_request_body - kontroluje, či sa má pôvodné telo požiadavky prečítať pred vykonaním direktív rewrite/access/access_by_lua alebo nie. V predvolenom nastavení nginx nečíta telo požiadavky klienta a ak k nemu potrebujete pristupovať, táto direktíva by mala byť zapnutá.
rewrite_by_lua_file - cesta k skriptu, ktorá popisuje logiku úpravy požiadavky
access_by_lua_file — cesta k skriptu, ktorá popisuje logiku, ktorá kontroluje prístup k zdroju.
proxy_pass — adresa URL, na ktorú bude žiadosť presmerovaná.
body_filter_by_lua_file — cesta k skriptu, ktorá popisuje logiku filtrovania požiadavky pred jej vrátením klientovi.
A konečne, post_action - oficiálne nezdokumentovaná smernica, pomocou ktorej môžete po odoslaní odpovede klientovi vykonať niektoré ďalšie akcie.
Ďalej popíšeme v poradí, ako sme vyriešili naše problémy.
Autorizácia/autentifikácia a žiadosť o úpravu
Povolenie
Vytvorili sme autorizáciu a autentifikáciu pomocou certifikátu. Existuje koreňový certifikát. Každému novému klientovi zákazníka je vygenerovaný jeho osobný certifikát, pomocou ktorého môže pristupovať k API. Tento certifikát je nakonfigurovaný v sekcii servera v nastaveniach 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;modifikácie
Môže vyvstať spravodlivá otázka: čo robiť s certifikovaným klientom, ak ho zrazu chceme odpojiť od systému? Nevystavujte znovu certifikáty pre všetkých ostatných klientov.
Plynule sme teda pristúpili k ďalšej úlohe – úprave pôvodnej požiadavky. Prvotná požiadavka klienta vo všeobecnosti neplatí pre konečný systém. Jednou z úloh je doplniť chýbajúce časti do požiadavky, aby bola platná. Ide o to, že chýbajúce údaje sú u každého klienta iné. Vieme, že za nami príde klient s certifikátom, z ktorého vieme zobrať odtlačok prsta a vytiahnuť z databázy potrebné údaje klienta.
Ak v určitom momente potrebujete klienta odpojiť od našej služby, jeho údaje zmiznú z databázy a nebude môcť nič robiť.
Práca s údajmi o zákazníkoch
Potrebovali sme, aby bolo riešenie vysoko dostupné, najmä ako získavame údaje o zákazníkoch. Problém je v tom, že primárnym zdrojom týchto údajov je služba tretej strany, ktorá nezaručuje neprerušovanú a dostatočne vysokú rýchlosť.
Preto sme potrebovali zabezpečiť vysokú dostupnosť zákazníckych dát. Ako nástroj sme si vybrali ktorý nám poskytuje:
- rýchly prístup k údajom
- schopnosť organizovať zhluk niekoľkých uzlov s údajmi replikovanými na rôznych uzloch.
Použili sme najjednoduchšiu stratégiu na doručovanie údajov do vyrovnávacej pamäte:

Práca s koncovým systémom prebieha v rámci relácií a maximálny počet je obmedzený. Ak klient neukončil reláciu, budeme to musieť urobiť my.
Údaje o otvorenej relácii pochádzajú z koncového systému a spočiatku sa spracúvajú na strane Lua. Rozhodli sme sa použiť Hazelcast na uloženie týchto údajov pomocou úlohy .NET. Potom v určitých intervaloch kontrolujeme právo na život otvorených relácií a zatvárame tie prehnité.
Prístup k Hazelcastu z Lua aj .NET
Neexistujú žiadni Lua klienti na prácu s Hazelcast, ale Hazelcast má REST API, ktoré sme sa rozhodli použiť. Pre .NET existuje , cez ktorý sme plánovali pristupovať k údajom Hazelcast na strane .NET. Ale nebolo to tam.

Pri ukladaní dát cez REST a načítavaní dát cez .NET klienta sa používajú rôzne serializátory a deserializátory. Preto nie je možné dať dáta cez REST, ale získať ich cez .NET klienta a naopak.
V prípade záujmu vám o tomto probléme povieme viac v samostatnom článku. Spojler - na schéme.

Logovanie a monitorovanie
Náš firemný štandard pre protokolovanie cez .NET je Serilog, všetky protokoly končia v Elasticsearch a analyzujeme ich cez Kibana. Niečo podobné by som rád urobil aj v tomto prípade. Jediný pracovať s Elastic na Lua, ktorá bola nájdená, praskla hneď pri prvej požiadavke. A použili sme Fluentd.
- open source riešenie na poskytovanie jedinej vrstvy protokolovania aplikácií. Umožňuje zhromažďovať protokoly z rôznych vrstiev aplikácie a potom ich vysielať do jedného zdroja.
API Gateway funguje v K8S, preto sme sa rozhodli pridať kontajner s fluentd v rovnakom pody, aby sme mohli zapisovať protokoly do existujúceho otvoreného tcp portu fluentd.
Tiež sme skúmali, ako by sa plynulý správal, keby nemal žiadne spojenie s Elasticsearch. Počas dvoch dní boli na bránu nepretržite odosielané požiadavky, protokoly boli odosielané na fluentd, ale fluentd bol zakázaný z IP Elastic. Po obnovení spojenia fluentd dokonale predbehol úplne všetky polená v Elastic.
Záver
Zvolený prístup k implementácii nám umožnil dodať skutočne fungujúci produkt do bojového prostredia len za 2.5 mesiaca.
Ak sa niekedy stane, že budete robiť takéto veci, odporúčame vám, aby ste v prvom rade jasne pochopili, aký problém riešite a aké zdroje už máte. Buďte si vedomí zložitosti integrácie s existujúcimi systémami správy API.
Pochopte sami, čo presne idete vyvíjať - iba obchodnú logiku spracovania požiadaviek, alebo, ako by to mohlo byť v našom prípade, celú proxy. Nezabudnite, že všetko, čo robíte sami, musíte následne dôkladne otestovať.
Zdroj: hab.com
