---
title: "Custom policies in code, archiving requests to S3 for replay later"
description: "Learn how easily archive every API request to AWS's S3 storage. Archive your API requests to replay them later."
canonicalUrl: "https://zuplo.com/blog/2022/03/22/custom-policies-in-code-archiving-requests-to-s3"
pageType: "blog"
date: "2022-03-22"
authors: "josh"
tags: "Amazon Web Services (AWS), Tutorial"
image: "https://zuplo.com/og?text=Custom%20policies%20in%20code,%20archiving%20requests%20to%20S3%20for%20replay%20later"
---
One of my favorite features of Zuplo is the ability to build custom policies.
Here we create a custom policy to archive every request to Amazon's S3 storage.

<YouTubeVideo videoId="YqcLu0cXNfE" />

Length: 3 minutes

Here's the code in our `archive-request.ts` module:

```ts
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

type MyPolicyOptionsType = {
  myOption: any;
};
export default async function (
  request: ZuploRequest,
  context: ZuploContext,
  options: MyPolicyOptionsType,
  policyName: string,
) {
  context.log.info(environment.AWS_SECRET_ACCESS_KEY);

  const s3Client = new S3Client({ region: "us-east-2" });
  const file = `${Date.now()}-${crypto.randomUUID()}.req.txt`;

  const clone = request.clone();

  const uploadParams = {
    Bucket: "request-storage",
    Key: file,
    Body: await clone.text(),
  };

  const data = await s3Client.send(new PutObjectCommand(uploadParams));

  return request;
}
```

Note, the code above will update S3 in serial with invoking your API, which will
increase the latency of your API. However, you can also do this asynchronously,
as follows:

```ts
import { ZuploContext, ZuploRequest, environment } from "@zuplo/runtime";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

type MyPolicyOptionsType = {
  myOption: any;
};
export default async function (
  request: ZuploRequest,
  context: ZuploContext,
  options: MyPolicyOptionsType,
  policyName: string,
) {
  context.log.info(environment.AWS_SECRET_ACCESS_KEY);

  const s3Client = new S3Client({ region: "us-east-2" });
  const file = `${Date.now()}-${crypto.randomUUID()}.req.txt`;

  const clone = request.clone();

  const uploadParams = {
    Bucket: "request-storage",
    Key: file,
    Body: await clone.text(),
  };

  const dataPromise = s3Client.send(new PutObjectCommand(uploadParams));
  // This tells the runtime to not shutdown until that promise is complete
  context.waitUntil(dataPromise);

  return request;
}
```