Některé společnosti, včetně našeho zákazníka, vyvíjejí produkt prostřednictvím partnerské sítě. Například velké internetové obchody jsou integrovány s doručovací službou – objednáte si produkt a brzy obdržíte sledovací číslo balíku. Dalším příkladem je, když si spolu s letenkou koupíte pojištění nebo letenku Aeroexpress.
K tomu slouží jedno API, které musí být partnerům vydáno prostřednictvím API Gateway. Tento problém jsme vyřešili. V tomto článku vám řekneme podrobnosti.
Vzhledem k tomu: ekosystém a API portál s rozhraním, kde jsou uživatelé registrováni, dostávají informace atd. Musíme vytvořit pohodlnou a spolehlivou bránu API. V tomto procesu jsme potřebovali poskytnout
- Registrace,
- API ovládání připojení,
- sledování toho, jak uživatelé používají koncový systém,
- účtování obchodních ukazatelů.

V článku budeme hovořit o našich zkušenostech s vytvářením API Gateway, během kterých jsme řešili následující úkoly:
- Ověření uživatele,
- oprávnění uživatele,
- úprava původní žádosti,
- požádat o proxy,
- postprocessing odezvy.
Existují dva typy správy API:
1. Standard, který funguje následovně. Před připojením uživatel otestuje funkce, poté zaplatí a vloží na svůj web. Nejčastěji se používají v malých a středních podnicích.
2. Velká B2B API Management, když společnost nejprve učiní obchodní rozhodnutí o připojení, stane se partnerem společnosti se smluvním závazkem a poté se připojí k API. A po vyřízení všech formalit získá společnost testovací přístup, projde testováním a jde do výroby. To ale není možné bez rozhodnutí vedení o připojení.

Naše řešení
V této části budeme hovořit o vytvoření brány API.
Koncovými uživateli vytvořené API brány jsou partneři našeho zákazníka. Na každou z nich již máme potřebné smlouvy. Budeme potřebovat pouze rozšířit funkcionalitu označením uděleného přístupu k bráně. V souladu s tím je zapotřebí řízený proces připojení a řízení.
Samozřejmě bylo možné vzít nějaké hotové řešení pro řešení problému API Management a vytvoření API Gateway zejména. Například by to mohlo být. To nám nevyhovovalo, protože v našem případě jsme již měli API portál a kolem něj vybudovaný obrovský ekosystém. Všichni uživatelé již byli zaregistrováni, již pochopili, kde a jak mohou získat potřebné informace. Potřebná rozhraní již v API portálu existovala, potřebovali jsme pouze API Gateway. Ve skutečnosti se zabýváme jeho vývojem.
To, co nazýváme API Gateway, je druh proxy. Zde jsme opět měli na výběr – můžete si napsat vlastní proxy, nebo si můžete vybrat něco hotového. V tomto případě jsme šli druhou cestou a vybrali jsme balíček nginx + Lua. Proč? Potřebovali jsme spolehlivý, testovaný software, který podporuje škálování. Nechtěli jsme po implementaci kontrolovat jak správnost obchodní logiky, tak správnost proxy.
Každý webový server má kanál pro zpracování požadavků. V případě nginx to vypadá takto:

