Serverless API – Jak postawić API bez serwera
Modne jest ostatnio wszystko, co ma związek z pojęciem serverless. Dziś zobaczymy jak postawić serverless API, czyli API bez serwera. Może nie bez serwera, ale bez zajmowania się serwerem. Taka opcja może się przydać nie tylko w celach testowych. Używając AWS Lambda możemy zapomnieć o konieczności skalowania, dbania o serwery, coś takiego jak brak dostępności do naszego API to będzie legenda.
Wykorzystamy AWS API Gateway i AWS Lambda. Pokażę jak prostą aplikację napisaną w Pythonie z wykorzstaniem Flask wrzucić do chmury i zacząć z niej korzystać.
Tworzymy API
Nie będę pokazywał jak stworzyć samą aplikację, czyli API. Zakładam, że to potraficie zrobić. Jeżeli nie, na GitHub udostępniam źródło prostego rozwiązania. Pamiętajcie tylko o dodaniu Flaska, czyli pip install Flask
.
W naszym API będziemy mieli dwa endpointy, jednen główny, oraz jeden z bardziej skomplikowaną ścieżką.
app = Flask(__name__) @app.route('/') def home(): return 'Hello, it\'s your first API' @app.route('/path') def deeper(): return 'Hello, it\'s another path'
Przygotowujemy i konfigurujemy nasze Serverless API
To tyle, jeżeli chodzi o kod. Teraz clue programu, Zappa. Zappa umożliwia deployment naszego rozwiązania w trzech krokach. Pierwszym z tych kroków jest dodanie jej (jej? Zappa to ona?) do naszego rozwiązania: pip install zappa
Dodajemy ją korzystając koniecznie z VirtualEnv.
Czym jest Zappa? Magikiem 🙂 W poprzednich wpisach pokazywałem jak skonfigurować AWS API Gateway. Zappa zrobi to za nas. I nie tylko to. Wrzuci także nasz kod do chmury. Po chwili od uruchomienia zaczynamy używać naszego API. Używać naszego API jako serverless, czyli otrzymamy nasz kod pracujący jako funkcja Lambda, z dostępem do niego poprzez AWS API Gateway. Ale po kolei.
Zainstalowaliśmy Zappę. Czas na skonfigurowanie projektu. Wpisujemy w konsoli zappa init
i zaczyna się dziać…
Zappa wita się z nami i pyta o środowisko, w którym chcemy pracować. Zostawmy domyślne dev
W kolejnym kroku podajemy nazwę bucketa S3, do którego Zappa będzie wrzucała uploadowane paczki z naszym kodem.
Zappa powinna rozpoznać typ naszej aplikacji, oraz zapyta o ścieżkę do funkcji.
Zostaniemy jeszcze zapytani czy chcemy uruchomić naszą funkcję globalnie (i nie, nie chcemy).
I powinna nam się ukazać propozycja konfiguracji utworzonej na podstawie naszych działań.
Możemy zawsze ten plik edytować lub usunąć i uruchomić kongirurację (zappa init) jescze raz. Po zatwierdzeniu dostaniemy instrukcję jak zrobić update naszej paczki w chmurze.
Wrzucamy do chmury
Mamy utworzoną konfugurację dla środowiska dev, spróbujmy wrzucić wszystko do chmury.
zappa deploy dev
i po chwili powiiniśmy mieć wszystko gotowe.
Dostaliśmy nawet jakiegoś urla 🙂 Otwieramy więc naszą ulubioną przeglądarkę, wklejamy tego urla i, voilà…
Dodajemy do urla naszą „rozbudowaną” ścieżkę, czyli teraz nasz url będzie wyglądał tak https://3luszhyzq7.execute-api.eu-west-1.amazonaws.com/dev/path
I znowu działa. Magia, mamy API na AWS bez dotykania AWS. No prawie 😉
Zobaczmy co tam nasz automat namieszał. Mamy więc utworzone API, które pracuje jako proxy
i przekazuje requesty do funkcji Lambda
Mieszamy
Aplikacje nigdy nie są skończone, a przede wszystkim bezbłędne. Robimy update naszego rozwiązania. Dodamy do naszego API obsługę POST. Zmeniamy trochę nasz kod, który teraz wygląda tak
from flask import Flask from flask import request app = Flask(__name__) @app.route('/') def home(): return 'Hello, it\'s your first API' @app.route('/path') def deeper(): return 'Hello, it\'s another path' @app.route('/hello', methods=['POST']) def hello(): data = request.json return 'Hello {0}'.format(data['name'])
i uaktualniamy nasze środowisko na AWS. zappa dev update
w terminalu
po chwili mamy nasze uaktualnienie wrzucone do chmury. Do przetestowania potrzebujemy jakiegoś klienta, mogącego wysłać POST request. Polecam Postmana, ale my zostaniemy w terminalu i wykorzystamy curla.
curl -X POST \ https://3luszhyzq7.execute-api.eu-west-1.amazonaws.com/dev/hello \ -H 'cache-control: no-cache' \ -H 'content-type: application/json' \ -H 'postman-token: 76fef9a0-74b1-e7ce-758c-594d2aa07c47' \ -d '{ "name" : "Przemek" }'
i znowu wszystko zadziałało
Podsumowanie
Czy API korzystające z funkcji AWS Lambda, Azure Functions czy Google CloudFunctions będzie zawsze lepszym rozwiązaniem? Nie. Przed wybraniem rozwiązania trzeba się zastanowić, co tak naprawdę nasze API robi i jakich zasobów potrzebuje. Ale to już chyba temat na osobny wpis.
Mnie cieszy jednak rozwój całej otoczki wokół chmur. Ułatwienia codziennej pracy. Możliwość oszczędności.