如何获取谷歌新闻API密钥(分步指南)
使用Serverless Framework构建API
在构建 API 时,您有多种选择。无服务器框架提供了一个很好的工具集,可以自动执行该过程。
在这篇文章中,我将演练如何使用 severless 框架在 python 中构建meal planning API。这个API将托管在AWS上,并使用DynamoDB进行数据存储。我会使用一个示例项目,您可以在我的GitHub仓库中找到它,只需执行git clone命令即可开始操作。
什么是 Serverless Framework?
无服务器框架可以在 serverless.com 中找到。它与主要云提供商(包括 AWS)合作,提供自动化构建和部署无服务器基础设施的方法。通过使用 CLI 来构建和打包项目。如果您已经安装 了AWS CLI,无服务器 CLI 将利用这些凭证与 AWS 通信。当您进行部署时,无服务器 CLI 将使用 Cloud Formation 模板创建一个“堆栈”,这些模板基于代码构建您的项目。更新时,堆栈也会同步更新。
对于 Lambda,无服务器框架将利用 AWS API Gateway 和 Lambda 函数来创建无服务器 API。
开始使用时,您只需安装 serverless framework CLI。在 Mac 上,您可以执行以下操作:
curl -o- -L https://slss.io/install | bash
安装 CLI 后,只需打开终端并运行“serverless
”,然后按照屏幕上的提示进行操作。
您可以将 CLI 用于大多数任务,也可以使用无服务器账户来执行更多其他的功能。
无服务器项目是什么样子的
在构建 Serverless 项目时,您可以选择搭建自己的基架或使用快速入门模板。我发现从示例开始更容易。如果您想查看所有示例,请在 https://github.com/serverless/examples 上查看。
正如我在简介中提到的,我创建了一个示例项目来展示其工作原理。我的项目最初是一个示例项目,我只是在构建应用程序时对其进行了修改。
基本项目结构需要两个文件:package.json
和 serverless.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/