MĂ”ned ettevĂ”tted, sealhulgas meie klient, arendavad toodet partnervĂ”rgustiku kaudu. NĂ€iteks on suured internetipoodid integreeritud tarnehaldussĂŒsteemiga â tellite toote ja saad peagi jĂ€lgimisnumbriga paki. Teine nĂ€ide on see, et koos lennupiletiga ostetakse kindlustus vĂ”i pilet aeroekspressile.
Selleks kasutatakse ĂŒhte API-d, mille peame partneritele API Gateway kaudu esitama. Selle ĂŒlesande me lahendasime. Selles artiklis rÀÀgime ĂŒksikasjadest.
Antud: ökosĂŒsteem ja API-portaal koos liidese ning registreeritud kasutajatega, kes saavad teavet jne. Me peame looma mugava ja usaldusvÀÀrse API Gateway. Protsessi kĂ€igus pidime tagama
- registreerimise,
- ĂŒhenduse kontrolli API-ga,
- kasutajate tegevuse jĂ€lgimise lĂ”pp-sĂŒsteemis,
- ÀrinÀitajate arvestuse.

Artiklis rÀÀgime oma kogemustest API Gateway loomisel, mille kĂ€igus lahendasime jĂ€rgmised ĂŒlesanded:
- kasutaja autentimine,
- kasutaja volitamine,
- algse pÀringu modifitseerimine,
- pÀringu edastamine,
- vastuse jÀrel töötlemine.
On kaks tĂŒĂŒpi API haldust:
1. Standardne, mis töötab jĂ€rgmiselt. Enne ĂŒhendamist testib kasutaja vĂ”imalusi, seejĂ€rel maksab ja integreerib oma veebisaidile. Seda kasutavad kĂ”ige sagedamini vĂ€ike ja keskmine Ă€ri.
2. Suur B2B API haldus, kus ettevĂ”te teeb esmalt Ă€rilise otsuse ĂŒhendamiseks, becomes partner of the company with a contractual obligation, pĂ€rast mida liitub API-ga. Ja alles pĂ€rast kĂ”igi formaalsuste lahendamist saab ettevĂ”te testimisĂ”iguse, lĂ€bib testimise ja jĂ”uab tootmisse. Kuid see pole vĂ”imalik ilma juhtimisotsuseta ĂŒhendamiseks.

Meie lahendus
Selles osas rÀÀgime API Gateway loomise protsessist.
API-kĂ€ideldava lĂ”ppkasutaja sihtgrupp on meie kliendi partnerid. IgaĂŒhe jaoks on meil juba vajalikud lepingud olemas. Peame lihtsalt laiendama funktsionaalsust, mĂ€rkides juurdepÀÀsu vĂ€ravas. Seega on vaja kontrollitud protsessi ĂŒhendamiseks ja haldamiseks.
Muidugi oleks olnud vĂ”imalik vĂ”tta mĂ”ni valmis lahendus API haldamise ja API Gateway loomise ĂŒlesande tĂ€itmiseks. NĂ€iteks vĂ”iks see olla. Meile see ei sobinud, sest meie olukorras oli meil juba olemas API-portaal ja hiiglaslik ökosĂŒsteem selle ĂŒmber. KĂ”ik kasutajad olid juba registreeritud, nad mĂ”istsid, kust ja kuidas nad saavad vajalikku teavet. API-portaalis olid juba olemas vajalikud liidesed, me vajasime vaid API Gatewayd. Selle arendusega me tegelikult tegelesime.
Seda, mida me nimetame API Gatewayks â on omamoodi proks. Siin oli meil taas valik â kas kirjutada oma proks vĂ”i valida juba midagi valmiskujul. Sellel juhul lĂ€ksime teist teed ja valisime kombinatsiooni nginx+Lua. Miks? Me vajasime usaldusvÀÀrset, testitud tarkvara, mis toetaks skaleerimist. Me ei soovinud pĂ€rast rakendamist kontrollida ei Ă€ri loogika Ă”igsust ega proksi töö Ă”igsust.
Igal veebiserveril on pÀringu töötlemise konveier. Nginxi puhul nÀeb see vÀlja jÀrgmiselt:

