MĂ”ned ettevĂ”tted, sealhulgas meie klient, arendavad toodet partnerite vĂ”rgustiku kaudu. NĂ€iteks on suured veebipoed integreeritud kohaletoimetamisteenustega â te tellite toote ja saate varsti jĂ€lgimisnumber. Teine nĂ€ide â koos lennupiletiga ostate ka kindlustuse vĂ”i pileti lennujaamabussile.
Selleks kasutatakse ĂŒhte API-t, mille tuleb partneritele anda lĂ€bi API Gateway. Selle ĂŒlesande lahendamisega me tegelesime. Selles artiklis jagame ĂŒksikasju.
Kontekst: ökosĂŒsteem ja API-portaal, kus kasutajad on registreeritud, saavad teavet jne. Me peame looma mugava ja usaldusvÀÀrse API Gateway. Protsessi kĂ€igus pidime tagama
- registreerimise,
- API-ĂŒhenduse kontrollimise,
- kasutajate tegevuse jĂ€lgimise lĂ”pp-sĂŒsteemis,
- Àri nÀitajate jÀlgimise.

Artiklis rÀÀgime oma kogemusest API Gateway loomisel, mille kĂ€igus lahendasime jĂ€rgmised ĂŒlesanded:
- kasutaja autentimine,
- kasutaja autoriseerimine,
- algse pÀringu muutmine,
- pÀringu edastamine,
- vastuse töötlemine.
API haldamise on kahte tĂŒĂŒpi:
1. Standardlahendus, mis töötab jĂ€rgmiselt. Enne ĂŒhenduse loomist testib kasutaja vĂ”imalusi, seejĂ€rel maksab ja integreerib oma saidile. Enim kasutavad seda vĂ€ike- ja keskmiselt ettevĂ”tted.
2. Suur B2B API haldamine, kus ettevĂ”te teeb esmalt Ă€riotsuse ĂŒhenduse loomise kohta, saab ettevĂ”tte partneriks lepinguliste kohustustega, pĂ€rast mida ĂŒhildub API-ga. Ja pĂ€rast kĂ”igi vormistamiste lĂ”petamist saab ettevĂ”te testimisjuurdepÀÀsu, lĂ€bib testimise ja lĂ€heb tootmisse. Kuid see ei ole vĂ”imalik ilma juhtimisotsuseta ĂŒhenduse loomiseks.

Meie lahendus
Selles osas rÀÀgime API Gateway loomise protsessist.
API looja lĂ”ppkasutajad on meie kliendi partnerid. IgaĂŒhe jaoks on meil juba vajalikud lepingud olemas. Peame lihtsalt laiendama funktsionaalsust, mĂ€rkides antud juurde pÀÀsu vĂ€ravale. Seega on vajalik kontrollitud ĂŒhendamise ja haldamise protsess.
Ilmselgelt oleks olnud vĂ”imalik vĂ”tta mĂ”ni valmis lahendus API haldamise ja eriti API Gateway loomiseks. NĂ€iteks vĂ”iks selliseks olla. Meie puhul see ei sobinud, sest meil oli juba API-portaal ja sellele rajatud suur ökosĂŒsteem. KĂ”ik kasutajad olid juba registreeritud ning nad mĂ”istsid juba, kus ja kuidas nad saavad vajalikku teavet. API-portaalis olid juba olemas vajalikud liidesed, me vajasime vaid API Gatewayâd. Just selle arendamisega me kokkuvĂ”ttes tegelema hakkasime.
Seda, mida me nimetame API Gatewayâks, vĂ”ib pidada omamoodi pöördeliseks. Ka siin seisis meil taas ees valik â kirjutada oma pöördel vĂ”i valida juba midagi valmisolevat. Antud juhul lĂ€ksime teist teed ja valisime kombinatsiooni nginx+Lua. Miks? Me vajasime usaldusvÀÀrset, testitud tarkvara, mis toetaks skaleerimist. Me ei tahtnud pĂ€rast elluviimist kontrollida mitte ainult Ă€ri loogika Ă”igsust, vaid ka pöördeliidestuse töö korrektset toimimist.
Igal veebiserveril on pÀringu töötlemise konveier. Nginxi puhul nÀeb see vÀlja jÀrgmiselt:

