基本項目結構需要兩個文件:package.jsonserverless.yml。

package.json 文件用于列出項目的 npm 依賴項,這些依賴項在 CLI 打包項目時將被拉取。CLI 會讀取這個文件以確定如何打包項目。

在我的示例項目中,我有一個 Python Lambda 函數,用于對餐食執行基本的創建、讀取、更新、刪除(CRUD)操作。這是我項目中的文件:serverless.yml。

service: building-an-api-with-serverless
variablesResolutionMode: 20210326

frameworkVersion: ">=1.1.0 <=2.33.1"
configValidationMode: error
provider:
name: aws
region: us-east-1
runtime: python3.8
stage: prod
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
apiGateway:
shouldStartNameWithService: true
lambdaHashingVersion: 20201221

functions:
createMeals:
handler: meals/create.create
events:
- http:
path: meals/create
method: post
cors: true

listMeals:
handler: meals/list.list
events:
- http:
path: meals/list
method: get
cors: true

getMeals:
handler: meals/get.get
events:
- http:
path: meals/get
method: post
cors: true

updateMeals:
handler: meals/update.update
events:
- http:
path: meals/update
method: put
cors: true

deleteMeals:
handler: meals/delete.delete
events:
- http:
path: meals/delete
method: delete
cors: true
authorizer: ${self:provider.environment.LAMBDA_AUTHORIZER}

resources:
Resources:
MealsDynamoDBTable:
Type: "AWS::DynamoDB::Table"
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: username
AttributeType: S
KeySchema:
- AttributeName: username
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}

讓我們看看它的結構如何。

第一部分是為其提供一個帶有變量解析設置的服務名稱(讓 CLI 知道如何解析變量名稱):

service: building-an-api-with-serverless
variablesResolutionMode: 20210326

第二部分定義了 lambda 的提供程序、框架(在本例中為 python)以及 IAM 角色語句。這些角色非常重要,因為它們允許 Lambda 在您的 AWS 賬戶中具有與 DynamoDB 交互的權限,以執行 CRUD(創建、讀取、更新和刪除)操作。還有一個環境變量部分,用于定義 Dynamo DB 實例的名稱:

frameworkVersion: ">=1.1.0 <=2.33.1"
configValidationMode: error
provider:
name: aws
region: us-east-1
runtime: python3.8
stage: prod
environment:
DYNAMODB_TABLE: ${self:service}-${opt:stage, self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.DYNAMODB_TABLE}"
apiGateway:
shouldStartNameWithService: true
lambdaHashingVersion: 20201221

接下來,我們將定義構建的 lambda 函數:

functions:
createMeals:
handler: meals/create.create
events:
- http:
path: meals/create
method: post
cors: true

listMeals:
handler: meals/list.list
events:
- http:
path: meals/list
method: get
cors: true

getMeals:
handler: meals/get.get
events:
- http:
path: meals/get
method: post
cors: true

updateMeals:
handler: meals/update.update
events:
- http:
path: meals/update
method: put
cors: true

deleteMeals:
handler: meals/delete.delete
events:
- http:
path: meals/delete
method: delete
cors: true

您是否注意到,這些函數的 YAML 文件的主要作用是命名函數、指定 Lambda 處理程序在項目中的位置,并為函數配置 HTTP 路由和請求方法。如果您允許 CORS:

createMeals:
handler: meals/create.create
events:
- http:
path: meals/create
method: post
cors: true

關于處理程序,如果您注意到它指向 meals/create.py,這是告訴無服務器 CLI 轉到 meals 文件夾并使用其中的 Python 文件。然后在該文件中,它指定了要使用的函數。文件路徑如下所示:meals/create.py

import os
import json
import logging
from meals import decimalencoder
import boto3
import traceback
import time
dynamodb = boto3.resource('dynamodb')

initialMeals = [
{
"day": "0",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "1",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "2",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "3",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "4",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "5",
"breakfast": "",
"lunch": "",
"dinner": ""
},
{
"day": "6",
"breakfast": "",
"lunch": "",
"dinner": ""
}
]

def create(event, context):
response = {}
try:
# select data
data = json.loads(event['body'])
# reference table
table = dynamodb.Table(os.environ['DYNAMODB_TABLE'])

# if username not in body then raise exception
if 'username' not in data:
logging.error("Validation Failed")
raise NameError("username is not provided")

timestamp = int(time.time() * 1000)

# create initial set of meals and then return
item = {
'username': data["username"],
'meals': initialMeals,
'createdAt': timestamp,
'updatedAt': timestamp,
}

# write the todo to the database
table.put_item(Item=item)

