How to Build a File Upload System on AWS with React and a Serverless API | Lambda, S3, API Gateway

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] what's up everyone welcome back to another episode of aws tutorial and today i'll show you how to build a file upload system with react.js and the serverless api in the back end and we're going to host everything on aws so at the end of the tutorial you'll be able to build something that looks like this where you can choose a file that you want to upload and then after you upload that after you choose that you can see the file details and you can just hit upload and then in the back end you can just do whatever you want you can do calculations on the data or you can just add more things to the data or combine the data and then store it in s3 or send it to someone for this tutorial i'm just going to add some text to it and then save it to our sd bucket so after you hit upload it's going to say that the file was uploaded successfully so this is what we're going to build today so without further ado let's get to it all right let's build out the front end system first and in order to create a react.js app you need to have node.js and npm installed in your machine and if you don't have that you can just go to this website and follow the instruction to download that and i think it detects your system here and after you get that installed you can just open a empty folder with vs code and what i'm going to do is i'm just going to do terminal new terminal and then we're going to use npx to create a react.js app and if you don't have npx install you can just do npm install npx like this so what i'm going to do is mpx create react app and then give it a name i just call it file upload system but you can call it whatever you want hit enter i think this is going to take a minute so i'm going to pause the video and then come back all right seems like it's done and it seems like we have an error permission denied oh this one doesn't matter because we're not going to use this file at all and now what we're going to do is we're going to cd into the project and then we're going to do a npm start to make sure that it's working first okay seems like it's working so now let's go back to vs code do a ctrl c and then we're gonna first delete the files that we don't need uh just for simplicity sake so we don't need this and then under source we're not going to need this i'm going to do a delete here and then in the index file we're going to delete this and then we don't need that as well and then inside app.js we're gonna delete this and then delete everything here and then we also remove everything here we're going to build everything from scratch so the first thing we're going to do here is we're going to import react and then component from react and now we're going to define app as a class which has a couple of states one is called selected file we're going to instantiate that as null and then we have a property called file uploaded let's say successfully we're going to instantiate that as false and then we're going to have a render function that returns a attack gonna div inside we're gonna have a h2 tag that says and then we're gonna have a h3 tag that says something like and then we're gonna have another div and inside we're gonna have a input that has a type of file because we're gonna upload a file and then on change we're gonna call a function called on file change and then we have a button that allows us to upload the file to our sd bucket and on click we're gonna call a function called file upload we're gonna define them later and the button just gonna label as upload and then finally we're gonna have something that displays the file details we're going to define this function later as well all right first thing we're going to define this function which is an error function that takes in an event and we're just going to do one thing here which is to set the state of the file to be the first one and then we're gonna define this which is also an error function except it doesn't take in any event information we are first going to construct a form data object and then we're gonna append some property to it the first one is just the name uh i'll just call it demo file or something like that and then the second one is the file content which is justified to select the file that we have to find earlier and then the next one is the name of the file select file name like that and next uh what we're going to do next is to call the api to upload the file but since right now we only have the front end we don't have the back end build out yet so we're going to just log out the file information for now from data and then we're gonna set the [Music] selected file to be no back to normal because we already uploaded it and then we're gonna do set the file upload successful to be true and then finally we're going to define this function to display the file data depending on the situation or what state we are at we're going to have a if condition here so the first condition we're going to have is we if we already have a file selected for upload we are going to display the file detail tool to the user uh just to tell them what he or she has already uploaded to the system or selected to be uploaded to the system right here we're going to have a h2 tag that says bio details and then we're gonna have a paragraph that shows the file name and we can get that from the selected file name and then we can show them what type of file that is type then lastly we're gonna have a last modified timestamp and we're going to get that from the selected file as well last modify to date string and let's instantiate that to take in an empty string if it doesn't have it and then we have a second condition that checks so if the file is uploaded successfully we're going to show the user a message now let's just have a break here we're going to have a h4 tag here and then we're going to tell the user that the file has been successfully uploaded oh i think i forgot to return here that should do it and then lastly if the user does not select anything or it has not uploaded anything we were just going to return something or a message called something like that um okay so i think that's everything and now let's test it and see if it's working okay seems like everything is working properly let's move everything to the middle so that it looks better so in the [Music] in here let's just call that container and then in the app.css file we're going to do text align center go to refresh and now everything is in the middle so it looks good and it tells us to choose a file and then press the upload button to upload and now let's create a dummy file for us to test everything so i'm just gonna do like a test text file let's say something like this is just a test file do an inspect on it first click on the console and then we're going to choose the file that we just created so hit choose file and then navigate to the directory and that's the file that we just created so hit select oh that's an error let's see what happened oh files not file now should be fine let's refresh it click choose file let's try one more time oh man another error let's see what that is last modified i think it should be last modified date okay uh let's refresh and upload it again and hopefully this time works all right there you go now we can get all the information here and if i do upload it's going to show me that your file has been successfully uploaded okay so now the front end is working and now let's move on to build out the backend system all right so right now i'm on the home page of the aws console so step number one is to create the imrove the lambda function to use for the api so i'm going to type in iam and then hit rows and then create row we're going to choose lambda because the lambda function is going to use it hit next we are going to attach two policies to it one is the s3 full access and then the other one is cloudwatch log flow access so i'm going to type in s3 full access click that and then cloud watch log full access and then hit next next give it a name i just call it file upload system well hit create all right so it's done and now let's create a lambda function so go to the lambda console hit create give it a name i'll just call it file upload system back end we're going to use node.js for permission we're going to choose the row that we just created i believe it's that one and then hit create so before i do anything i'm going to change two things here one is the timeout and the other one is the memory uh just in case the file is too big for it to process so i'm going to click on configure general and then i'm going to change that to be one minute and 500 megabytes should be enough and then hit save and then next we're going to create a s3 bucket to host or to store our files after we upload it so i'm just going to type s3 hit create bucket i just call it gene meister file upload storage enable versioning and then enable server side encryption uh hit create all right so it's done so we're going to use that to store our files after the user uploads it and then next we're going to create the api gateway for our api so i'm just going to type in api gateway and then we're going to scroll down make sure that you select restful api rest api here because that's what we're going to use for the tutorial so let's click on build here hit ok new api i'll just call it file upload system api i keep it as original create api so for this tutorial i'm just going to focus on the implementation of it i have a separate video that talks about serverless api and everything you need to know about uh using the api gateway authentications and stuff like that i'll include the link down below so if you're interested you can check that out first thing first we are going to create a resource we're going to call it maybe file upload and then make sure that you enable course and then create resource and then inside here we're going to create a method which is a post method it's a check mark and then we're going to use the lambda function make sure you check the proxy integration here so that it gives you all the default default properties and then we're going to choose the lambda function that we just created i believe it's that one we're just gonna use the default timeout hit save hit okay so normally you're gonna have a health check endpoint here to test out your api but for simplicity i'm just gonna have only one endpoint here to test things out another thing i want to mention is that this api gateway right now is open to the world so anyone can access it so if your api is is going to be in production you may want to use the api keys to restrict access and require people to authenticate i have a separate videos for that i'll include a link down below so you can check that out if you're interested so what i'm going to do here is i'm just going to promote that to the production so deploy api let's call it prod deploy and that's our endpoint and before we do anything let's go back to the lambda function to write out the code for our api so hit on code so for this tutorial i'm just going to write everything in the in the lambda console because i don't require any external libraries or anything so i'm going to delete everything here first thing first we're going to do some imports so the first one is the file processing service we're going to define this file later and then the second one is a util function or a u2 file we're going to define it later as well and then we're going to have a constant that is the path which is what we define in our api gateway file upload and then in the handler the first thing we're going to do is we're going to do a console.log just to lock out the request event just to see how it looks like and then we're going to define a response and then we're going to have a switch statement we're going to have it as true and then we're going to have a case switch then we're going to check the http method to see if it's a post and then the path is equal to our file upload path if that matches we're going to set the response to be this we're going to define this method later i'm just going to take the body and then we're going to do a break and then for everything else we will just gonna set the response to be [Music] we're gonna define this function later as well 404 and then finally we're going to return the response to the client oh there's a typo okay that should be well it's a lot of typos here okay now let's define this file in the root directory so the first thing we're going to do is we're going to define the aws parameter just going to use the aws sdk and then we're going to define an s3 client and then we're going to use the util library that we're going to define later and then we're gonna define the bucket name and i think we can just copy this and then for the subfolder uh we can just call it data maybe and then we're gonna have a async function called process that takes in a request body and then we're going to pass the file name from the request body before we do anything here let me just show you how request body looks like so remember here we have the event object and then we just pass in the body from the event object and this is how the event body looks like or event object looks like it has the source it has the path and http method and stuff and then all the way at the end it has the body which is a string and since we use the data form to upload it it has it automatically added the boundary text text here and we don't want that we just want the file name and the file content so we need to think of a way to parse it so let's go back to the lambda function and i already have this written down before so i'm just going to copy and paste it so what it does here is it it will split everything by the new line and then select that and split everything by the semicolon and then by the equal sign and then remove the quote from the name get the file name and then next we're going to extract the file content and i already have that written down before as well so i'm just gonna copy and paste it and then now we can just do some modifications to the file content you can do calculations on it you can do um additions of text to it as well and what i'm going to do here is i'm just going to add the timestamp to it to the end of the the file content so i need to do file content i need to change that to let because i'm modifying it um first thing i'm going to do is i'm going to add two new lines to it and then i'm going to say process timestamp and then i'm going to do new date to iso string and the next we're going to define the param that we're going to use to save the file first thing is the bucket bucket name key we're gonna do the subfolder first and then do a slash and then we're gonna do the file name and the next we have the body which is the file content and that should do it oh there's a typo here new date not new data and then next we're going to do in a weight s3 then put object parens and then we're going to do a just do a promise and then finally we're going to return a 200 back to the client and that should be everything and now we're going to define this helper function a helper file dot js all right this one is pretty simple we're only going to have one function here that takes in the status code and then the body if it has anything which is optional it will just return a status code to be status code and then the headers so this is very important make sure that you have this otherwise it's not going to allow your client to request the endpoint origin set that to be start content type application json and then we're just gonna do a stringify on the body which is optional you don't have to have it and then lastly we're gonna export this function oh i think we forgot to do it here module dot x what process to be processed okay that should be everything and now let's deploy it and now i think we can just go back to the front end and tell the client to call the api so let's go to api gateway stages right let's copy this endpoint then go back to the front end so in here call api so what we can do is we can just use axio to do a post on the api but before we do that we need to add the module so let's go to package.json and then let's add it here axio and then specify a version number and i think that's what we're going to use and then in the app.js we're going to import that axios from axios and then here we're just going to do a post copy this fix the space and then we have file upload i think let's see yep file upload and then we're going to pass in the form data as to request body and then we're going to do a dot then which is a an arrow function and we can just move everything to the inside and we don't need this all right so i think that's done but before we can test it we need to do a npm installed to install the axio module okay so that is done and now we can do it npm start to test it locally all right let's choose a file choose the same file that one hit open and then hit upload now your file was successfully uploaded and now if we go back to the s3 bucket we should be able to see the file and let's download that just to take a look to see how it looks like all right so it contains all the contents we have written down uh plus the time stamp that we just added uh from the lambda function or the api all right so everything's working locally now and now let's create a separate sd bucket that hosts our front end so that we have a web page so let's go back to s3 great bucket i just call it dream meister file upload system finance i'm gonna uncheck this to allow public access to read it you check this enable enable hit create and let's click into it and under permissions scroll all the way down in bucket policy we're gonna add something here and i can just go to gmeister.com s3 scroll all the way down and then we're gonna we're gonna copy this one thing we need to do is we need to change this art to be this hit save unexpected error oh there's a space here okay how about now okay so that is done and then one last thing we have to do is under properties scroll all the way down here under static website hosting made edit hit enable and then we're gonna do index.html and do the same thing here hit save okay and now we are ready to build out the front end and upload the necessary files to the bucket for website hosting so i'm gonna go back to vs code hit ctrl c and then i'm gonna do npm run build all right so it's done so it basically creates a file or folder called built and it contains all the necessary files that we need for for website hosting so i'm going to go back to the s3 bucket and then upload everything in this folder so hit here upload add files inside builds open and then we're gonna upload a folder remember when we select upload file we only uploaded this file we need to upload this folder as well so i hit upload hit yes okay so everything is there now let's get the website uil go all the way to the bottom and this is our website url so if i go to a new tab paste it here we should see our file upload system and one thing you may notice is that this is unsecured which means it's not https i have a separate video that i talked about how to make the website secure to use https so if you're interested you can check out the link down below except but for now i just leave it as is and before we do a file upload let's delete the one that we already have in our sd bucket first so click here let's hit delete so it's empty and now if i do choose file and then select the test file that we created earlier hit open it's still working hit upload and that is working and now if i go back to the s3 bucket hit refresh i should be able to see the data folder and inside that i should have a test.txt file and let me just download that just to take a look what is inside and it has the same content except the timestamp is different and this is it everyone i hope you have learned something and if you like this video i hope you can give it a thumbs up and i'll see you in the next video
Info
Channel: Felix Yu
Views: 1,563
Rating: undefined out of 5
Keywords: aws, file upload system, serverless api, lambda, api gateway, react, react.js, node.js, s3
Id: IgAE-ycnb94
Channel Id: undefined
Length: 31min 24sec (1884 seconds)
Published: Thu Sep 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.