Let's connect API Gateway to the one of Last time. This is the goal
API Gateway
The GUI is pretty intuitive so you can use it without using your head.
/ project
GET`` PUT
POST`` DELETE
on the resourceproject
for each methodIt's easy to forget that you have to press "Deploy" to deploy the API changes. This should work for the time being
A little troublesome when using API keys
dev_1
here)It may take a few minutes for the changes to take effect, but now you should be able to call with the API key.
curl -s -X GET -H "x-api-key: your-api-key-here" https://<project-id>.execute-api.us-east-2.amazonaws.com/dev_1/projects | jq
--Check Lambda integrated proxy
--Associate the method (GET/PUT/POST/DELETE) with the lambda function [^ 1]
[^ 1]: In a case like this, actually using ANY
as a method eliminates the need to associate each method with a lambda function.
By doing so, various parameters included in the HTTP request are passed to Lambda as they are.
For example, you can tell on the Lambda side whether the HTTP method is POST
or GET
.
When I read it like this
curl -s -X GET -H "x-api-key:your-api-key-here" https://<api-id>.execute-api.us-east-2.amazonaws.com/dev_1/projects?say=ciao -d '{"say": "hello"}'
The parameter passed to Lambda as event
looks like this
event
{
"resource": "/projects",
"path": "/projects",
"httpMethod": "GET",
"headers": {
"accept": "*/*",
"content-type": "application/x-www-form-urlencoded",
"Host": "<project-id>.execute-api.us-east-2.amazonaws.com",
"User-Agent": "curl/7.64.1",
"X-Amzn-Trace-Id": "Root=1-5fd44390-5f78ee5a289e7e3a0355bec2",
"x-api-key": "your-api-key",
"X-Forwarded-For": "***.**.**.**",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
"accept": [
"*/*"
],
"content-type": [
"application/x-www-form-urlencoded"
],
"Host": [
"<project-id>.execute-api.us-east-2.amazonaws.com"
],
"User-Agent": [
"curl/7.64.1"
],
"X-Amzn-Trace-Id": [
"Root=1-5fd44390-5f78ee5a289e7e3a0355bec2"
],
"x-api-key": [
"<your-api-key>"
],
"X-Forwarded-For": [
"***.**.**.**"
],
"X-Forwarded-Port": [
"443"
],
"X-Forwarded-Proto": [
"https"
]
},
"queryStringParameters": {
"say": "ciao"
},
"multiValueQueryStringParameters": {
"say": [
"ciao"
]
},
"pathParameters": null,
"stageVariables": null,
"requestContext": {
"resourceId": "<resource-id>",
"resourcePath": "/projects",
"httpMethod": "GET",
"extendedRequestId": "Xa9-iG9kCYcFU8Q=",
"requestTime": "12/Dec/2020:04:14:08 +0000",
"path": "/dev_1/projects",
"accountId": "<account-id>",
"protocol": "HTTP/1.1",
"stage": "dev_1",
"domainPrefix": "<project-id>",
"requestTimeEpoch": 1607746448145,
"requestId": "06499aaf-9168-49d7-b4da-2a0a3ad5d4ad",
"identity": {
"cognitoIdentityPoolId": null,
"cognitoIdentityId": null,
"apiKey": "<your-api-key>",
"principalOrgId": null,
"cognitoAuthenticationType": null,
"userArn": null,
"apiKeyId": "<api-key-id>",
"userAgent": "curl/7.64.1",
"accountId": null,
"caller": null,
"sourceIp": "***.**.**.**",
"accessKey": null,
"cognitoAuthenticationProvider": null,
"user": null
},
"domainName": "<project-id>.execute-api.us-east-2.amazonaws.com",
"apiId": "<api-id>"
},
"body": "{\"say\": \"hello\"}",
"isBase64Encoded": false
}
The data body
from the client can be accessed byevent ['body']
, so change the CRUD code on the Lambda side a little from previous to make it look like this
require 'json'
require 'aws-sdk-dynamodb'
def add_project(table, body)
table.put_item({ item: body })
end
def delete_project(table, body)
params = { table_name: table, key: { 'project-id': body['project-id'] } }
begin
table.delete_item(params)
rescue Aws::DynamoDB::Errors::ServiceError => error
puts error.message
end
end
def update_project(table, body)
params = {
table_name: table,
key: { 'project-id': body['project-id'] },
attribute_updates: {
name: {
value: body['name'],
action: "PUT"
}
}
}
table.update_item(params)
end
def list_project(table)
scan_output = table.scan({ limit: 50, select: "ALL_ATTRIBUTES" })
scan_output.items.each do |item|
keys = item.keys
keys.each do |k|
puts "#{k}: #{item[k]}"
end
end
end
def lambda_handler(event:, context:)
http_method = event['httpMethod'] #Add this
body = JSON.parse(event['body']) #Add this
dynamodb = Aws::DynamoDB::Resource.new(region: 'us-east-2')
table = dynamodb.table('project')
case http_method
when 'GET' then list_project(table)
when 'PUT' then update_project(table, body)
when 'POST' then add_project(table, body)
when 'DELETE' then delete_project(table, body)
else 0
end
{ statusCode: 200, body: JSON.generate(list_project(table)) }
end
For example, if you make a request like this, you will see the HTTP method and perform CRUD processing. By the way, jq
is recommended because it is easy to see.
curl -s -X POST -d '{ "project-id":101, "name":"Cycling", "is-default":false }' -H "x-api-key: <your-api-key-here>" https://<project-id>.execute-api.us-east-2.amazonaws.com/dev_1/projects | jq
Um, it worked
Recommended Posts