使用 DynamoDB 的 API 服务器
在本教程中,让我们看看如何使用它来构建一个小型 API,该 API 具有用于插入和检索信息的端点,并由 DynamoDB 支持。
本教程假设您拥有 AWS 和 Deno Deploy 帐户。
概述 跳转到标题
我们将构建一个 API,它只有一个端点,接受 GET/POST 请求并返回相应的信息
# A GET request to the endpoint should return the details of the song based on its title.
GET /songs?title=Song%20Title # '%20' == space
# response
{
title: "Song Title"
artist: "Someone"
album: "Something",
released: "1970",
genres: "country rap",
}
# A POST request to the endpoint should insert the song details.
POST /songs
# post request body
{
title: "A New Title"
artist: "Someone New"
album: "Something New",
released: "2020",
genres: "country rap",
}
设置 DynamoDB 跳转到标题
我们过程中的第一步是生成 AWS 凭据以以编程方式访问 DynamoDB。
生成凭据
- 转到 https://console.aws.amazon.com/iam/ 并转到“用户”部分。
- 单击**创建用户**按钮,填写**用户名**字段(可以使用
denamo
),然后选择**程序访问**类型。 - 单击**下一步**
- 选择**直接附加策略**并搜索
AmazonDynamoDBFullAccess
。选中结果中此策略旁边的框。 - 单击**下一步**和**创建用户**
- 在生成的**用户**页面上,单击您刚刚创建的用户。
- 单击**创建访问密钥**
- 选择**在 AWS 外部运行的应用程序**
- 单击*创建*
- 单击**下载 .csv 文件**以下载您刚刚创建的凭据。
创建数据库表
- 转到 https://console.aws.amazon.com/dynamodb 并单击**创建表**按钮。
- 在 **表名** 字段中填写
songs
,在 **分区键** 字段中填写title
。 - 向下滚动并点击 **创建表**。
- 创建表后,点击表名并找到 **常规信息**。
- 在 **Amazon 资源名称 (ARN)** 下,记下新表的区域(例如 us-east-1)。
编写应用程序 跳转到标题
创建一个名为 index.js
的文件并插入以下内容
import {
json,
serve,
validateRequest,
} from "http://land.deno.org.cn/x/[email protected]/mod.ts";
// AWS has an official SDK that works with browsers. As most Deno Deploy's
// APIs are similar to browser's, the same SDK works with Deno Deploy.
// So we import the SDK along with some classes required to insert and
// retrieve data.
import {
DynamoDBClient,
GetItemCommand,
PutItemCommand,
} from "https://esm.sh/@aws-sdk/client-dynamodb";
// Create a client instance by providing your region information.
// The credentials are obtained from environment variables which
// we set during our project creation step on Deno Deploy.
const client = new DynamoDBClient({
region: Deno.env.get("AWS_TABLE_REGION"),
credentials: {
accessKeyId: Deno.env.get("AWS_ACCESS_KEY_ID"),
secretAccessKey: Deno.env.get("AWS_SECRET_ACCESS_KEY"),
},
});
serve({
"/songs": handleRequest,
});
async function handleRequest(request) {
// The endpoint allows GET and POST request. A parameter named "title"
// for a GET request to be processed. And body with the fields defined
// below are required to process POST request.
// validateRequest ensures that the provided terms are met by the request.
const { error, body } = await validateRequest(request, {
GET: {
params: ["title"],
},
POST: {
body: ["title", "artist", "album", "released", "genres"],
},
});
if (error) {
return json({ error: error.message }, { status: error.status });
}
// Handle POST request.
if (request.method === "POST") {
try {
// When we want to interact with DynamoDB, we send a command using the client
// instance. Here we are sending a PutItemCommand to insert the data from the
// request.
const {
$metadata: { httpStatusCode },
} = await client.send(
new PutItemCommand({
TableName: "songs",
Item: {
// Here 'S' implies that the value is of type string
// and 'N' implies a number.
title: { S: body.title },
artist: { S: body.artist },
album: { S: body.album },
released: { N: body.released },
genres: { S: body.genres },
},
}),
);
// On a successful put item request, dynamo returns a 200 status code (weird).
// So we test status code to verify if the data has been inserted and respond
// with the data provided by the request as a confirmation.
if (httpStatusCode === 200) {
return json({ ...body }, { status: 201 });
}
} catch (error) {
// If something goes wrong while making the request, we log
// the error for our reference.
console.log(error);
}
// If the execution reaches here it implies that the insertion wasn't successful.
return json({ error: "couldn't insert data" }, { status: 500 });
}
// Handle GET request.
try {
// We grab the title form the request and send a GetItemCommand
// to retrieve the information about the song.
const { searchParams } = new URL(request.url);
const { Item } = await client.send(
new GetItemCommand({
TableName: "songs",
Key: {
title: { S: searchParams.get("title") },
},
}),
);
// The Item property contains all the data, so if it's not undefined,
// we proceed to returning the information about the title
if (Item) {
return json({
title: Item.title.S,
artist: Item.artist.S,
album: Item.album.S,
released: Item.released.S,
genres: Item.genres.S,
});
}
} catch (error) {
console.log(error);
}
// We might reach here if an error is thrown during the request to database
// or if the Item is not found in the database.
// We reflect both conditions with a general message.
return json(
{
message: "couldn't find the title",
},
{ status: 404 },
);
}
在您的新项目中初始化 git 并 推送到 GitHub。
部署应用程序 跳转到标题
现在我们已经准备就绪,让我们部署您的新应用程序!
- 在您的浏览器中,访问 Deno Deploy 并链接您的 GitHub 帐户。
- 选择包含您的新应用程序的仓库。
- 您可以为您的项目命名,也可以让 Deno 为您生成一个名称。
- 在入口点下拉菜单中选择
index.js
- 点击 **部署项目**
为了使您的应用程序正常工作,我们需要配置其环境变量。
在您的项目成功页面或项目仪表盘中,点击 **添加环境变量**。在环境变量下,点击 **+ 添加变量**。创建以下变量
AWS_ACCESS_KEY_ID
- 使用您从 CSV 文件中下载的值AWS_SECRET_ACCESS_KEY
- 使用您从 CSV 文件中下载的值。AWS_TABLE_REGION
- 使用您的表的区域
点击保存变量。
让我们测试 API。
POST 一些数据。
curl --request POST --data \
'{"title": "Old Town Road", "artist": "Lil Nas X", "album": "7", "released": "2019", "genres": "Country rap, Pop"}' \
--dump-header - https://<project_name>.deno.dev/songs
GET 关于标题的信息。
curl https://<project_name>.deno.dev/songs?title=Old%20Town%20Road
恭喜您学习了如何使用 Deno Deploy 与 DynamoDB!