Arhitectură orientată spre servicii cu AWS Lambda: un tutorial pas cu pas
Publicat: 2022-03-11Când construiți aplicații web, există multe alegeri care trebuie făcute, care fie vă pot ajuta, fie vă pot împiedica aplicația în viitor, odată ce vă angajați să le faceți. Opțiuni precum limba, cadrul, găzduirea și baza de date sunt cruciale.
O astfel de alegere este dacă să creați o aplicație bazată pe servicii folosind arhitectura orientată pe servicii (SOA) sau o aplicație tradițională, monolitică. Aceasta este o decizie arhitecturală comună care afectează deopotrivă startup-urile, extinderile și companiile.
Arhitectura orientată pe servicii este folosită de un număr mare de unicorni bine-cunoscuti și companii de top-tech, cum ar fi Google, Facebook, Twitter, Instagram și Uber. Aparent, acest model de arhitectură funcționează pentru companiile mari, dar poate funcționa și pentru tine?
În acest articol vom introduce subiectul arhitecturii orientate pe servicii și modul în care AWS Lambda în combinație cu Python poate fi folosit pentru a construi cu ușurință servicii scalabile și eficiente din punct de vedere al costurilor. Pentru a demonstra aceste idei, vom construi un serviciu simplu de încărcare și redimensionare a imaginilor folosind Python, AWS Lambda, Amazon S3 și alte câteva instrumente și servicii relevante.
Ce este arhitectura orientată pe servicii?
Arhitectura orientată pe servicii (SOA) nu este nouă, având rădăcini de acum câteva decenii. În ultimii ani, popularitatea sa ca model a crescut datorită faptului că oferă multe beneficii pentru aplicațiile orientate către web.
SOA este, în esență, abstractizarea unei aplicații mari în multe aplicații comunicante mai mici. Aceasta urmează câteva bune practici ale ingineriei software, cum ar fi decuplarea, separarea preocupărilor și arhitectura cu o singură responsabilitate.
Implementările SOA variază în ceea ce privește granularitatea: de la foarte puține servicii care acoperă zone mari de funcționalitate până la multe zeci sau sute de aplicații mici în ceea ce se numește arhitectură „microservicii”. Indiferent de nivelul de granularitate, ceea ce este în general de acord printre practicanții SOA este că nu este în niciun caz un prânz gratuit. La fel ca multe bune practici în inginerie software, este o investiție care va necesita planificare, dezvoltare și testare suplimentare.
Ce este AWS Lambda?
AWS Lambda este un serviciu oferit de platforma Amazon Web Services. AWS Lambda vă permite să încărcați cod care va fi rulat pe un container la cerere gestionat de Amazon. AWS Lambda va gestiona furnizarea și gestionarea serverelor pentru a rula codul, astfel încât tot ceea ce este nevoie de la utilizator este un set de cod de rulat și câteva opțiuni de configurare pentru a defini contextul în care rulează serverul. Aceste aplicații gestionate sunt denumite funcții Lambda.
AWS Lambda are două moduri principale de operare:
Asincron/controlat de evenimente:
Funcțiile Lambda pot fi rulate ca răspuns la un eveniment în modul asincron. Orice sursă de evenimente, cum ar fi S3, SNS etc., nu se va bloca, iar funcțiile Lambda pot profita de acest lucru în multe moduri, cum ar fi stabilirea unei conducte de procesare pentru anumite lanțuri de evenimente. Există multe surse de informații și, în funcție de sursă, evenimentele vor fi trimise la o funcție Lambda din sursa evenimentului sau vor fi interogate pentru evenimente de către AWS Lambda.
Sincron/Solicitare->Răspuns:
Pentru aplicațiile care necesită ca răspunsul să fie returnat sincron, Lambda poate fi rulat în modul sincron. De obicei, acesta este utilizat împreună cu un serviciu numit API Gateway pentru a returna răspunsuri HTTP de la AWS Lambda unui utilizator final, cu toate acestea, funcțiile Lambda pot fi apelate sincron printr-un apel direct către AWS Lambda.
Funcțiile AWS Lambda sunt încărcate ca fișier zip care conține codul de gestionare în plus față de orice dependențe necesare pentru funcționarea handlerului. Odată încărcat, AWS Lambda va executa acest cod atunci când este necesar și va scala numărul de servere de la zero la mii atunci când este necesar, fără nicio intervenție suplimentară necesară de către consumator.
Lambda funcționează ca o evoluție a SOA
SOA de bază este o modalitate de a vă structura baza de cod în aplicații mici pentru a beneficia o aplicație în modurile descrise mai devreme în acest articol. De aici, intră în atenție metoda de comunicare între aceste aplicații. SOA bazat pe evenimente (aka SOA 2.0) permite nu numai comunicarea directă tradițională de la serviciu la serviciu a SOA 1.0, ci și ca evenimentele să fie propagate în arhitectură pentru a comunica schimbarea.
Arhitectura bazată pe evenimente este un model care promovează în mod natural cuplarea slabă și compozibilitatea. Prin crearea și reacția la evenimente, serviciile pot fi adăugate ad-hoc pentru a adăuga funcționalități noi unui eveniment existent și mai multe evenimente pot fi compuse pentru a oferi funcționalități mai bogate.
AWS Lambda poate fi folosit ca platformă pentru a construi cu ușurință aplicații SOA 2.0. Există multe modalități de a declanșa o funcție Lambda; de la abordarea tradițională a cozii de mesaje cu Amazon SNS, la evenimente create de un fișier care este încărcat pe Amazon S3 sau un e-mail trimis cu Amazon SES.
Implementarea unui serviciu simplu de încărcare a imaginilor
Vom construi o aplicație simplă pentru a încărca și a prelua imagini utilizând stiva AWS. Acest exemplu de proiect va conține două funcții lambda: una care rulează în modul cerere->răspuns care va fi folosită pentru a servi interfața noastră web simplă și alta care va detecta imaginile încărcate și le va redimensiona.
Prima funcție lambda va rula asincron ca răspuns la un eveniment de încărcare a fișierelor declanșat pe compartimentul S3 care va găzdui imaginile încărcate. Va prelua imaginea furnizată și o va redimensiona pentru a se potrivi într-o imagine de 400x400.
Cealaltă funcție lambda va servi pagina HTML, oferind atât funcționalitatea unui utilizator de a vizualiza imaginile redimensionate de cealaltă funcție Lambda, cât și o interfață pentru încărcarea unei imagini.
Configurare AWS inițială
Înainte de a începe, va trebui să configuram unele servicii AWS necesare, cum ar fi IAM și S3. Acestea vor fi configurate folosind consola AWS bazată pe web. Cu toate acestea, cea mai mare parte a configurației poate fi realizată și prin utilizarea utilitarului de linie de comandă AWS, pe care îl vom folosi mai târziu.
Crearea găleților S3
S3 (sau Serviciul de stocare simplu) este un serviciu de stocare de obiecte Amazon care oferă stocare fiabilă și rentabilă a oricăror date. Vom folosi S3 pentru a stoca imaginile care vor fi încărcate, precum și versiunile redimensionate ale imaginilor pe care le-am procesat.
Serviciul S3 poate fi găsit în meniul drop-down „Servicii” din consola AWS, în sub-secțiunea „Stocare și livrare de conținut”. Când creați o grupă, vi se va solicita să introduceți atât numele compartimentului, cât și să selectați o regiune. Selectarea unei regiuni apropiate de utilizatorii dvs. va permite lui S3 să se optimizeze pentru latență și cost, precum și pentru unii factori de reglementare. Pentru acest exemplu vom selecta regiunea „Standard SUA”. Aceeași regiune va fi folosită ulterior pentru găzduirea funcțiilor AWS Lambda.
Este demn de remarcat faptul că numele compartimentelor S3 trebuie să fie unice, așa că dacă numele ales este luat, vi se va cere să alegeți un nume nou, unic.
Pentru acest exemplu de proiect, vom crea două compartimente de stocare numite „test-upload” și „test-resized”. Secțiunea „încărcare de test” va fi folosită pentru încărcarea imaginilor și stocarea imaginii încărcate înainte de a fi procesată și redimensionată. Odată redimensionată, imaginea va fi salvată în compartimentul „test-redimensionat”, iar imaginea brută încărcată va fi eliminată.
Permisiuni de încărcare S3
În mod implicit, permisiunile S3 sunt restrictive și nu vor permite utilizatorilor externi sau chiar utilizatorilor care nu sunt administrativi să citească, să scrie, să actualizeze sau să șteargă orice permisiuni sau obiecte din compartiment. Pentru a schimba acest lucru, va trebui să fim autentificați ca utilizator cu drepturi de gestionare a permisiunilor pentru compartimentul AWS.
Presupunând că ne aflăm pe consola AWS, putem vizualiza permisiunile pentru compartimentul nostru de încărcare selectând compartimentul după nume, făcând clic pe butonul „Proprietăți” din colțul din dreapta sus al ecranului și deschizând secțiunea restrânsă „Permisiuni”.
Pentru a permite utilizatorilor anonimi să încarce în acest compartiment, va trebui să edităm politica compartimentului pentru a permite permisiunea specifică care permite încărcarea. Acest lucru se realizează printr-o politică de configurare bazată pe JSON. Acest tip de politici JSON sunt utilizate pe scară largă în AWS împreună cu serviciul IAM. După ce faceți clic pe butonul „Editați politica coletului”, pur și simplu lipiți următorul text și faceți clic pe „Salvare” pentru a permite încărcarea imaginilor publice:
{ "Version": "2008-10-17", "Id": "Policy1346097257207", "Statement": [ { "Sid": "Allow anonymous upload to /", "Effect": "Allow", "Principal": { "AWS": "*" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::test-upload/*" } ] }
După ce facem acest lucru, putem verifica că politica compartimentului este corectă încercând să încărcăm o imagine în compartiment. Următoarea comandă cURL va face truc:
curl https://test-upload.s3.amazonaws.com -F 'key=test.jpeg' -F '[email protected]'
Dacă se returnează un răspuns cu interval de 200, vom ști că configurația pentru grupul de încărcare a fost aplicată cu succes. Gălețile noastre S3 ar trebui acum (în mare parte) configurate. Vom reveni mai târziu la acest serviciu în consolă pentru a conecta evenimentele noastre de încărcare a imaginii la invocarea funcției noastre de redimensionare.
Permisiuni IAM pentru Lambda
Rolurile Lambda rulează toate într-un context de permisiune, în acest caz un „rol” definit de serviciul IAM. Acest rol definește toate permisiunile pe care funcția Lambda le are în timpul invocării sale. În scopul acestui exemplu de proiect, vom crea un rol generic care va fi utilizat între ambele funcții Lambda. Cu toate acestea, într-un scenariu de producție, se recomandă o granularitate mai fină în definițiile de permisiuni pentru a se asigura că orice exploatare a securității este izolată doar de contextul de permisiune care a fost definit.
Serviciul IAM poate fi găsit în subsecțiunea „Securitate și identitate” din meniul drop-down „Servicii”. Serviciul IAM este un instrument foarte puternic pentru gestionarea accesului la serviciile AWS, iar interfața furnizată poate fi puțin copleșitoare la început dacă nu sunteți familiarizat cu instrumente similare.
Odată ajuns pe pagina tabloului de bord IAM, subsecțiunea „Roluri” poate fi găsită în partea stângă a paginii. De aici putem folosi butonul „Creați un rol nou” pentru a afișa un vrăjitor în mai mulți pași pentru a defini permisiunile rolului. Să folosim „lambda_role” ca nume al permisiunii noastre generice. După ce continuați din pagina de definire a numelui, vi se va prezenta opțiunea de a selecta un tip de rol. Deoarece avem nevoie doar de acces S3, faceți clic pe „AWS Service Roles” și în caseta de selecție selectați „AWS Lambda”. Vi se va prezenta o pagină cu politici care pot fi atașate acestui rol. Selectați politica „AmazonS3FullAccess” și continuați cu pasul următor pentru a confirma rolul care urmează să fie creat.
Este important să rețineți numele și ARN-ul (Amazon Resource Name) rolului creat. Acesta va fi folosit la crearea unei noi funcții Lambda pentru a identifica rolul care urmează să fie utilizat pentru invocarea funcției.
Notă: AWS Lambda va înregistra automat toate ieșirile din invocări de funcții în AWS Cloudwatch, un serviciu de înregistrare. Dacă se dorește această funcționalitate, care este recomandată pentru un mediu de producție, la politicile pentru acest rol trebuie adăugată permisiunea de a scrie într-un flux de jurnal Cloudwatch.
Codul!
Prezentare generală
Acum suntem gata să începem codificarea. Vom presupune în acest moment că ați configurat comanda „awscli”. Dacă nu ați făcut-o, puteți urma instrucțiunile de la https://aws.amazon.com/cli/ pentru a configura awscli pe computer.
Notă: codul folosit în aceste exemple este scurtat pentru a ușura vizualizarea pe ecran. Pentru o versiune mai completă, vizitați depozitul la https://github.com/gxx/aws-lambda-python/.
În primul rând, să creăm o structură schelet pentru proiectul nostru.
aws-lambda-python/ - image_list/ - handler.py - list.html - Makefile - requirements.txt - image_resize/ - handler.py - resize.py - Makefile - requirements.txt - .pydistutils.cfg
Avem două subdirectoare în structura noastră, câte unul pentru fiecare dintre funcțiile noastre lambda. În fiecare dintre acestea avem fișierele comune handler.py, Makefile și requirements.txt. Fișierul handler.py va conține metoda de apel la invocarea fiecăreia dintre funcțiile lambda și poate fi considerat punctul de intrare pentru funcții. Fișierul requirements.txt va conține o listă a dependențelor noastre, astfel încât să putem specifica și actualiza cu ușurință cerințele. În sfârșit, comanda Makefile pe care o vom folosi pentru a oferi un mecanism ușor de interacțiune cu awscli. Acest lucru va face procesul de creare și actualizare a funcției noastre lambda mult mai ușor.
Veți observa fișierul .pydistutils.cfg în rădăcina directorului nostru de proiect. Acest fișier este necesar dacă lucrați cu Python în Homebrew. Datorită metodei de implementare a unei funcții Lambda (acoperită în secțiunea următoare), acest fișier este necesar. Consultați depozitul pentru mai multe detalii.
Redimensionarea imaginii Funcția Lambda
Cod
Începând cu funcția resize_image, vom îngheța dependența Wand, biblioteca noastră de procesare a imaginilor, salvând Wand==0.4.2
în requirements.txt. Aceasta va fi singura dependență pentru funcția noastră lambda image_resize. Funcția resize_image din resize.py va trebui să gestioneze o resursă de imagine din biblioteca Wand și să o redimensioneze în funcție de parametrii de lățime și înălțime specificați. Pentru a păstra imaginea care este redimensionată, vom folosi un algoritm de redimensionare „cel mai potrivit” care va menține raportul imaginii imaginii originale, reducând în același timp dimensiunea imaginii pentru a se încadra în lățimea și înălțimea specificate.
def resize_image(image, resize_width, resize_height): ... original_ratio = image.width / float(image.height) resize_ratio = resize_width / float(resize_height) # We stick to the original ratio here, regardless of what the resize ratio is if original_ratio > resize_ratio: # If width is larger, we base the resize height as a function of the ratio of the width resize_height = int(round(resize_width / original_ratio)) else: # Otherwise, we base the width as a function of the ratio of the height resize_width = int(round(resize_height * original_ratio)) if ((image.width - resize_width) + (image.height - resize_height)) < 0: filter_name = 'mitchell' else: filter_name = 'lanczos2' image.resize(width=resize_width, height=resize_height, filter=filter_name, blur=1) return image
Cu acest lucru în afara drumului, este necesară o funcție de gestionare pentru a accepta evenimentul generat de o imagine încărcată S3, pentru a-l transfera funcției resize_image
și pentru a salva imaginea redimensionată rezultată.

from __future__ import print_function import boto3 from wand.image import Image from resize import resize_image def handle_resize(event, context): # Obtain the bucket name and key for the event bucket_name = event['Records'][0]['s3']['bucket']['name'] key_path = event['Records'][0]['s3']['object']['key'] response = boto3.resource('s3').Object(bucket_name, key_path).get() # Retrieve the S3 Object # Perform the resize operation with Image(blob=response['Body'].read()) as image: resized_data = resize_image(image, 400, 400).make_blob() # And finally, upload to the resize bucket the new image s3_connection.Object('test-resized', key_path).put(ACL='public-read', Body=resized_data) # Finally remove, as the bucket is public and we don't want just anyone dumping the list of our files! s3_object.delete()
Desfășurare
Odată cu completarea codului, va trebui să fie încărcat pe Amazon Lambda ca o nouă funcție Lambda. Aici intră în joc Makefile care a fost adăugat la structura de directoare. Acest Makefile va fi folosit pentru a implementa definițiile funcției Lambda pe care le creăm.
ROLE_ARN = arn:aws:iam::601885388019:role/lambda_role FUNCTION_NAME = ResizeImage REGION = us-west-1 TIMEOUT = 15 MEMORY_SIZE = 512 ZIPFILE_NAME = image_resize.zip HANDLER = handler.handle_resize clean_pyc : find . | grep .pyc$ | xargs rm install_deps : pip install -r requirements.txt -t . build : install_deps clean_pyc zip $(ZIPFILE_NAME) -r * create : build aws lambda create-function --region $(REGION) \ --function-name $(FUNCTION_NAME) \ --zip-file fileb://$(ZIPFILE_NAME) \ --role $(ROLE_ARN) \ --handler $(HANDLER) \ --runtime python2.7 \ --timeout $(TIMEOUT) \ --memory-size $(MEMORY_SIZE) update : build aws lambda update-function-code --region $(REGION) \ --function-name $(FUNCTION_NAME) \ --zip-file fileb://$(ZIPFILE_NAME) \ --publish
Principalele funcții ale acestui Makefile sunt „crearea” și „actualizarea”. Aceste funcții împachetează mai întâi directorul curent, care reprezintă tot codul necesar pentru a rula funcția Lambda. Apoi, orice dependențe specificate în fișierul requirements.txt
vor fi instalate în subdirectorul curent care urmează să fie împachetat. Pasul de ambalare arhivează conținutul directorului pentru a fi încărcat ulterior cu comanda „awscli”. Makefile-ul nostru poate fi adaptat pentru a fi utilizat în altă definiție a funcției Lambda.
În utilitarul Makefile, definim câteva variabile necesare pentru crearea/actualizarea imaginii noastre. Configurați-le după cum este necesar pentru ca comenzile Makefile să funcționeze corect pentru dvs.
-
ROLE_ARN
: Acesta este numele resursei Amazon care identifică rolul nostru sub care să rulăm funcția Lambda. -
FUNCTION_NAME
: numele funcției Lambda pe care o creăm/actualizăm. -
REGION
: Regiunea în care va fi creată/actualizată funcția Lambda. -
TIMEOUT
: Timeout în secunde înainte ca o invocare Lambda să fie oprită. -
MEMORY_SIZE
: dimensiunea memoriei în megaocteți la care funcția Lambda va avea acces atunci când este invocată. -
ZIPFILE_NAME
: numele pachetului arhivat care conține codul funcției Lambda și dependențe. -
HANDLER
: Calea absolută de import, în notație cu puncte, a funcției handler.
Odată configurat, rularea comenzii make create
va genera ceva similar cu următoarea ieșire:
$ make create pip install -r requirements.txt -t . ... find . | grep .pyc| xargs rm zip image_resize.zip -r * ... aws lambda create-function --region ap-northeast-1 \ --function-name ResizeImage2 \ --zip-file fileb://image_resize.zip \ --role arn:aws:iam::11111111111:role/lambda_role \ --handler handler.handle_resize \ --runtime python2.7 \ --timeout 15 \ --memory-size 512 { "CodeSha256": "doB1hsujmZnxZHidnLKP3XG2ifHM3jteLEBvsK1G2nasKSo=", "FunctionName": "ResizeImage", "CodeSize": 155578, "MemorySize": 512, "FunctionArn": "arn:aws:lambda:us-west-1:11111111111:function:ResizeImage", "Version": "$LATEST", "Role": "arn:aws:iam::11111111111:role/lambda_role", "Timeout": 15, "LastModified": "2016-01-10T11:11:11.000+0000", "Handler": "handler.handle_resize", "Runtime": "python2.7", "Description": "" }
Testare
După executarea comenzii de creare, funcția de redimensionare pentru imaginile noastre este disponibilă pentru a fi utilizată, însă nu a fost conectată la bucket-ul S3 pentru a primi evenimente. Putem testa în continuare funcția prin Consola AWS pentru a afirma că funcția gestionează în mod corespunzător evenimentele de încărcare a fișierelor S3. Pe tabloul de bord AWS Lambda, care poate fi găsit în sub-secțiunea „Calcul” din meniul drop-down „Servicii”, selectați numele funcției pe care am creat-o. Această pagină cu detaliile funcției Lambda oferă un meniu derulant etichetat „Acțiuni” care conține o opțiune etichetată „Configurare eveniment de testare”.
Făcând clic pe acesta, se va deschide un modal care vă permite să specificați un eveniment de testare și câteva exemple de șabloane. Alegeți exemplul „S3 Put” și înlocuiți orice mențiune a numelui unei găleți cu numele găleții care a fost configurată. Odată ce aceasta a fost configurată, utilizarea ulterioară a butonului „Test” de pe pagina funcției Lambda va invoca funcția Lambda ca și cum evenimentul configurat anterior ar fi avut loc într-adevăr.
Pentru a monitoriza orice urmă de stivă de erori sau mesaje de jurnal, puteți vizualiza fluxul de jurnal în Cloudwatch. Un nou grup de jurnal va fi creat în același timp în care a fost creată funcția Lambda. Aceste fluxuri de jurnal sunt utile și pot fi conectate la alte servicii.
Conectarea la S3 Bucket Events
Înapoi în tabloul de bord S3, extindeți secțiunea restrânsă „Evenimente” aflată în meniul „Proprietăți” pentru a afișa formularul „Notificări de evenimente”. Câmpurile obligatorii pe care să le completăm sunt intrările „Evenimente” și „Trimite către”. Din „Evenimente”, selectați evenimentul „Obiect creat (toate)”. Acest lucru va permite interceptarea tuturor evenimentelor care creează un obiect în compartimentul de încărcare. Pentru intrarea „Trimis către”, selectați butonul radio „Funcție Lambda”. Va apărea o nouă secțiune cu un drop-down care conține funcția lambda „ResizeImage” pe care am configurat-o ca opțiune. După ce faceți clic pe „Salvare”, orice eveniment „Obiect creat” va fi acum direcționat ca intrare la invocarea funcției Lambda „ResizeImage”.
Acum avem funcționalitatea de bază a aplicației. Să rulăm un alt test cURL pentru a ne asigura că totul funcționează conform așteptărilor. Utilizați cURL pentru a încărca o imagine în compartimentul S3 și verificați manual dacă imaginea este încărcată în compartimentul de redimensionare.
curl https://test-upload.s3.amazonaws.com -F 'key=test.jpeg' -F '[email protected]'
La executarea acestei comenzi, imaginea redimensionată ar trebui creată în compartimentul „test-redimensionat” după 50-1000 ms, în funcție de faptul dacă funcția Lambda a fost deja „încălzită”.
Listă imaginea funcției Lambda
Cod
Funcția ListImage Lambda va prelua o listă de imagini redimensionate și le va afișa pe o pagină HTML pentru utilizator. Această pagină HTML oferă, de asemenea, funcționalitatea utilizatorului de a încărca propriile imagini. Jinja2 este folosit în funcție pentru a reda HTML dintr-o definiție de șablon. La fel ca și înainte, aceste cerințe sunt specificate în fișierul requirements.txt
.
from __future__ import print_function import os import boto3 from jinja2 import Environment from jinja2 import FileSystemLoader def _render_template(image_urls): env = Environment(loader=FileSystemLoader(os.path.abspath(os.path.dirname(__file__)))) template = env.get_template('list.html') rendered_template = template.render(image_urls=image_urls) return rendered_template def handle_list_image(event, context): bucket = boto3.resource('s3').Bucket('test-resized') image_summaries = sorted((image_summary for image_summary in bucket.objects.all()), key=lambda o: o.last_modified) image_urls = [] for summary in image_summaries: image_urls.append( boto3.client('s3').generate_presigned_url( 'get_object', Params={ 'Bucket': summary.bucket_name, 'Key': summary.key } ) ) return {'htmlContent': _render_template(image_urls)}
<html> <head> <title>List Images</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script> var uploadImage = (function () { var inProgress = false; return function () { if (inProgress) { return; } inProgress = true; var formData = new FormData(); var fileData = $('#image-file').prop('files')[0]; formData.append('key', parseInt(Math.random() * 1000000)); formData.append('acl', 'public-read'); formData.append('file', fileData); $.ajax({ url: 'https://test-upload.s3.amazonaws.com/', type: 'POST', data: formData, processData: false, contentType: false, success: function (data) { window.location.reload(); } }); } })(); </script> <style type="text/css"> .image__container { float: left; width: 30%; margin-left: 2.5%; margin-right: 2.5%; max-width: 400px; } </style> </head> <body> <nav> <input type="file" onchange="uploadImage()" value="Upload Image" /> </nav> <section> {% for image_url in image_urls %} <div class="image__container"> <img src="{{ image_url }}" /> </div> {% endfor %} </section> </body> </html>
Încă o dată, putem modifica fișierul Makefile anterior și putem folosi comanda create pentru a implementa funcția noastră lambda.
Gateway API
Funcția ImageList Lambda este completă, dar nu poate fi oferită niciunui utilizator. Acest lucru se datorează faptului că funcțiile Lambda pot fi apelate doar fie ca răspuns la un eveniment de la alt serviciu, fie în mod programatic. Aici intervine serviciul Amazon AWS API Gateway. Gateway-ul API poate fi găsit în subsecțiunea „Servicii de aplicație”.
API Gateway este o modalitate de modelare a punctelor finale ca un set de resurse și metode, în esență o interfață REST. Pe lângă faptul că oferă o facilitate pentru validarea și transformarea cererilor, API Gateway îndeplinește și alte funcții, cum ar fi furnizarea de cereri de limitare/limitare a ratei.
Din tabloul de bord API Gateway, creați un nou API pentru a servi funcția ListImage. Numele și descrierea pot fi setate după preferințele dvs. Odată creat, faceți clic pe numele noului API pentru a accesa detaliile API. Creați o nouă resursă pentru adresa URL rădăcină „/”. Această adresă URL va fi utilizată pentru a difuza pagina HTML.
În timp ce vizualizați detalii pentru pagina de resurse rădăcină, adăugați o metodă GET. Setați „Tipul de integrare” să fie „Funcție Lambda”, setați „Regiune Lambda” la „us-west-1” sau regiunea selectată de dvs. și introduceți numele funcției Lambda ListImage.
Înainte de a începe maparea răspunsului nostru la o ieșire HTML, trebuie să definim un „model” care va defini o schemă pentru răspunsul de la server, în plus față de maparea acestui răspuns la un tip de conținut. Selectați secțiunea „Modele” pentru API și faceți clic pe „Creare” pentru a crea un nou model. Dați modelului numele „HTML”, cu un tip de conținut „text/html” și definiți schema după cum urmează:
{ "$schema": "http://json-schema.org/draft-04/schema#", "title" : "HTML", "type" : "object" }
Înapoi pe tabloul de bord API, selectați resursa pe care am creat-o și navigați la secțiunea „Răspuns de integrare”. Această secțiune definește orice transformare de proces după primirea unui răspuns de la funcția Lambda înainte de a trimite răspunsul la pasul final.
Deschideți secțiunea „Șabloane de cartografiere” și adăugați un nou „Tip de conținut” de „text/html”. Eliminați vechiul „Tip de conținut” în același timp. În partea dreaptă, schimbați meniul drop-down din „Output Passthrough” în „Mapping template”. Acest lucru ne va permite să modificăm JSON brut acceptat de API Gateway și să folosim conținutul HTML din proprietatea „htmlContent” a datelor noastre returnate. Pentru șablonul de mapare, specificați „$input.htmlContent” ca șablon. În cele din urmă, modificați secțiunea „Răspuns metoda” eliminând „application/json” din „Modele de răspuns pentru 200” și adăugând în schimb „text/html”.
Revenind la tabloul de bord pentru API, există un buton în partea din stânga sus a paginii etichetat „Deploy API”. Faceți clic pe acest buton pentru a actualiza sau a crea API-ul cu resursele, metodele, modelele și mapările specificate. Odată ce se face acest lucru, va fi afișată o adresă URL pentru etapa de implementare care a fost selectată (înscenare în mod implicit). În sfârșit, exemplul este complet! Puteți încărca câteva fișiere pentru a testa și vizualiza imaginile redimensionate.
Încheierea
AWS este un serviciu mare și nu va dispărea prea curând. Deși blocarea furnizorului este întotdeauna ceva de care trebuie să aveți grijă, AWS Lambda oferă un serviciu relativ subțire, cu un set bogat de opțiuni de configurare auxiliare. Folosirea serviciilor furnizate de AWS pentru a implementa aplicații ușor scalabile și întreținute va oferi cel mai mare beneficiu al utilizării platformei AWS. AWS Lambda oferă o soluție elegantă, scalabilă și rentabilă, susținută de o platformă de nivel enterprise, utilizată de un număr foarte mare de consumatori. Cred că aplicațiile „fără server” sunt calea viitorului. Spune-ne ce crezi în comentariile de mai jos.