(schéma z )
Naším cílem bylo zapadnout do tohoto potrubí v bodě, kde můžeme upravit původní požadavek.
Chceme vytvořit transparentní proxy, aby požadavek zůstal funkčně stejný, jak přišel. Kontrolujeme pouze přístup k finálnímu API, pomáháme požadavku se k němu dostat. V případě, že byl požadavek nesprávný, mělo by chybu zobrazit konečné API, ale ne my. Jediný důvod, proč můžeme žádost odmítnout, je ten, že klient nemá přístup.
Již existuje pro nginx na . Lua je skriptovací jazyk, je velmi lehký a snadno se učí. Implementovali jsme tedy potřebnou logiku pomocí Lua.
Konfigurace nginx (obdoba cesty aplikace), kde se provádí veškerá práce, je celkem pochopitelná. Zde stojí za zmínku poslední direktiva - 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;
}
Zvažte, co se stane v této konfiguraci:
more_clear_input_headers — vymaže hodnotu hlaviček zadaných za direktivou.
lua_need_request_body - kontroluje, zda má být před provedením direktiv rewrite/access/access_by_lua přečteno původní tělo požadavku nebo ne. Ve výchozím nastavení nginx nečte tělo požadavku klienta, a pokud k němu potřebujete přistupovat, měla by být tato direktiva zapnuta.
rewrite_by_lua_file - cesta ke skriptu, která popisuje logiku pro úpravu požadavku
access_by_lua_file — cesta ke skriptu, která popisuje logiku, která kontroluje přístup ke zdroji.
proxy_pass — URL, na kterou bude požadavek přesměrován.
body_filter_by_lua_file — cesta ke skriptu, která popisuje logiku pro filtrování požadavku před jeho vrácením klientovi.
A konečně, post_action - oficiálně nezdokumentovaná směrnice, pomocí které můžete po obdržení odpovědi klientovi provádět některé další akce.
Dále popíšeme v pořadí, jak jsme naše problémy vyřešili.
Autorizace/autentizace a požadavek na úpravu
Povolení
Vytvořili jsme autorizaci a autentizaci pomocí přístupu k certifikátu. Existuje kořenový certifikát. Každému novému klientovi zákazníka je vygenerován jeho osobní certifikát, pomocí kterého může přistupovat k API. Tento certifikát se konfiguruje v sekci server v nastavení 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;Změna
Může vyvstat spravedlivá otázka: co dělat s certifikovaným klientem, když ho náhle chceme odpojit od systému? Nevystavujte znovu certifikáty pro všechny ostatní klienty.
Plynule jsme tedy přistoupili k dalšímu úkolu – úpravě původního požadavku. Prvotní požadavek klienta, obecně řečeno, není platný pro konečný systém. Jedním z úkolů je doplnit do požadavku chybějící části, aby byl platný. Jde o to, že chybějící údaje jsou u každého klienta jiné. Víme, že za námi přijde klient s certifikátem, ze kterého sejmeme otisk prstu a vytáhneme potřebná klientská data z databáze.
Pokud v určité chvíli potřebujete klienta odpojit od naší služby, jeho data zmizí z databáze a nebude moci nic dělat.
Práce s daty zákazníků
Potřebovali jsme, aby bylo řešení vysoce dostupné, zejména jak získáváme zákaznická data. Potíž je v tom, že primárním zdrojem těchto dat je služba třetí strany, která nezaručuje nepřetržitou a dostatečně vysokou rychlost.
Proto jsme potřebovali zajistit vysokou dostupnost zákaznických dat. Jako nástroj jsme zvolili která nám poskytuje:
- rychlý přístup k datům
- schopnost organizovat shluk několika uzlů s daty replikovanými na různých uzlech.
Použili jsme nejjednodušší strategii pro doručování dat do mezipaměti:

Práce s koncovým systémem probíhá v rámci relací a maximální počet je omezen. Pokud klient neuzavřel relaci, budeme to muset udělat my.
Data otevřené relace pocházejí z koncového systému a jsou zpočátku zpracována na straně Lua. Rozhodli jsme se použít Hazelcast k uložení těchto dat pomocí úlohy .NET. Potom v určitých intervalech kontrolujeme právo na život otevřených relací a zavřeme ty prohnilé.
Přístup k Hazelcastu z Lua i .NET
S Hazelcastem nepracují žádní Lua klienti, ale Hazelcast má REST API, které jsme se rozhodli použít. Pro .NET existuje , přes který jsme plánovali přistupovat k datům Hazelcast na straně .NET. Ale nebylo to tam.

Při ukládání dat přes REST a načítání dat přes .NET klienta se používají různé serializátory a deserializátory. Proto není možné dát data přes REST, ale získat je přes .NET klienta a naopak.
V případě zájmu vám o tomto problému řekneme více v samostatném článku. Spoiler - na schématu.

Logování a monitorování
Naším firemním standardem pro protokolování prostřednictvím .NET je Serilog, všechny protokoly končí v Elasticsearch a analyzujeme je prostřednictvím Kibana. V tomto případě bych chtěl udělat něco podobného. Jediný pracovat s Elastic na Lua, která byla nalezena, praskla hned při prvním požadavku. A použili jsme Fluentd.
- open source řešení pro poskytování jediné vrstvy protokolování aplikací. Umožňuje shromažďovat protokoly z různých vrstev aplikace a poté je vysílat do jednoho zdroje.
API Gateway funguje v K8S, takže jsme se rozhodli přidat kontejner s fluentd ve stejném pody, abychom mohli zapisovat protokoly do existujícího otevřeného tcp portu fluentd.
Také jsme zkoumali, jak by se plynulý choval, kdyby neměl žádné spojení s Elasticsearch. Po dobu dvou dnů byly na bránu nepřetržitě odesílány požadavky, protokoly byly odesílány na fluentd, ale Elastic IP byl zakázán. Po obnovení spojení fluentd perfektně předběhl naprosto všechny kulatiny v Elastic.
Závěr
Zvolený přístup k implementaci nám umožnil dodat skutečně fungující produkt do bojového prostředí za pouhé 2.5 měsíce.
Pokud někdy takové věci uděláte, doporučujeme vám, abyste nejprve jasně pochopili, jaký problém řešíte a jaké prostředky již máte. Buďte si vědomi složitosti integrace se stávajícími systémy správy API.
Uvědomte si sami, co přesně budete vyvíjet - pouze obchodní logiku zpracování požadavků, nebo, jak by to mohlo být v našem případě, celé proxy. Nezapomeňte, že vše, co děláte sami, musíte následně důkladně otestovat.
Zdroj: www.habr.com
