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.