(skeem )
Meie eesmÀrk oli siseneda sellesse konveierisse hetkel, kus me saaksime algset pÀringut muuta.
Soovime luua lĂ€bipaistva proxy, et funktsionaalne pĂ€ring jÀÀks selliseks, nagu ta on. Kontrollime vaid juurdepÀÀsu lĂ”pp-API-le ja aitame pĂ€ringul sinna jĂ”uda. Kui pĂ€ring oli vale, peab vea nĂ€itama lĂ”pp-API, mitte meie. Ainus pĂ”hjus, miks me pĂ€ringu tagasi vĂ”ime lĂŒkata, on kliendi juurdepÀÀsu puudumine.
Nginx jaoks on juba olemas jÀrgnevaga . Lua on skriptikeel, mis on vÀga kerge ja hÔlpsasti omandatav. Seega rakendasime vajalikku loogikat Lua abil.
Nginxi konfiguratsioon (analoogia rakenduse marsruudiga), kus kogu töö toimub, on tĂ€iesti arusaadav. Siin on mĂ€rkimisvÀÀ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 toimub selles konfiguratsioonis:
more_clear_input_headers â puhastab direktiivi jĂ€rel nimetatud pĂ€iste vÀÀrtuse.
lua_need_request_body â reguleerib, kas tuleb lugeda pĂ€ritud pĂ€ringu keha enne rewrite/access/access_by_lua direktiivide tĂ€itmist vĂ”i mitte. Vaikimisi ei loe nginx kliendi pĂ€ringu keha, ja kui on vajalik sellele juurde pÀÀseda, peab see direktiiv olema seatud vÀÀrtusele on.
rewrite_by_lua_file â tee skripti, mis mÀÀratleb pĂ€ringu muutmise loogika
access_by_lua_file â tee skripti, mis mÀÀratleb loogika, mis kontrollib juurdepÀÀsu olemasolu ressursile.
proxy_pass â url, kuhu pĂ€ring edastatakse.
body_filter_by_lua_file â tee skripti, mis mÀÀratleb loogika pĂ€ringu filtreerimiseks enne selle tagastamist kliendile.
Ja lĂ”puks, post_action â ametlikult dokumenteerimata direktiiv, mis vĂ”imaldab teha muid toiminguid pĂ€rast vastuse andmist kliendile.
Edasi rÀÀgime samm-sammult, kuidas me oma ĂŒlesandeid lahendasime.
Autoriseerimine/autentimine ja pÀringu modifitseerimine
Autoriseerimine
Oleme autoriseerimise ja autentimise loonud sertifikaatide pÔhjal. On juursertifikaat. Iga uue kliendi jaoks genereeritakse isiklik sertifikaat, mille kaudu saab ta ligipÀÀsu API-le. Selle sertifikaadi seadistamine toimub nginx serveri seadete jaotises.
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
VĂ”ib kĂŒsida, mida teha sertifitseeritud kliendiga, kui me Ă€kki otsustame ta sĂŒsteemist vĂ€lja lĂŒlitada? Kas tĂ”esti, et kĂ”igi teiste klientide sertifikaate uuesti vĂ€lja anda.
Nii oleme sujuvalt jĂ”udnud jĂ€rgmise ĂŒlesandeni â sisendpĂ€ringu muutmine. Klientide algne pĂ€ring ei ole pĂ”hjapanevalt kehtiv lĂ”pp-sĂŒsteemi jaoks. Ăks ĂŒlesanne on lisada pĂ€ringusse puuduvaid osi, et muuta see kehtivaks. Asi on selles, et puuduvaid andmeid on igale kliendile erinevalt. Me teame, et klient tuleb meile sertifikaadiga, mille pĂ”hjal saame vĂ”tta sĂ”rmejĂ€lje ja tĂ”mmata andmebaasist vajalikud kliendi andmed.
Kui mingil hetkel on vajalik klient meie teenusest eemaldada, siis tema andmed kaovad andmebaasist ja ta ei saa midagi teha.
Kliendiandmetega töötamine
Me pidime tagama lahenduse kÔrge kÀtte saadavuse, eriti selle osas, kuidas me kliendiandmeid saame. Probleemiks on see, et nende andmete algallikaks on kolmanda osapoole teenus, mis ei garanteeri katkematut ja piisavalt kÔrget töökiirus.
SeetÔttu pidime tagama klientide andmete kÔrge kÀtte saadavuse. Tööriistana valisime , mis pakub meile:
- kiiret juurdepÀÀsu andmetele,
- vÔimalust organiseerida klaster mitmest nodist, millel on replikatsioon erinevates nodides.
Me valisime kÔige lihtsama strateegia andmete edastamiseks vahemÀllu:

