AWS Amplify: How to upload files to S3 using GraphQL API in React

AWS Amplify: How to upload files to S3 using GraphQL API in React

ยท

4 min read

AWS gives a kind of superpower for frontend developers where they can use a variety of its services like Cognito for authentication, DynamoDB for storing structured data, S3 Storage for files, etc.

When it comes to AWS Amplify it not only gives superpower but also makes the life of developers easier. AWS Amplify is a set of purpose-built tools and services that makes it quick and easy to make full-stack applications.

So in this blog, we will focus on how we can upload an image and store it in AWS S3, and retrieve it back using a GraphQL API.

So first step is having a react app so you can create a react app by following the command

npx create-react-app demoapp

We have then set up the Amplify in the project for that we must install CLI and other react libraries so you can go through the official docs to set it up Amplify Setup. Since it was already explained well enough in the official docs.

After setting it up now it's time to add the s3 storage and graphQL API into the react app.

We'll first add s3 storage to our project we can do it by running the following command on the terminal.

amplify add storage

Screenshot 2021-10-21 at 1.13.20 AM.png

After adding the storage you have to push it by running the following command

amplify push --y

This will create an instance of S3 in your AWS console and you can verify it by going to your AWS console and searching the S3 storage inside which you will find the storage you created for this app.

Now let create the API through which we will talk to the S3. For creating the GraphQL, you guessed it right we can use the following command.

amplify add api

You have to select GraphQL since we will be the writing schema for it. You can go through the following Image to select the appropriate options.

Screenshot 2021-10-21 at 1.30.42 AM.png

After going through the options you will see that there will be api folder created inside which there will be schema.graphql.

Once done open the schema.graphql file and delete everything inside we will write our own schema.

type S3Object {
  bucket : String!
  region : String!
  key : String!
} 

type Picture @model {
  id : ID!
  name: String
  file : S3Object
}

So going through a quick summary Picture is the model we created inside which we an id of type ID! exclamatory means that it is required, the ID means it will be generated automatically, the name field will hold the file which we will upload of type string and finally, the actual file which will be stored in S3 type will be an S3object that contained bucket id, regions, and key which is required while accessing the file.

Once we add the schema we need to push it by running the command.

amplify push --y

Now our backend job is done let's jump into react app and try to upload an image.

import React,{useState} from "react"
import { Storage, API, graphqlOperation} from 'aws-amplify';

import awsmobile from '../aws-exports';
import { createPicture } from "../graphql/mutations";

const Upload = () => {

  const [imagefile, setImagefile] = useState()

  const addToDatabase = async(image) => {
    try{
        await API.graphql(graphqlOperation(createPicture,{input: image}))
    }
    catch(err){
      console.log(err);
    }
  }

  const onChangeHandler = (e) => {
    console.log(e);
    const file = e.target.files[0]
    console.log(file.name);
    Storage.put(file.name, file,{
      contentType: "image/png"
    }).then((result) => {
      console.log(result);
      setImagefile(URL.createObjectURL(file))
      const image  = {
        filename : file.name,
        file :{ 
            bucket: awsmobile.aws_user_files_s3_bucket,
            region: awsmobile.aws_user_files_s3_bucket_region,
            key: file.name
        }
      }
      addToDatabase(image)
      console.log("Added Completed");
    })
  }
  console.log(imagefile);
  return (
    <div className="App">
        <h3>AWS Amplify S3 Demo</h3>
        <input type="file" onChange={onChangeHandler}/>
        <div>
          <img src={imagefile} />
        </div>
    </div>
  );
}

export default Upload

The above snippet is an Upload component where we first take the input type file and put it into the s3 storage.

Once done we need to store the reference in our DynamoDb as well so that we can access it easily later so we call our graphQL API which saves the details in DynamoDB, So now if we want the image we can call the GraphQL API itself.

And in App.js we call the Upload component as below.

import React from "react"
import Amplify from "aws-amplify";
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react';

import awsExports from "./aws-exports";
import './App.css';
import Upload from "./components/Upload";

Amplify.configure(awsExports);

function App() {
  return (
    <div className="App">
      <AmplifySignOut />
        <Upload/>
    </div>
  );
}

export default withAuthenticator(App);

s3blog.gif

Voila..!! Now we can add files to S3 Storage and also retrieve them using GraphQL API.

So I assume you might have got a hold on how to upload and save the file in S3 also how to create a graphQL API in aws amplify.

Let's meet in the next blog with some other interesting topics. Until then

Happy Codding..!!๐Ÿ™Œ๐Ÿฝ

Did you find this article valuable?

Support Vishak Amin by becoming a sponsor. Any amount is appreciated!

ย