#✅ - How to get the name of the S3 bucket created by the backend to the frontend

4 messages · Page 1 of 1 (latest)

rich geyser
#

I need to store the name of the S3 bucket created during the backend deployment together with other file data to the data schema when users are uploading data from the frontend. What is the best strategy to pass the S3 bucket name from the backend to the frontend. I crafted this solution but I was wondering if there woudl be a better way....

1st) Create the function
amplify/data/get-s3-bucket/resource.ts

import { defineFunction } from '@aws-amplify/backend'
import dotenv from 'dotenv'
import 'dotenv/config'
dotenv.config()

export const getS3Bucket = defineFunction({
  name: 'get-s3-bucket',
  environment: {
    BUCKET_PREFIX: process.env.BUCKET_PREFIX || 'defaultPrefix',
  },
})

2nd) Attached the function to the storage resource
amplify/storage/resource.ts

import { defineStorage } from '@aws-amplify/backend'
import { getS3Bucket } from '../data/get-s3-bucket/resource'
import dotenv from 'dotenv'
import 'dotenv/config'
dotenv.config()

const path = ` ${process.env.SAMPLE_FILE_DIR}/*`

export const storage = defineStorage({
  name: process.env.BUCKET_PREFIX || 'DEFAULT_NAME',
  access: (allow) => ({
    [path]: [
      allow.groups(['ADMINS', 'MANAGERS']).to(['read', 'write', 'delete']),
      allow.authenticated.to(['read', 'write']),
      allow.resource(getS3Bucket).to(['read']),
    ],
  }),
})

3rd) Create a query in the data backend
amplify/data/resource.ts

import { type ClientSchema, a, defineData } from '@aws-amplify/backend'
import { getS3Bucket } from './get-s3-bucket/resource'

const schema = a.schema({
  getS3Bucket: a
    .query()
    .authorization((allow) => [allow.authenticated()])
    .handler(a.handler.function(getS3Bucket))
    .returns(a.json()),
})

export type Schema = ClientSchema<typeof schema>

export const data = defineData({
  schema,
  authorizationModes: {
    defaultAuthorizationMode: 'userPool',
  },
})

4th) Create the Handler
amplify/data/get-s3-bucket/resource.ts

import type { Schema } from '../resource'
import { env } from '$amplify/env/get-s3-bucket'

type Handler = Schema['getS3Bucket']['functionHandler']
const bucket = `${env.BUCKET_PREFIX}_BUCKET_NAME`

export const handler: Handler = async () => {
  return env[bucket as keyof typeof env]
}

5th) Finally call the function from the front end

import type { Schema } from '@amplify/data/resource'
import { generateClient } from 'aws-amplify/data'
const client = generateClient<Schema>()

const { data: s3bucket } = await client.queries.getS3Bucket()

Is there a simpler strategy or this is sound and good?

Thanks for the comments

serene sparrow
#

You can access information about your backend resources in your frontend using the amplify_outputs.json file automatically created on every backend deployment.
In there you'll find a storage section containing the S3 bucket name:

  "storage": {
    "aws_region": "eu-central-1",
    "bucket_name": "amplify-xxx-xxx-xxx6cbfaeh5-g04jevghbggs"
  },

You can find more information about the amplify_outputs.json file here:
https://docs.amplify.aws/javascript/reference/amplify_outputs/

rich geyser
#

Of course! Thanks for the pointer!

tardy echoBOT
#

✅ - How to get the name of the S3 bucket created by the backend to the frontend