LĂ”pp-sĂŒsteemiga töötamine toimub sessioonide raames ja on maksimaalne piir. Kui klient ei ole sessiooni lĂ”petanud, peame seda tegema meie.
Avasessiooni andmed saavad lĂ”pp-sĂŒsteemist ja töödeldakse alguses Lua poolel. Otsustasime kasutada Hazelcast'i nende andmete salvestamiseks .NET keeles kirjutatud tööjuhtmoodulis. SeejĂ€rel kontrollime perioodiliselt avatud sessioonide elujĂ”udlust ja sulgeme aegunud sessioonid.
PÀÀs Hazelcasti juurde on nii Lua kui ka .NET kaudu.
Hazelcasti jaoks ei ole Lua kliente, kuid Hazelcast'il on REST API, mida me otsustasime kasutada. .NET'i puhul on olemas , mille kaudu plaanisime pÀÀseda andmetele Hazelcasti poolt .NET poolel. Kuid mitte nii kiiresti.

REST kaudu andmete salvestamisel ja .NET kliendi kaudu nende tÀiustamisel kasutatakse erinevaid serialiseerijaid/deserialiseerijaid. SeetÔttu ei ole vÔimalik andmeid RESTi kaudu sisestada ja seejÀrel .NET kliendi kaudu vÀlja vÔtta ja vastupidi.
Kui on huvilisi, saame sellest probleemist ĂŒksikasjalikumalt rÀÀkida eraldi artiklis. Spoileri jaoks â skeemil.

Logimine ja jÀlgimine
Meie ettevĂ”tte standard logimise jaoks .NET'is on Serilog, kĂ”ik logid jĂ”uavad viimaks Elasticsearch'i ja nende analĂŒĂŒsi teeme Kibanaga. Midagi sarnast soovisime ka sel juhul teha. Ainult et Elasticiga töötamiseks mĂ”eldud Lua, mis leiti, purunes juba esimeses require'is. Ja me kasutasime Fluentd-d.
â avatud lĂ€htekoodiga lahendus, mis tagab rakenduse logimise ĂŒhtse kihi. See vĂ”imaldab koguda logisid erinevatest rakenduse kihtidest ja seejĂ€rel edastada need ĂŒhte allikasse.
API Gateway töötab K8S-is, seetÔttu otsustasime lisada konteineri Fluentd sama pod'i, et kirjutada logisid olemasolevasse avatud tcp porti Fluentd.
Uurime ka, kuidas kĂ€itub Fluentd, kui tal pole ĂŒhendust Elasticsearchiga. Kaks pĂ€eva ajal suunati pidevalt pĂ€ringud vĂ€ravasse, Fluentd'le saadeti logisid, kuid Fluentd IP Elasticust blokeeriti. PĂ€rast ĂŒhenduse taastamist edastas Fluentd kĂ”ik logid Elasticsearchi tĂ€ielikult.
KokkuvÔte
Valitud rakenduse lÀhenemine vÔimaldas meil toimetada reaalselt töötava toote tootmiskeskkonda vaid 2,5 kuuga.
Kui kunagi satute tegelema sarnaste asjadega, soovitame esmalt selgelt mĂ”ista, millist ĂŒlesannet te lahendate ja milliseid ressursse teil juba on. Olge ettevaatlikud API haldamise olemasolevate sĂŒsteemidega integreerimise keerukuste suhtes.
MĂ”istke ise, mida te kavatsete arendada â kas ainult Ă€riloogikat, mis kĂ€sitleb pĂ€ringute töötlemist, vĂ”i, nagu see oli meie puhul, terve proksi. Ărge unustage, et kĂ”ik, mida te ise teete, peab hiljem olema pĂ”hjalikult testitud.
Allikas: habr.com