(skeem on )
Meie eesmÀrk oli integreeruda sellesse konveierisse sel hetkel, kus me saame algset pÀringut modifitseerida.
Me tahame luua lĂ€bipaistva proksi, et funktsionaalselt jÀÀks pĂ€ring selliseks, nagu ta tuli. Me lihtsalt kontrollime juurdepÀÀsu lĂ”plikule API-le, aitame pĂ€ringul sinna jĂ”uda. Juhul, kui pĂ€ring oli vale, peaks vea nĂ€itama lĂ”plik API, mitte meie. Ainus pĂ”hjus, miks me saame pĂ€ringu tagasi lĂŒkata, on pĂ”hjendamatud kliendi juurdepÀÀsuĂ”igused.
Nginxi jaoks on juba olemas . Tundub, et . Lua on skriptimiskeel, see on vÀga kerge ja lihtne Ôppida. Seega, vajalik loogika teostati Lua abiga.
Nginxi konfiguratsioon (analoogia rakenduse marsruudiga), kus kogu töö toimub, on ĂŒsna arusaadav. Siin on tĂ€helepanuvÀÀrne viimane direktiiv â 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;
}
Vaatame, mis juhtus selle konfiguratsiooniga:
more_clear_input_headers â puhastab direktiivide jĂ€rel mĂ€rgitud pĂ€iste vÀÀrtused.
lua_need_request_body â reguleerib, kas tuleks lugeda algne pĂ€ringu keha enne direktiivide rewrite/access/access_by_lua tĂ€itmist vĂ”i mitte. Vaikimisi ei loe nginx kliendi pĂ€ringu keha ning kui teil on sellele juurdepÀÀs vajalik, peab see direktiiv olema vÀÀrtusega on.
rewrite_by_lua_file â tee skripti, kus on kirjeldatud pĂ€ringu muutmise loogika
access_by_lua_file â tee skripti, kus on kirjeldatud loogika, mis kontrollib juurdepÀÀsu olemasolu ressursile.
proxy_pass â url, kuhu pĂ€ring edastatakse.
body_filter_by_lua_file â tee skripti, kus on kirjeldatud loogika pĂ€ringu filtreerimiseks enne, kui see klientidele tagastatakse.
Ja lĂ”puks, post_action â ametlikult dokumenteerimata direktiiv, millega saab teha muid toiminguid pĂ€rast seda, kui vastus on kliendile antud.
JĂ€rgnevalt rÀÀgime jĂ€rjestikku, kuidas me oma ĂŒlesandeid lahendasime.
Autoriseerimine/ autentimine ja pÀringu muutmine
Autoriseerimine
Autoriseerimist ja autentimist teostasime sertifikaatide kaudu. On olemas juursertifikaat. Iga uue kliendi jaoks genereeritakse oma isiklik sertifikaat, millega ta saab API-le juurde pÀÀseda. See sertifikaat seadistatakse nginx'i serveri seadete lÔigus.
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;Muutmine
TĂ”statub Ă”igustatud kĂŒsimus: mida teha sertifitseeritud kliendiga, kui me Ă€kki soovime ta sĂŒsteemist vĂ€lja lĂŒlitada? Ei ole ju mĂ”istlik sertifikaate kĂ”igi teiste klientide jaoks uuesti vĂ€lja anda.
Nii jĂ”udsime sujuvalt jĂ€rgmise ĂŒlesande juurde â algse pĂ€ringu muutmine. Kliendi algne pĂ€ring ei ole ĂŒldiselt lĂ”pp-sĂŒsteemi jaoks kehtiv. Ăks ĂŒlesandeid on lisada pĂ€ringusse puuduolevaid osi, et muuta see kehtivaks. Probleem on selles, et puuduolevad andmed on igale kliendile erinevad. Me teame, et klient tuleb meile sertifikaadiga, millest saame vĂ”tta jĂ€lje ja vĂ€lja tĂ”mmata kliendi vajalikud andmed andmebaasist.
Kui mingil hetkel on vajalik klient meie teenusest vĂ€lja lĂŒlitada, kaovad tema andmed andmebaasist ja ta ei saa enam midagi teha.
Töötamine kliendi andmetega
Meil oli vaja tagada lahenduse kÔrge kÀttesaadavus, eriti nende andmete saamise osas. Probleem seisneb selles, et andmete esmasteks allikateks on kolmandate osapoolte teenused, mis ei garanteeri katkestusteta ja piisavalt kÔrget töökiirust.
SeetÔttu pidi meil tagama kliendiandmete kÔrge kÀttesaadavus. Tööriistaks valisime , mis pakub meile:
- kiire juurdepÀÀs andmetele,
- vÔimalus korraldada kluster mitmest sÔlmest replitseeritud andmetega eri sÔlmedes.
Me jÀrgnesime kÔige lihtsamale andmeedastamise strateegiale vahemÀlusse:

