Ich möchte eine Seite erstellen, die __dynamisches HTML mit Lambda aus AWS __ generiert. Mit Lambda können Sie Ihre bevorzugten Python-Skripte ausführen, ohne einen eigenen Server einrichten zu müssen. Daher werde ich versuchen, damit eine Seite zu erstellen, die dynamisches HTML generiert.
Es gibt bereits einige Gespräche über das Erstellen von Seiten mit Lambda, aber die zuvor angekündigte __API Gateway Lambda-Proxy-Integration __ Der Zweck dieser Zeit ist es, das Gefühl ein wenig besser zu machen, indem Lambdas Bereitstellungstool apex kombiniert wird. Außerdem ist template engine für das Ausspucken von HTML aus dem Skript unverzichtbar. Daher habe ich damit gespielt, um zu überprüfen, ob es tatsächlich in Kombination verwendet werden kann.
Was die Art der Seite angeht, habe ich mich diesmal entschlossen, einen __ Schrein __ zu bauen. Eine der berühmten Template-Engines von Python ist "jinja2", und ich habe beschlossen, einen Schrein ohne Server zu erstellen. (Aber es ist nur eine Webseite, nur für den Fall)
Ich möchte es als Beispiel für eine dynamische Seite erstellen, daher werde ich einen Zugriffszähler einrichten, der die Anzahl der Anbeter anzeigt. Die Rückgabe der aktuellen Uhrzeit ist ein gutes Beispiel für Dynamik, aber es ist auch langweilig, das zu tun, was Sie mit Javascript auf dem Server tun können, und ich denke, dass die meisten Dinge, die eine dynamische Verarbeitung erfordern, dazu dienen, mit der Datenbank herumzuspielen. Ich habe den Zugangsschalter als praktisches Element gewählt. Achten Sie darauf, dass der Zugangsschalter selbst wie ein Fossil behandelt wird.
https://cloudcraft.co/view/67eed248-a460-46dc-91dd-fdb5a70f529f?key=D4aRY_6kyWIfbEKtYk78TQ
Die Konfiguration des Servers, den ich dieses Mal vornehmen werde, ist wie folgt. Lambda kann nicht direkt vom Browser aus aufgerufen werden, daher habe ich das API-Gateway zuvor gebissen, um es zugänglich zu machen. Darüber hinaus wird DynamoDB dahinter installiert, um die Anzahl der Zugriffe zu speichern. DynamoDB ist auch eine Schlüsselwertdatenbank, die verwendet werden kann, ohne eine Instanz zu erstellen. Es ist einfach, aber es ist immer noch eine gute Architektur ohne Server.
Apex
Dieses Mal habe ich beschlossen, Lambda mit einem Tool namens Apex bereitzustellen. Wenn Sie externe Bibliotheken mit Lambda verwenden, müssen diese komprimiert und platziert werden. Dieses Tool namens Apex ist jedoch sehr praktisch, da es die Bereitstellung und Ausführung installierter Skripts über die Befehlszeile vereinfacht.
Ich werde hier nicht auf Details eingehen,
apex deploy
Sie können so schnell bereitstellen.
DynamoDB Bereiten Sie zuerst eine Tabelle für die Zugriffsaggregation vor. Im Fall von DynamoDB müssen nicht alle zu verwendenden Spalten definiert werden, da es schemenlos ist. Es ist jedoch erforderlich, den Primärschlüssel für das Scannen im Voraus zu bestimmen.
Dieses Mal habe ich die folgende Tabelle gemacht.
Wir haben einen primären Partitionsschlüssel namens "counter_id". Als Verwendung ist es so, als würde man 10 Zähler mit counter_id von 0 bis 9 vorbereiten und sie zufällig angeben, um sie zu erhöhen. Durch die Vorbereitung mehrerer Zähler wird das Schreiben nicht an einem Ort konzentriert und die Leistung kann konstant gehalten werden.
Da DynamoDB keine Transaktionen hat, dachte ich, dass das Schreiben in dieselbe Tabelle zur gleichen Zeit inkonsistent werden würde, aber es scheint, dass ein Atomzähler durch Inkrementieren als Ausdruck mit update_item
realisiert werden kann. (Ich habe gerade gelernt)
Beim Lesen erhalten wir alle Zähler und geben die Summe zurück. Wenn Sie keine "starke Konsistenz" verwenden, wird das schriftliche Ergebnis anscheinend nicht sofort wiedergegeben, aber diesmal bitten wir nicht um Strenge, daher verwenden wir eine vernünftig schwache Konsistenz.
Das Ergebnis des mehrmaligen Schreibens.
Ich werde es sofort schaffen.
Durch das Einfügen des Jinja2-Pakets und der Vorlage, die ich verwenden möchte, in den Apex-Funktionsordner konnte ich die Vorlagen-Engine problemlos mit Lambda verwenden.
Ordnerstruktur.txt
├── functions
│ └── jinja
│ ├── jinja2/Eine solche
│ ├── main.py
│ ├── requirements.txt
│ └── templates
│ ├── index.html
│ └── layout.html
├── project.json
Die Ordnerstruktur aus dem Apex-Projektstamm befindet sich oben. In dem Ordner namens functions befindet sich ein Ordner namens jinja. Dies ist der Stammordner der diesmal definierten Lambda-Funktion. Durch das Erstellen mehrerer Ordner in dieser Hierarchie ist es möglich, verschiedene Lambda-Funktionen zusammen zu verarbeiten.
Um jinja2
zu verwenden, müssen Sie pip install -t .jinja2
im jinja-Ordner ausführen, um das gesamte jinja2-Paket zu installieren. Erstellen Sie außerdem einen Ordner für die Vorlagendateien, die Sie verwenden möchten.
main.py
# coding: utf-8
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader(path.join(path.dirname(__file__), 'templates'), encoding='utf8'))
template = env.get_template('index.html')
html = template.render()
Beim Anrufen sieht es so aus. Jetzt können Sie die Vorlagen in templates / index.html ausgeben.
Es ist einfach, die offizielle Bibliothek "boto3" zu verwenden, um über die Lambda-Funktion auf DynamoDB zuzugreifen. Sie können es verwenden, ohne es in das Apex-Paket einfügen zu müssen (in einigen Fällen können Sie es explizit einfügen, weil Sie die Version korrigieren möchten). Wenn Sie die entsprechende Rolle für Lambda angeben, können Sie es verwenden, ohne sich in Ihrem Code authentifizieren zu müssen.
main.py
import boto3
dynamodb = boto3.resource('dynamodb')
count_table = dynamodb.Table('lambda-jinja')
counts = count_table.scan(Limit=10)
Mit API Gateway können Sie Lambda über HTTP ausführen und die Ergebnisse erhalten. Beim herkömmlichen API-Gateway musste jedoch zugeordnet werden, welche Art von Anforderung in welcher Art von Pfad einging und welche Art von Antwort zurückgegeben wurde. Dies ist relativ problematisch. Ich konnte den Fall nicht behandeln, in dem ich nicht auf beliebige Anfragen antworten oder ein Skript gemäß dem Pfad wiederverwenden konnte, aber kürzlich wurde ein wunderbarer Mechanismus namens Proxy-Integration eingeführt. es war erledigt. Wenn Sie dies verwenden, werden Anforderungs- und Pfadinformationen an die Funktionsseite übergeben, sodass die Möglichkeiten von API Gateway + Lambda sofort erweitert werden. Diesmal habe ich es sofort versucht.
Erstellen Sie auf diese Weise eine Methode und eine Ressource für die Route mit API Gateway und ordnen Sie diese Lambda zu, die diesmal erstellt werden soll.
swagger.yaml
---
swagger: "2.0"
basePath: "/jinja"
schemes:
- "https"
paths:
paths:
/:
x-amazon-apigateway-any-method:
produces:
- "application/json"
responses:
200:
description: "200 response"
schema:
$ref: "#/definitions/Empty"
/{proxy+}:
x-amazon-apigateway-any-method:
produces:
- "application/json"
parameters:
- name: "proxy"
in: "path"
required: true
type: "string"
responses: {}
definitions:
Empty:
type: "object"
title: "Empty Schema"
Das Schreiben in Swagger sieht so aus.
Durch Auflisten der Ressource als "/ {proxy +}" ist es möglich, Anforderungen eines beliebigen Pfads mit demselben Lambda zu verarbeiten.
Ich konnte den Zugriff des Stamms nicht nur mit / {proxy +}
abrufen, daher habe ich auch eine separate Methode für den Stamm definiert.
Das Setup auf der API-Gateway-Seite war einfach, aber auf der Lambda-Seite gab es ein Problem. Ich habe mich gefragt, ob ich ein Lambda erstellen könnte, das HTML zurückgibt und es mit API Gateway verbindet, und es würde die Seite zurückgeben, aber es war etwas anders. Wenn Sie nur HTML zurückgeben, wird 502 auf der API-Gateway-Seite zurückgegeben. Zuerst habe ich mit den Einstellungen für ContentType und API Gateway herumgespielt und gedacht, dass das Format nicht JSON ist, aber die Ursache liegt woanders.
Bei Verwendung der Proxy-Integration scheint das Skript __ eine Antwort in einem bestimmten Format __ zurückgeben zu müssen. Es war eine Pointe, dass 502 ohne Fragen zurückgegeben würde, wenn Sie dieses Format nicht befolgen würden.
Klicken Sie hier für das feste Format.
main.py
def handle(event, context):
html = ...
return {
"statusCode": 200,
"headers": {"Content-Type": "text/html"},
"body": html
}
Es ist erforderlich, das Wörterbuch, das drei von "statusCode", "headers" und "body" definiert, aus der von Lambda aufgerufenen Funktion zurückzugeben. API Gateway betrachtet diese und erstellt eine HTTP-Antwort.
Außerdem werden alle Informationen beim Anfordern einer Anforderung an das API-Gateway an das Ereignis (erstes Argument) der Funktion "handle" übergeben. In diesem Beispiel wird von pprint angezeigt, welche Art von Wert übergeben wird. Wenn Sie möchten, beziehen Sie sich bitte darauf.
https://teu24wc5u9.execute-api.ap-northeast-1.amazonaws.com/jinja/ Der Schrein wurde erfolgreich abgeschlossen. Ich wollte die Seite ein bisschen mehr wie einen Schrein machen, aber ich war erschöpft, weil ich keine Zeit hatte. Ich bin froh, dass ich Ihnen gesagt habe, was ich technisch vermitteln möchte.
Können Sie sehen, dass die Anzahl der angezeigten Anbeter mit jedem Zugriff zunimmt? Ich konnte eine dynamische Webseite erstellen, ohne eine einzelne Instanz zu erstellen.
Der Pfad zum Zugriff ist
/jinja/
/jinja/hoge
/jinja/fuga
/jinja/piyopiyo
Alles wird akzeptiert. Die Anforderungsinformationen "Pfad" am Ende der Seite sollten ebenfalls ordnungsgemäß verwendet werden. Auf diese Weise können Sie ganz einfach Ihren eigenen Routing-Prozess hinzufügen und verschiedene Seiten anzeigen.
Aufgrund von API-Gateway-Einschränkungen ist der Teil / jinja /
eine Versionszeichenfolge und kann nicht entfernt werden.
Für den Zugriff über root scheint es gut, CloudFront usw. vor API Gateway zu stellen. Sie können statische Dateien nicht nur mit API Gateway hosten.
Ich habe versucht, mit Lambda eine dynamische Seite mit einer ziemlich engen Abweichung zu erstellen, aber es war gut, sie sicher erstellen zu können. Ich hatte wegen des Namens API Gateway Bedenken, etwas für API als Webseite zu verwenden, aber am Ende ist es mächtig, dass sogar ein vollwertiger Webdienst mit Lambda + API Gateway verwendet werden kann. Ich habe es gefühlt. Der einzige Schmerz in Lambda ist, dass Sie nur Python2 verwenden können ... Bitte unterstütze 3 so schnell wie möglich: bete:
https://github.com/pistatium/lambda_jinja_sample Die Quelle für diese Zeit ist hier.
Unsere Qiita-Organisation Wurde letztes Mal gemacht. Ich würde gerne mein Bestes geben, um etwas anderes als AdventCalender zu schreiben.
Recommended Posts