response = {
"statusCode": 200,
"headers": {'Access-Control-Allow-Origin': '*'},
"body": json.dumps(item['meals'],
cls=decimalencoder.DecimalEncoder)
}
except NameError as nameError:
nameBody = str("Name error: {0}".format(nameError))
response = {
"statusCode": 500,
"headers": {'Access-Control-Allow-Origin': '*'},
"body": nameBody
}
except:
errorBody = traceback.format_exc()
response = {
"statusCode": 500,
"headers": {'Access-Control-Allow-Origin': '*'},
"body": errorBody
}

return response

關于 CORS,響應包括:

"headers": {'Access-Control-Allow-Origin': '*'},

這樣,響應就可以為任何使用您的 API 的應用程序傳遞一個“印前檢查清單”。當我第一次使用無服務器技術時,我發現解決將 API 連接到我構建的前端應用程序時遇到的各種 CORS 錯誤有些困難。盡管這些信息在無服務器網站上有所記錄,但我認為此配置就是通過 CORS 所需的全部配置。顯然,您也可以將應用程序鎖定到特定域。

yaml 文件的最后一部分是定義資源。您可以在此處定義 DynamoDB 表名稱等內容:

resources:
Resources:
MealsDynamoDBTable:
Type: "AWS::DynamoDB::Table"
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
- AttributeName: username
AttributeType: S
KeySchema:
- AttributeName: username
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.DYNAMODB_TABLE}

構建您的處理程序

因此,為了在 AWS Lambda 中定義處理程序,您可以使用與構建控制臺幾乎相同的方法。我分享了上面的文件:create.py 和 get.py。

import os
import json
import logging
from meals import decimalencoder
import boto3
from boto3.dynamodb.conditions import Key
import traceback
dynamodb = boto3.resource('dynamodb')

def get(event, context):
response = {}
try:
# select data
data = json.loads(event['body'])
# reference table
table = dynamodb.Table(os.environ['DYNAMODB_TABLE'])

# if username not in body then raise exception
if 'username' not in data:
logging.error("Validation Failed")
raise NameError("username is not provided")

result = table.query(
KeyConditionExpression=Key('username').eq(data["username"])
)

response = {
"statusCode": 200,
"headers": { 'Access-Control-Allow-Origin': '*' },
"body": json.dumps(result['Items'],
cls=decimalencoder.DecimalEncoder)
}
except NameError as nameError:
nameBody = str("Name error: {0}".format(nameError))
response = {
"statusCode": 500,
"headers": { 'Access-Control-Allow-Origin': '*' },
"body": nameBody
}
except:
errorBody = traceback.format_exc()
response = {
"statusCode": 500,
"headers": { 'Access-Control-Allow-Origin': '*' },
"body": errorBody
}

return response

如您所見,您定義了一個處理程序,然后由 AWS Lambda 使用。AWS 對此有很好的記錄,因此我不打算在此之后進行太多討論。一般您只需定義處理程序,然后在 severless.yml文件中引用它們。當您準備好部署時,無服務器 CLI 會將它們全部打包并為您部署。

將您的項目部署到 AWS

因此,一旦你已經構建了 API,你就可以繼續部署它。如前所述,Serverless CLI 使用您的 AWS 憑證來部署您的項目。您需要先設置 AWS CLI,然后才能部署項目。完成此操作后,打開一個終端輸入“serverless deploy”并轉到項目運行以查看其運行情況:

創建完項目后,您應該會看到如下所示:

如果您注意到,最后一條消息會為您提供一組與您的函數對應的終端節點。這些終端節點都具有相同的基 URL,因為它們由 AWS API Gateway 托管。所以它們都是單個項目中的路由。

您可以獲取終端節點并將它們與 postman 掛鉤,然后查看結果:

如果您進入 AWS 控制臺,則可以查看創建的內容。以下是 API Gateway 中的路由:

您還可以在 AWS 控制臺的 Cloud Formation 模板中查看堆棧:

當您準備好關閉項目時,您可以返回到項目的終端并運行“serverless remove”,這將刪除已創建的堆棧。

結束語

我非常希望您能喜歡這篇文章,并在此過程中對無服務器框架有所了解。我已經在多個項目中使用了無服務器框架,并獲得了很好的體驗。它的文檔記錄的很詳細,且提供了豐富的示例來幫助您入門。除了我們示例中提到的創建“PRD”環境外,使用無服務器框架還可以實現許多其他酷炫的功能,比如設置定時任務(cron jobs)等。強烈建議您訪問 serverless framework 的官方文檔頁面,那里有更多詳細的信息和指導。

原文鏈接:https://andrewevans.dev/blog/2021-07-09-building-an-api-with-the-serverless-framework/

上一篇:

您可以在一個月內開發的5個反向鏈接審核功能

下一篇:

如何使用Spring AI、React和Docker構建AI聊天機器人
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費