Töötamine lĂ”ppkasutaja sĂŒsteemiga toimub sessioonide raames ja on piirang maksimaalsete sessioonide arvu osas. Kui klient ei ole sessiooni suletud, peame me selle lĂ”petama.
Teave avatud sessiooni kohta tuleb lĂ”ppkasutaja sĂŒsteemist ja see töödeldakse esmalt Lua poolel. Otsustasime kasutada Hazelcasti nende andmete salvestamiseks töötaskuga, mis on kirjutatud .NET-is. SeejĂ€rel kontrollime teatud aja jooksul avatud sessioonide elujĂ”ulisust ja sulgeme aegunud sessioonid.
JuurdepÀÀs Hazelcastile nii Lua-st kui ka .NET-ist
Lua-le, mis töötaks Hazelcastiga, kliente ei ole, kuid Hazelcastil on REST API, mida me otsustasime kasutada. .NET-i jaoks on olemas , mille kaudu kavatsesime saada juurdepÀÀsu Hazelcasti andmetele .NET poolel. Kuid sellega oli probleeme.

REST-i kaudu andmete salvestamisel ja .NET kliendi kaudu vÀljavÔttel kasutatakse erinevaid serialiseerijat/dserialiseringut. SeetÔttu ei ole vÔimalik andmeid salvestada REST-i kaudu ja neid vÀlja vÔtta .NET kliendi kaudu ning vastupidi.
Kui kedagi huvitab, saame sellest probleemist rÀÀkida pĂ”hjalikumalt eraldi artiklis. Spoiler â joonisel.

Logimine ja monitooring
Meie ettevĂ”tte standard logimiseks .NET-is on Serilog, kĂ”ik logid jĂ”uavad lĂ”puks Elasticsearchi, me analĂŒĂŒsime neid Kibana kaudu. Soovisime midagi sarnast teha ka sel juhul. Ainus Lua-le tööks Elasticus, mis leiti, katkes esimesel require-l. Ja me kasutasime Fluentd-d.
â avatud lĂ€htekoodiga lahendus, et tagada rakenduse logimise ĂŒhtne kiht. See vĂ”imaldab koguda logisid erinevatest rakenduse kihtidest ja seejĂ€rel edastada need ĂŒhte allikasse.
API Gateway töötab K8S-is, seega otsustasime lisada konteineri fluentd samasse podi, et kirjutada logisid olemasolevasse avatud tcp porti fluentd.
Uurisime ka, kuidas kĂ€itub fluentd, kui tal pole ĂŒhendust Elasticsearchiga. Kaks pĂ€eva jĂ€rjest edastati pidevalt pĂ€ringuid vĂ€ravasse, fluentd-sse saadeti logisid, kuid fluentd-l oli Elasticu IP blokeeritud. PĂ€rast ĂŒhenduse taastamist edastas fluentd kĂ”ik logid sujuvalt Elasticisse.
KokkuvÔte
Valitud lÀhenemisviis vÔimaldas meil tuua tÔeliselt töötava toote tootmisse vaid 2,5 kuu jooksul.
Kui kunagi peaksite tegelema selliste asjadega, soovitame kĂ”igepealt selgelt mĂ”ista, millist ĂŒlesannet te lahendada pĂŒĂŒdlete ja millised ressursid teil juba on. Olge tĂ€helepanelik API haldussĂŒsteemide integreerimise raskuste suhtes.
MĂ”istke, mida te tegelikult arendama asute â ainult Ă€riloogikat pĂ€ringute töötlemiseks vĂ”i, nagu meie puhul, kogu proksi. Ăra unusta, et kĂ”ik, mida te ise teete, peab hiljem olema pĂ”hjalikult testitud.
Allikas: habr.com
