deno.com
本页内容

使用 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。

生成凭证

  1. 访问 https://console.aws.amazon.com/iam/ 并进入“用户”部分。
  2. 点击“创建用户”按钮,填写“用户名”字段(可以使用 denamo),并选择“编程访问”类型。
  3. 点击“下一步
  4. 选择“直接附加策略”并搜索 AmazonDynamoDBFullAccess。在结果中勾选此策略旁边的复选框。
  5. 点击“下一步”和“创建用户
  6. 在显示的“用户”页面上,点击您刚刚创建的用户。
  7. 点击“创建访问密钥
  8. 选择“在 AWS 外部运行的应用程序
  9. 点击“创建
  10. 点击“下载 .csv 文件”以下载您刚刚创建的凭证。

创建数据库表

  1. 访问 https://console.aws.amazon.com/dynamodb 并点击“创建表”按钮。
  2. 将“表名”字段填写为 songs,将“分区键”填写为 title
  3. 向下滚动并点击“创建表”。
  4. 表创建成功后,点击表名,查找其“常规信息”。
  5. 在“Amazon 资源名称 (ARN)”下,记下您的新表的区域(例如 us-east-1)。

编写应用程序 跳转到标题

创建一个名为 index.js 的文件并插入以下内容

import {
  json,
  serve,
  validateRequest,
} from "https://deno.land/x/sift@0.6.0/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

部署应用程序 跳转到标题

现在一切就绪,让我们部署您的新应用程序吧!

  1. 在浏览器中,访问 Deno Deploy 并关联您的 GitHub 账户。
  2. 选择包含您新应用程序的存储库。
  3. 您可以为项目命名,或者让 Deno 为您生成一个
  4. 在“入口点”下拉菜单中选择 index.js
  5. 点击“部署项目

为了使您的应用程序正常工作,我们需要配置其环境变量。

在项目成功页面或项目仪表板中,点击“添加环境变量”。在“环境变量”下,点击“+ 添加变量”。创建以下变量:

  1. AWS_ACCESS_KEY_ID - 填写您下载的 CSV 文件中的值
  2. AWS_SECRET_ACCESS_KEY - 填写您下载的 CSV 文件中的值。
  3. 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!

您找到所需内容了吗?

隐私政策