Erstellen wir eine API, die DynamoDB-Daten mit AWS SAM abruft
Kurz gesagt, von einem Tisch wie diesem ...
group(Hash) | name(Range) |
---|---|
group1 | name1 |
group1 | name2 |
group2 | name3 |
Ich möchte es so nehmen.
curl https://hogehoge/Prod/dynamo-api/v1/?group=group1&name=name1
{
"result": [
{
"name": "group1",
"group": "name1"
}
]
}
Informationen zur Erstellung finden Sie in der vorherigen [AWS SAM] Einführung in die Python-Version. (Dies ist das Verfahren zum Initialisieren einer AWS SAM-Anwendung mit Pipenv.)
Die Ressourcen, die dieses Mal erstellt werden müssen, sind wie folgt
Schreiben wir nun template.yaml, um die oben genannten Ressourcen zu erstellen.
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
dynamo-api
Sample SAM Template for dynamo-api
#Lambda-Timeout-Einstellungen
Globals:
Function:
Timeout: 60
#Definition von Tabellenname, Funktionsname usw.
Parameters:
DynamoAPIFunctionName:
Type: String
Default: dynamo-api
DynamoTableName:
Type: String
Default: DynamoApiTable
#Ressourcendefinition
Resources
DynamoTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Ref DynamoTableName
#Definition von Hash-Schlüssel und Bereichsschlüssel (Spaltenname und -typ)
AttributeDefinitions:
- AttributeName: group
AttributeType: S
- AttributeName: name
AttributeType: S
KeySchema:
- AttributeName: group
KeyType: HASH
- AttributeName: name
KeyType: RANGE
#Lademodusbezeichnung (PAY_PER_ANFRAGE ist Pay-as-you-go)
BillingMode: PAY_PER_REQUEST
DynamoAPIFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- 'lambda.amazonaws.com'
Action:
- 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
#Lesen in DynamoDB-Tabelle zulassen (dies ermöglicht nur das Lesen der Tabelle, die Sie dieses Mal erstellen)
Policies:
- PolicyName: 'DynamoApiTablePolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:Get*
- dynamodb:Query
Resource: !GetAtt DynamoTable.Arn
DynamoAPIFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Ref DynamoAPIFunctionName
Role: !GetAtt DynamoAPIFunctionRole.Arn
# app.Verzeichnispfad, in dem sich py befindet
CodeUri: dynamo-api/
#Handler-Pfad (Es ist leicht, einen Fehler zu machen, wenn Sie ihn unachtsam ändern ... Es ist gut, ihn in Ruhe zu lassen)
Handler: app.lambda_handler
Runtime: python3.7
#API-Gateway-Einstellungen (SAM-spezifische Beschreibung)
Events:
DynamoApi:
Type: Api
Properties:
Path: /dynamo-api/v1/
Method: get
#Die ursprüngliche Rolle der in Ausgaben angegebenen Parameter besteht darin, Daten an andere Vorlagen zu übergeben.
#Dieses Mal wird es verwendet, um den API-Endpunkt auszugeben, wenn die Bereitstellung abgeschlossen ist.
Outputs:
DynamoApi:
Description: "API Gateway endpoint URL for Prod stage for Dynamo API function"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/dynamo-api/v1/"
Die Einstellungen für Lambda und API Gateway stimmen fast mit denen der Vorlage überein, sodass das Schreiben einfach ist.
Installieren Sie zunächst die erforderlichen Bibliotheken.
$ pipenv install requests boto3
Als Nächstes erstellen wir einen Prozess, der tatsächlich Daten aus der Dynamo-Tabelle abruft. Durchsuchen Sie die Dynamo-Tabelle mit den im Parameter GET angegebenen "Gruppen" und "Namen" und geben Sie ihren Wert zurück Es ist ein einfacher Mechanismus. Ich habe versucht, "Name" zum vorderen zu machen.
app.py
import json
import json
import boto3
from boto3.dynamodb.conditions import Key
from http import HTTPStatus as status
DYNAMODB_TABLE_NAME = 'DynamoApiTable'
def lambda_handler(event, context):
table = boto3.resource('dynamodb').Table(DYNAMODB_TABLE_NAME)
params = event.get('queryStringParameters')
results = dynamo_search(table, params)
if results is None:
return {
"statusCode": status.BAD_REQUEST,
"body": json.dumps({
"error": "Bad Request"
}, ensure_ascii=False),
}
return {
"statusCode": status.OK,
"body": json.dumps({
"results": results
}, ensure_ascii=False),
}
def dynamo_search(table, params):
if params.get('group'):
keyConditionExpression = Key('group').eq(params.get('group'))
if params.get('name'):
keyConditionExpression &= Key('name').begins_with(params.get('name'))
return table.query(
KeyConditionExpression=keyConditionExpression).get('Items', [])
return None
Ich möchte von Pipfile
zu require.txt
konvertieren ...
In einem solchen Fall können Sie mit diesem Befehl konvertieren.
(Boto3 wird von Anfang an auch in Lambda vorbereitet, daher darf es nicht viel verwendet werden ..: Denken :)
$ pipenv lock -r > requirements.txt
Dieses Mal können Sie die Standardeinstellung "require.txt" beibehalten: heat_smile:
$ sam build
Building resource 'DynamoAPIFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
Build Succeeded
Built Artifacts : .aws-sam/build
Built Template : .aws-sam/build/template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
Wenn Sie separate Einstellungen für "~ / .aws / credentials" haben, fügen Sie die Option --profile hinzu.
Die Option "--guided" ist nur zum ersten Mal in Ordnung. (Weil die Einstellungen in samconfig.toml
gespeichert sind)
$ sam deploy --guided
Stack dynamo-api-stack outputs:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
OutputKey-Description OutputValue
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
DynamoApi - API Gateway endpoint URL for Prod stage for Dynamo API function https://hogehoge/Prod/dynamo-api/v1/
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Der Endpunkt wird auch richtig ausgegeben ~
Dieses Mal (auch) habe ich den empfohlenen Gruppennamen und -namen registriert.
group(Hash) | name(Range) |
---|---|
Honigband | Suo Patra |
Honigband | Miko Weir |
Holo leben | Fubuki Shirakami |
... | ... |
Versuchen Sie, eine Anforderung an den Ausgabeendpunkt zu senden. Es ist schwer zu sehen, also formatieren wir es mit jq
.
(Leute im Browser, weil "Curl" lästig ist: information_desk_person :)
Geben Sie zunächst group
(Hash-Schlüssel) an.
$ curl https://hogehoge/Prod/dynamo-api/v1/ \
--get \
--data-urlencode 'group=Honigband' | jq
{
"results": [
{
"name": "Suo Patra",
"group": "Honigband"
},
{
"name": "Miko Weir",
"group": "Honigband"
},
{
"name": "Shimamura Charlotte",
"group": "Honigband"
},
{
"name": "Saizonoji Mary",
"group": "Honigband"
}
]
}
Ich habe es verstanden: klatschen:
Natürlich können Sie auch nach "Name" (Bereichstaste) mit einer Präfixübereinstimmung suchen.
$ curl https://hogehoge/Prod/dynamo-api/v1/ \
--get \
--data-urlencode 'group=Honigband' \
--data-urlencode 'name=Suo' | jq
{
"results": [
{
"name": "Suo Patra",
"group": "Honigband"
}
]
}
Ich habe es verstanden! Es ist perfekt!
Dieses Mal habe ich eine einfache API erstellt. Nächstes Mal werde ich mit pytest
testen.
Vielen Dank für das Lesen bis zum Ende!