Created
August 12, 2021 08:02
-
-
Save leegilmorecode/7d444d11475a2202da4e26c33559a13a to your computer and use it in GitHub Desktop.
Example code for generating a pre-signed download URL using AWS S3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import AWS from 'aws-sdk'; | |
| import { APIGatewayProxyHandler, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda'; | |
| import { v4 as uuid } from 'uuid'; | |
| import config from '../../config'; | |
| type HeadObjectRequest = AWS.S3.HeadObjectRequest; | |
| type HeadObjectOutput = AWS.S3.HeadObjectOutput; | |
| const METHOD = 'get-file.handler'; | |
| const s3 = new AWS.S3(); | |
| export const handler: APIGatewayProxyHandler = async ({ | |
| pathParameters, | |
| }: APIGatewayEvent): Promise<APIGatewayProxyResult> => { | |
| try { | |
| const correlationId = uuid(); | |
| console.log(`${correlationId} - ${METHOD} - started`); | |
| // basic validation to check id exists - in reality the path parameter check would | |
| // happen using an approach like json schema validation | |
| if (!pathParameters?.id) throw new Error('path parameter id does not exist'); | |
| const { id } = pathParameters; | |
| const imageName = `${id}.png`; | |
| console.log(`${correlationId} - ${METHOD} - bucket: ${config.bucket}, file: ${imageName}`); | |
| const headRequest: HeadObjectRequest = { | |
| Bucket: config.bucket, | |
| Key: `${imageName}`, | |
| }; | |
| // check if the image exists in the s3 bucket | |
| const exists: HeadObjectOutput = await s3.headObject(headRequest).promise(); | |
| console.log(`${correlationId} - ${METHOD} - file exists with last modified date: ${exists.LastModified}`); | |
| // create an s3 pre-signed download url for the image if it exists | |
| const url = s3.getSignedUrl('getObject', { | |
| Bucket: config.bucket, | |
| Key: `${imageName}`, | |
| Expires: 60, | |
| }); | |
| // you would NEVER log this but we are doing it for clarity of logs for the demo | |
| console.log(`${correlationId} - ${METHOD} - generated url: ${url}`); | |
| return { | |
| statusCode: 200, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify( | |
| { | |
| url, | |
| }, | |
| null, | |
| 2, | |
| ), | |
| }; | |
| } catch (error: any) { | |
| console.error(`${METHOD} - error: ${JSON.stringify(error)}`); | |
| let statusCode = 500; | |
| let errorMessage = 'An error has occurred'; | |
| // check if the error is for an image which does not exist | |
| // and return an appropriate message and status code | |
| if (error.code === 'Forbidden') { | |
| statusCode = 404; | |
| errorMessage = 'Image does not exist'; | |
| } | |
| // return a generic error otherwise | |
| return { | |
| statusCode, | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| }, | |
| body: JSON.stringify(errorMessage, null, 2), | |
| }; | |
| } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment