HTTP
endpoints have become one of the most ubiquitous ways of delivering software to end users. Cdev provides a simple interface for creating HTTP APIs
and connecting them to Serverless Functions
. You can find more information about HTTP
in the official documentation.
Open the src/hello_world/resources.py
file and start by importing the following resources:
import json from cdev.resources.simple.api import Api from cdev.resources.simple.xlambda import simple_function_annotation from cdev import Project as cdev_project
Next, add lines 8, 10 and 12
to define your project, API
and create your route.
import json from cdev.resources.simple.api import Api from cdev.resources.simple.xlambda import simple_function_annotation from cdev import Project as cdev_project myProject = cdev_project.instance() myApi = Api("demoApi") hello_world_get_route = DemoApi.route("/hello_world", "GET")
Now, intergrate your route with a Serverless Function by adding lines 10 - 35
.
import json from cdev.resources.simple.api import Api from cdev.resources.simple.xlambda import simple_function_annotation from cdev import Project as cdev_project myProject = cdev_project.instance() myApi = Api("demoApi") hello_world_get_route = myApi.route("/hello_world", "GET") @simple_function_annotation("demo_function", events=[hello_world_get_route.event()]) def hello_world(event, context): """ This is an example function connected to an example API route """ message = { "message": "Hello World from Lambda!" } return { "isBase64Encoded": False, "status_code": 200, "body": json.dumps(message), "headers": { "Content-Type": "application/json" } } myProject.display_output("Base API URL", myApi.output.endpoint) myProject.display_output("Routes", myApi.output.endpoints)
Save and deploy your endpoint with the following commands:
cdev plan
cdev deploy
Get the live url for your endpoint:
cdev output <component_name>.api.demoApi.endpoint
You can test the endpoint with the following commands from your terminal:
curl <your_endpoint>/hello_world
Using the same src/hello_world/resources.py
file from the GET
route example, make the following changes.
Replace lines 12 - 31
with:
send_data_route = myApi.route("/send_data", "POST")
@simple_function_annotation("send_data_handler", events=[send_data_route.event()])
def hello_world(event, context):
"""
This is an example function connected to an example POST API route that can receive data
"""
print(event)
data = json.loads(event.get("body"))
print(data)
message = {
"message": "Handled Data"
}
return {
"isBase64Encoded": False,
"status_code": 200,
"body": json.dumps(message),
"headers": {
"Content-Type": "application/json"
}
}
The src/hello_world/resources.py
now looks like:
import json from cdev.resources.simple.api import Api from cdev.resources.simple.xlambda import simple_function_annotation from cdev import Project as cdev_project myProject = cdev_project.instance() myApi = Api("demoApi") send_data_route = myApi.route("/send_data", "POST") @simple_function_annotation("send_data_handler", events=[send_data_route.event()]) def hello_world(event, context): """ This is an example function connected to an example POST API route that can receive data """ print(event) data = json.loads(event.get("body")) print(data) message = { "message": "Handled Data" } return { "isBase64Encoded": False, "status_code": 200, "body": json.dumps(message), "headers": { "Content-Type": "application/json" } } myProject.display_output("Base API URL", myApi.output.endpoint) myProject.display_output("Routes", myApi.output.endpoints)
Save and deploy your endpoint with the following commands:
cdev plan
cdev deploy
Get the live url for your endpoint:
cdev output <component_name>.api.demoApi.endpoint
You can test the endpoint with the follow commands from your terminal:
curl -X POST <your_endpoint>/send_data -H 'Content-Type: application/json' -d "{\"login\":\"my_login\"}"
Check the logs of your function
cdev run function.logs <component_name>.send_data_handler
From the AWS Documentation, API Gateway makes the following assumptions if your Lambda
function returns valid JSON
and does not return a statusCode:
false
.200
.application/json
.function's response
.Examples:
Function Response
return "Hello from Lambda!"
API Gateway Response
{
"isBase64Encoded": false,
"statusCode": 200,
"body": "Hello from Lambda!",
"headers": {
"content-type": "application/json"
}
}
Function Response
return { "message": "Hello from Lambda!" }
API Gateway Response
{
"isBase64Encoded": false,
"statusCode": 200,
"body": "{ \"message\": \"Hello from Lambda!\" }",
"headers": {
"content-type": "application/json"
}
}
If you want to customize your return value completely, it should have the form:
return {
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": True|False,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": "Hello from Lambda!"
}
If you are going to return a custom value and want the body to be a JSON
value, the value must be a JSON
encoded string. You can use the std lib json.dumps
method to generate the properly encoded string.
return {
"cookies" : ["cookie1", "cookie2"],
"isBase64Encoded": True|False,
"statusCode": httpStatusCode,
"headers": { "headername": "headervalue", ... },
"body": json.dumps({
"message" :"Hello from Lambda!"
})
}