Spring Boot, React.js & AWS S3 Full Stack Development
Aug 16, 2023
Spring Boot, React.js & AWS S3 Full Stack Development
In this spring boot tutorial you’ll learn how to create a spring boot project for a full-stack application with React.js that enables users to upload files to Amazon S3 with ease. Follow along as we dive into the integration of React.js on the frontend and Spring Boot 3 on the backend to create a restful API that enabling file uploads. By the end of this tutorial, you’ll have the knowledge to develop your own file uploading functionality in your next project, and take advantage of the power of AWS S3 for your application’s storage needs. ▷ Enrol for certificate - bit.ly/41PG7iZ ▷ Follow Me on LinkedIn - https://bit.ly/3Nqrpuy ▷ Join Amigoscode LinkedIn Group - https://bit.ly/44snIKX ▷ Join Amigoscode Discord - https://bit.ly/3Llkf7T ▷ Repo - https://bit.ly/41O3OYN Don’t Forget to =========================================== 💯 Subscribe to Amigoscode - http://bit.ly/2HpF5V8 💯 Courses Available for free here - https://amigoscode.com/courses 💯 Join Private Facebook Group and Discord - https://amigoscode.com/p/join-community 🙊 Here are the goods for all my videos video 🙊 ► Recommended Books =========================================== - Clean Code - https://amzn.to/2UGDPlX - HTTP: The Definitive Guide - https://amzn.to/2JDVi8s - Clean Architecture - https://amzn.to/2xOBNXW ► Computer and Monitor =========================================== - New Apple MacBook Pro - https://amzn.to/3464Mmn - Dell 27 INCH Ultrasharp U2719D Monitor - https://amzn.to/2xM3nW1 - Double Arm Stand Desk Mount - https://amzn.to/3aYKKfs - USB C Hub Multiport Adapter - https://amzn.to/2Jz7NlL ► Camera Gear ============================================= - Sony ILCE7M3B Full Frame Mirrorless Camera - https://amzn.to/346QIJn - Sigma 16 mm F1.4 DC DN - https://amzn.to/2wbic3Q - Sigma 33B965 30 mm F1.4 DC DC - https://amzn.to/39G37Fd ► IDE \u0026 Tools I use for coding 💻 🎒 =========================================== - ITerm - VsCode - GoLand - IntelliJ Ultimate - Sublime P.S =========================================== 💯 Don’t forget to subscribe | http://bit.ly/2HpF5V8 💯 Join Private Facebook Group and Discord - https://amigoscode.com/p/join-community 💯 Follow me on Instagram | http://bit.ly/2TSkA9w ❤️ Thanks for watching
Content
0 -> hey what's going on guys welcome to Amigoscode
in this spring boot tutorial I'm going to take you through
7.38 -> the journey of learning how to implement the
functionality of storing files using spring boot
14.88 -> React,js and AWS S3. I've done this video a couple
days ago and I decided to basically re-revamp and
22.5 -> because it's part of the full stack professional
course which is over 60 hours and growing with
28.86 -> new features that you guys have been requesting
so I decided to just revamp the video that I've
36.66 -> done a couple years ago and also if you want
to gain a certificate on the website you can
42.06 -> basically enroll and basically take this crash
course and gain a certificate and this course
48.3 -> is Hands-On so get ready and clone the repo and
yeah I want you to learn something new from this
56.52 -> video if you're new to this channel literally
just take one second and subscribe and also
63.84 -> for all of you guys smash the like button come
on I'll give you one second that's it without
70.44 -> further Ado let's go ahead and learn about spring
boot react AWS and S3 catch me on the next one
84.12 -> in here I've put this diagram together where
you can basically have an idea and see all the
90.66 -> different services that you need within AWS
but basically right here this is our API that
96.96 -> you basically have deployed successfully to an
ec2 instance backed by ECS now the API actually
105.84 -> is running on this ec2 instance and we want to
upload pictures to a bucket so Amazon they have
114.24 -> a service called S3 which basically allows you
to store files now before you can upload files
121.8 -> you need to basically configure the row so the
role that is called AWS elastic Beanstalk EC2
132.06 -> roll in my case to have the ability of accessing
this bucket in here if you don't have that then
142.14 -> whenever this ec2 instance that has a row tries
to access the bucket IE to upload it will fail
152.4 -> so we need to attach a row then we can use the SDK
by Amazon and I'm going to let you go and try and
161.46 -> figure out which one to use but later I'll give
you the solution but basically you can use the S3
167.34 -> client and what I want you to do in this exercise
is the ability of you having two implementations
175.8 -> so one which basically connects to the real S3
bucket and then the other one that basically acts
183.9 -> as an S3 backed by a folder under a path within EC2 your file system so in my case I'm going to put
194.16 -> it under home a folder called dot Amigos code and
then S3 and then images and then user ID and then
201.9 -> the image ID so this will be the idea and in here
this would be number three in fact right here
211.02 -> and also what you need to do is to store
the fact that a customer has an image so
217.86 -> that you can then later retrieve the image
of the bucket with the corresponding ID
224.46 -> and here you see that we do have IntelliJ and
basically in here you should be able to run your
230.82 -> code and what I really want to see is actually
an integration test that basically simulates all
238.62 -> of this so adding to AWS so S3 but also to the
fake one in here and mainly you know when we are
246.48 -> running integration tests we're not going to have
the ability of communicating with AWS services
251.46 -> so that's why we do have this fake implementation
so that the integration tests do work when we use
258.78 -> them within GitHub actions and on the front end in
here I've got basically a bunch of people in here
266.64 -> so people are messing up with this application
at the moment but in here so if I click on update
273 -> so here I've got this basically drag and drop
component where I can drag a picture in here
278.46 -> or I can select so let me show you the drag
and drop feature so here I do have a couple
283.8 -> of pictures and literally I can take any picture
so let's say Georgie so Georgian let's just take
291.96 -> my picture in here and here I can drop the
picture and this will upload to the server
299.58 -> and currently I don't have any loading and you
can see that basically took some time but it was
306.54 -> actually uploading the picture uh but basically
if I search now for joji so G orgy is it Georgie
315.42 -> G or G or G or G there we go so this is Georgie
right here and you can see my picture also if I
326.16 -> click on update and here now you can see that
the picture is present in here and obviously I
333.9 -> can basically upload the picture again so let me
just now pull a female for example and just bear
340.5 -> in mind that as I said so there's no loading
component at the moment but you can add that
344.46 -> yourself so if I drag the picture so at this point
it's actually loading and this time it was faster
349.8 -> so if I search for Gog again so command f so G or
G or G and you can see that this is the picture
359.58 -> now click on update and it's working beautifully
awesome let's learn how to implement all of this
370.68 -> so for this course I want to be using IntelliJ
as the IDE of choice and the IntelliJ they've
376.56 -> just launched their brand new theme which
currently it's in beta mode and maybe by
381.6 -> the time that you watch this video it might not
be in beta but it really doesn't matter if I use
387.54 -> the new UI theme or the old UI theme because
it's just coding okay so when I run some code
395.04 -> is going to be the exact same place so
all you have to do is just look for the
398.52 -> play button and it's basically the same
place it's quite easy for you to see then
404.64 -> the other thing is I'm doing a giveaway and I'm
giving you the IntelliJ license so the ultimate
413.1 -> for three months I can't even say three months
so for three months right and all you have to do
420.06 -> is follow me on my LinkedIn profile also there's
a brand new group which you will basically find
428.1 -> a link and the description of this video within
LinkedIn so we have a LinkedIn group now and also
434.76 -> join Discord because that's where if you have
any questions about the course you should post
441.6 -> um your questions okay so this code is a very
active community and you should be part of it so
447.3 -> join all those three uh so follow me I'm not join
but follow me join the LinkedIn group and also
454.86 -> Discord and you should get your license cool this
is pretty much it I'm so excited let's get started
468.48 -> if you want to follow and code along
with me which I think is the best
473.46 -> way of you to learn all of the stuff that
I'm about to teach you go ahead and clone
478.56 -> the repository which you can find the
link and the description of this video
483.6 -> So within the repository click on code and then
in here you are able to basically clone using SSH
490.44 -> you can see some description about basically this
is part of the curriculum which is over 50 hours
497.28 -> and we are adding more content to it so also you
can look into the commits in here which I'm going
504.48 -> to show you which one you have to commit in order
to follow along so go ahead and pretty much just
511.02 -> clone so click on code grab this link and then
open up your terminal so in here I've got my
518.34 -> terminal open and you can literally clone this to
anywhere within your file system so if I say PWD
525.42 -> you can see that this is uses for slash Amigos
code and right now let me just go to desktop
531.96 -> so CD and then desktop and in here I'm going to
say git and then clone and then paste the link
539.04 -> awesome so now it's actually cloning and there
we go next let's open up this repo with IntelliJ
553.26 -> for this course I'm going to use IntelliJ ultimate
and it's by far the best IDE for Java development
560.34 -> and also for full stack it's amazing so luckily
for you I've got a coupon code for three months
567.72 -> in which you can basically use and have access to
all the features so here if you navigate to this
573 -> website which I'm going to leave the link and
the description of this video and if you click
577.38 -> on download you'll see that IntelliJ basically
they have two versions they have the community
581.64 -> as well as the ultimate so this one is a paid
version which I'm going to give you access for
588 -> three months as I said now the best way for
installing IntelliJ is not directly and you
595.74 -> should do it through so if we click on developer
tools and in here you should see the toolbox app
602.46 -> so basically this is the best way for you
to manage all of your jetbrains Ides so
608.22 -> this basically allows you to upgrade easily
install rollback and downgrade and all that
613.68 -> good stuff so basically go and install the
toolbox app and then you'll have access to
620.7 -> and then you'll be able to install IntelliJ
let me show you so in here I already have
626.64 -> the toolbox app which is available in here so
if I click on toolbox you can see that this
632.4 -> opens up the toolbox and if I click on tools
you can see that I do have IntelliJ Community
638.46 -> I've got idea and there's updates which I need
to basically do and you can see all the other
644.64 -> ones in here but the one I wanted to install
is this one in here and I'm going to leave
650.34 -> the instructions on how to get the three months
license next let's go ahead and open up IntelliJ
661.32 -> all right so in here if I open up IntelliJ you
should be presented with a screen that looks
667.32 -> like this so let's open up our project so here
I'm going to click on open or if you want you
675.48 -> can get from VCS so you just paste the GitHub
link and basically just clone the repo also if
682.62 -> you have the exact same version you can enable
the brand new UI which is I think in build beta
689.52 -> mode which I'm not going to use so I just want
to make sure that basically all the recordings
694.14 -> are with the same IDE but if you want to use
their brand new UI feel free to do so it looks
701.76 -> pretty good actually so here I'm going to click
on open and then within my desktop this is where
707.1 -> I've got the folder so open the folder and all
I want you to do is to open the root so this
714.66 -> is a mono repo where we have the front end the
back end and whatnot so just open there we go
721.2 -> and you can see now there's a few things about
what's new about IntelliJ so I've just updated
728.1 -> and if I close this there's also the readme I'm
going to close this and I'm going to basically
734.64 -> load this because you found the maven build
script there we go so just give it a second
743.7 -> and I'm going to cancel this plugin here and
there we go so if you manage to get this right
750.78 -> here where you see the folder in here and it
looks like this and if you expand you should
756.3 -> see CI GitHub git ignore backend front end within
the front end we have angular react so if you see
764.52 -> all of this in here you've successfully managed
to open the project with IntelliJ cool the next
773.52 -> thing that I want you to do is if you open up git
in here you should see that there's basically all
780.96 -> of these commits in here and what I want you
to do is to check out the point before the
788.58 -> file upload so here I think so this is the readme
stuff that I've done and then this is the react
798.12 -> and then in here so basically I think it's this
one right here so basically what I want to do at
806.58 -> this point so I want to check out the code before
I implement the file uploads so you see S3 file
815.28 -> uploads the commit before it no this one because
this one is a branch but before it enroll to
822.18 -> enroll so basically two L's to one L so basically
right click and then what I want to do is to check
829.98 -> out revision so basically we're going to check
out to this point so check out and there we go
840.06 -> so I'm also going to leave the command so in
case you want to check out using the terminal
846.54 -> or command line what you do is so here I'm going
to right click and we should be able to copy the
854.4 -> revision number just like that and if I hide this
and in here so basically it's just downloading a
863.82 -> few things let this finish and you can see
the revision in here actually so the reason
870.78 -> why I'm doing this is so that you can follow
along awesome so here we can open the terminal
877.32 -> and you can see that this is the revision
now if I say git check out and then Main
884.76 -> you can see that I went back from this revision
to main right now I can say git checkout and then
893.1 -> paste the revision so basically this long number
in here press enter so this is the exact same
900.54 -> thing have a look now the head is at enroll to
enroll so I'm going to leave this command as well
907.02 -> so that if you want to do it this way you can do
it but but this will be the starting point for us
919.14 -> in order to successfully run the application
you need to install Docker and basically Docker
924.66 -> is just a fancy way of you basically running
anything that you want locally without having to
931.26 -> do any setup whatsoever so if you want to learn
more about Docker I have a course on Docker and
936.78 -> Docker is a must these days if you are serious
about becoming a software engineer or if you're
943.56 -> a software engineer and you don't know much about
Docker then you must know about Docker right now
950.4 -> so go and install Docker and once Docker is
installed you should see something called
956.82 -> Docker desktop so in here if I click on
this button in here so open the dashboard
964.5 -> and you should see something like this so
let's take this command in here so if this
971.7 -> is the first time that you run Docker just take
this right here so this command copy and open up
978.18 -> your terminal and what we're going to do is just
paste that command and this will verify that we
983.82 -> have Docker installed so basically it's just going
to run a hello world or getting started container
991.32 -> you can see that it says enable to find
it's going to do something like this
996.72 -> and it's going to basically run and then finish
so if the command run and executed successfully
1004.58 -> what I want to do is open up Docker desktop
and you should see this right here which is
1011.36 -> a brand new container cool and this guy
here is running on Port 80. and if you
1019.58 -> want to see the exact same details through the
terminal you could just type Docker and then PS
1026.48 -> so here basically is the same information
so you have one container right here so
1032.24 -> basically port 80. on the host mapping to
Port 80 inside of the container now what
1038.54 -> I want to do is I want you to open your
web browser and together let's type local
1045.86 -> and then host literally just localhost press enter
and you should get this right here up and running
1055.94 -> so if you manage to get this page right here it
means that everything it's working as expected
1063.26 -> now let me destroy this container so in here back
to Docker desktop we can basically delete the
1070.52 -> container through here or through the terminal by
saying Docker RM and then let's say Dash f 4 so we
1079.82 -> don't have to stop the container get the container
ID and then paste and then enter and you should
1087.74 -> get the ID back and now within Docker desktop no
containers are running and if I try to access the
1096.02 -> same page so this one here before so if I reload
you can see that the site cannot be reached
1103.7 -> cool so if you've done all of this congratulations
you are on your way in terms of learning Docker
1109.94 -> next let's go ahead and get the database I've
been running for our application using docker
1120.56 -> cool in order to get the database up and running
for this course we're going to use Docker as it's
1127.04 -> the world most advanced open source relational
database and it's quite popular and it's one
1133.7 -> that I recommend on my courses so let's go ahead
and get this database up and running with Docker
1141.68 -> So within IntelliJ if I just hide this you should
see that there's a file called dockercompose.yaml
1149.06 -> and in this file this is the ammo definition for
Kepler containers so here I've got one called DB
1156.8 -> and this is for the database then I also have
another one for the API so this is the API that
1163.04 -> we build in the course and then we containerize
and the idea is that we can just use this Docker
1170.36 -> compose file and then get the entire stack up and
running also we have the front end with react here
1177.44 -> as well cool and if you want to learn more about
all of these as I said check out the docker course
1182.48 -> where I teach all of this so for now what I'm
going to do and this is very important let's get
1188.54 -> rid of the API in here so this service so I'm
going to collapse this as well as react so we
1195.14 -> don't need none of this and I don't want this to
cause us any issues so I just want us to be able
1201.44 -> to have the database I've been running because
this is what our spring boot application will need
1206.48 -> when we run it locally cool so now make sure that
you have this exact same file as is and I'm going
1214.4 -> to leave this in the description of this video so
that you could just copy and paste but one thing
1219.56 -> to bear in mind is have a look The Amigos code is
the user and the password and here is password so
1225.32 -> this is what this springboard application uses to
connect to this database cool next let's open up
1231.2 -> the terminal and within the terminal what we're
going to do is we're going to CD into the full
1237.44 -> stack folder so here I'm within the desktop
so CD full stack professional and now if I
1244.4 -> type LS you should see that we have the docker
composer yaml if I say cat Docker composer yaml
1255.26 -> you can see that this is the file that I've just
showed you with one service which is the database
1261.92 -> awesome now what I want to do is simply to
say docker compose and then up Dash and then d
1273.38 -> so this is Docker and then within Docker
there's another compose tool and basically
1280.52 -> allows us to run containers based of the yaml
definition and D is for detached mode press enter
1287.78 -> and you can see that for me this was super
quick but for you maybe if you're running
1292.46 -> this first time it should take some time to pull
the images or to pull this postgres image in fact
1301.34 -> nice now go ahead and type docker and then
PS if you type Docker PS and you have one
1311.96 -> container is fine right and the container is up
and running but if you use Docker before and you
1317.3 -> have multiple containers look for the one called
in here postgres so names post and then grass
1326.12 -> also there's this nice environment variable
so here I think it's format so I think let me
1333.86 -> just say export and then format which I'm going to
leave in the description of this video press that
1339.74 -> and then I can say Docker PS dash dash format and
now this gives me the output formatted nicely like
1350.48 -> this instead of like this and here you can see
the ID the name the image the port So currently
1358.16 -> it's localhost 5332 mapping to 5432 inside of the
container the command created and the status which
1369.86 -> basically up about a minute ago now what I want
you to do is let's take either the name or the ID
1377.36 -> and say Docker logs and take the name or the
ID press enter and in here you should see this
1389.72 -> exact same output that says database is ready to
accept connections awesome if you've managed to
1398 -> get this far congratulations if not let us know
within this code otherwise next let's go inside
1404.6 -> of this container and create a database called
customer which our backend needs in order to run
1418.34 -> within IntelliJ if I close the
docker compose yaml for now
1423.74 -> and let us open the backend folder SRC main Java
and here you have the main class so if you try
1434.84 -> to run this main class in here or you can run it
through here or right click run this should fail
1443.48 -> in here there we go and it fails because
the database customer does not exist
1450.62 -> so let's create that within our database so
you've got two options you can connect using
1457.1 -> the database client in here with IntelliJ or
through the terminal so let me do it through the
1463.46 -> terminal So within the terminal if I type Docker
PS you can see that we have one container which
1470.36 -> is running and this is the database so let's take
the database name or ID say docker exec Dash it
1481.1 -> just like this paste the name or the ID for our
container and then say sh now we are within this
1491.6 -> container and this basically is just a Linux
box if I type LS you can see the Linux file
1496.94 -> structure so what we're going to do is type psql
so this is the official CLI client for postgres
1504.8 -> here say Dash capital u Amigos code so this is
the user and also let's connect to so say Dash D
1515 -> and by default we should have a database called
post and then Grace press enter and you can see
1523.34 -> that we are inside at this point if I press
Ctrl L it just makes some room for us there
1530.24 -> and if I type backslash L you can see that this
lists the databases and currently there's four
1537.92 -> so Amigos code postgres template 0 and template
1. so what we're going to do is let's just say
1545.48 -> create and then data base and in here we're
going to create a database called customer
1553.82 -> and then make sure that you have a semicolon enter
and if you have the exact same output so if this
1561.2 -> comes back create database it means that it was
successfully created and also if I type backslash
1569.42 -> l once more clear the screen press enter now you
can see that we have the customer database inside
1578.12 -> so let's basically connect to customer so say
backslash C and then customer and now if I type
1588.02 -> backslash and then D enter there's no relations
let's open up IntelliJ and if we try to run the
1597.86 -> application once more so this time it should
just work there we go and we have a user in here
1607.34 -> so insert into customer age email blah blah blah
blah blah values and the application is up and
1616.88 -> running awesome next let's go back to the database
and if I type backslash and then D once more
1624.74 -> now you can see that we have few relations we
have the table called customer the sequence and
1630.98 -> Flyway schema history as well as a table so if I
say select and Then star from and then customer
1641 -> if I press enter so make sure you have
semicolon there you can see that we have this
1647 -> customer right here now let me say backslash
t and then run the exact same command again
1655.1 -> or sorry not t so let me just toggle
it off and I think it's backslash X
1661.82 -> yes expand the display on so let me just run the
exact same command so select start from customer
1669.38 -> and you can see how the data now comes this
way and this is our customer id1 that's the
1676.46 -> name the password obviously in here is
encoded and gender mail and the age 98.
1685.7 -> so if you managed to get this far congratulations
next let me go ahead and press Ctrl D to come out
1694.28 -> of psql and then Ctrl D once more to come
out of the container and we are good to
1701 -> go if you've managed to get the back end
up running congratulations otherwise let
1706.16 -> me know if you are facing any issues so that
you can follow along catch me on the next one
1716.48 -> in order to get the front-end up and running
either react or angular what we need to do is to
1722.72 -> install node.js so this is very important in order
to run our front end locally so download either
1731.9 -> the long term support or the current it doesn't
matter because it should just work once you have
1738.08 -> node installed open up the terminal and within the
terminal so if I clear the screen in here Ctrl l
1745.52 -> I'm going to say CD and then navigate to
Front End and let's first do react there we go
1756.14 -> and in here I'm going to type npm so just type
npm and you should see that this will come back
1763.64 -> and say hey you want to do something these are the
usages right so it means that we have successfully
1770.36 -> installed node.js and when you install node.js it
comes with npm which is the package manager so now
1778.64 -> what we're going to do is say npm and then I and
in fact before I do that if I type LS have a look
1787.34 -> so these are the files and folders We have but
when we type npm I or install is the same thing
1796.46 -> this will go and download all dependencies
and you can see that added 269 packages
1803.3 -> so here let's just type LS once more and now you
can see that we have node modules let me clear the
1810.68 -> screen and now to run the react front end just
type npm and then run and then death awesome so
1820.22 -> you can see that it says this is actually running
on localhost 5173 so let's just take this URL
1828.8 -> and open up Chrome new tab paste URL press enter
and you should see this beautiful UI awesome if
1840.5 -> you want to log in to grab the credentials open up
IntelliJ and remember when we started the back end
1846.26 -> you should see the logs this email so just take
the email go back and then paste that and for the
1854.18 -> password is going to be password and then login
and you can see that it works click on customers
1863.18 -> and you should see that we have one customer
in here and we can update we can delete the
1869.78 -> customer if we want and also let's try to add
a new customer so here let's just say Jean
1878.54 -> let's say she's 22 password is going
to be password and then gender female
1890.24 -> submit you can see that she's added in here and
let's try to login with Jean sign out this will
1900.86 -> be Jean at amigosco.com the password is password
login and now we are signed in with Jean customers
1911.48 -> and we can see everyone again awesome if you've
managed to do all of this congratulations you
1918.62 -> are on your way in terms of building the
functionality to upload pictures with AWS
1930.2 -> cool let's begin our journey in terms of building
all of this the very first place that I always
1936.86 -> start when I have to basically use an SDK or an
API or basically Implement literally any feature
1946.64 -> is by looking at the documentation and then take
it from there so in here I'm within the AWS SDK
1954.68 -> for Java documentation so this is the official
documentation from AWS and in here basically we
1962.96 -> learn how to integrate AWS services with Java so
you can find the link on the description of this
1971.72 -> video for this documentation but here I know that
for a fact that you know version one is actually
1978.56 -> deprecated and there's a new version which is two
there's also a migration guide and in here so we
1985.88 -> have the API reference and here we have the
developer guide so let's look into developer
1992.72 -> guide and this should gives us more or less an
idea of how to get up and running so on the left
1999.74 -> you can see that we have you know get started
tutorial some information about the SDK and
2007.3 -> setup SDK features security documentation history
and whatnot so let's click on get started tutorial
2015.22 -> and here you can basically follow this tutorial
if you want to get up and running with this SDK
2021.4 -> but in here so basically if I scroll down this
is a maven project you can see the palm.xml and
2029.62 -> in here you can see that they have the dependency
and then basically they use the SDK like so
2037.36 -> and um yeah so also under setup in here they also
have you know a more detailed guide I think with
2046.42 -> Maven and possibly Gradle as well and how
to migrate from version 1 to version two
2052.96 -> so on and so forth so in here so let's basically
click on build steps so I want to set up with
2061.84 -> Apache maven and actually let's look into
right so this actually it's using the SDK so
2070.66 -> in here what I really want to take from is the
dependency so if I scroll down I can see have
2077.62 -> a look declare the SDK as a dependency so here
this is the version in here and if I scroll down
2086.8 -> so this is the dependency management which we
are not using but instead we're going to take
2094 -> the dependency right here so the S3 dependency
like so so let's basically command C on this guy
2103.42 -> and then open up IntelliJ and within IntelliJ
open up palm.xml and in healing for this full
2110.92 -> screen and under dependencies in here I'm going
to basically add it as the last one now here we
2119.32 -> also have to add the version so here version and
the version as it stands I'm going to use 2 20 26.
2129.04 -> and if I go back in here have a look 220 I think
there's a newer version actually as I'm speaking
2136.9 -> but basically I would say try and use the same
version as I have or probably if this is not
2145.96 -> three so basically three which means the major
version upgrade then everything should just work
2152.38 -> cool let me go back to IntelliJ and you
could take this right here so this version
2158.56 -> as a property but I'm going to leave it as is
and let me just click on load maybe changes
2166 -> and this is pretty much it next let's
go ahead and learn how to use this SDK
2180.46 -> cool we have the maven dependency and let me
collapse setup in here use the SDK so if I click
2189.22 -> on it you can see that they give us basically
an example on how to use it but one thing that
2197.26 -> we need to make sure that we have first is here
if I click on provide temporary credentials so
2203.86 -> before making a request to AWS we need temporary
credentials so that we can use these Services
2211.36 -> provided by AWS here we have temporary credentials
so if I click on it they basically show us what
2218.8 -> we need to do then we have default credential
provided chain so this is when you basically
2226.42 -> are initializing this service within Java then
this is where the credentials are retrieved from
2235.06 -> so first is from java properties then environment
variables web identity token shared credentials
2243.94 -> ECS container and then here easy to instance imbro
which later you'll see how we're going to use this
2253.54 -> but what we're going to first use is temporary
credentials so here if I click on it so basically
2261.94 -> what we're going to do is we're going to retrieve
the credentials from AWS console and then we're
2268.66 -> going to store them in a location called here so
under home dot AWS and then credentials and this
2278.56 -> is mainly for local development right then we're
going to add the access key ID the secret access
2285.64 -> and I think for us this should be more than enough
and here you can follow you know details on how to
2293.02 -> do it but don't worry I'm going to show you how
to do this so let's go ahead together and open
2299.86 -> up the AWS console and within the console navigate
to your username so in here Amigos code in my case
2308.32 -> then navigate to security credentials and
within this page in here you should see
2314.68 -> access management on your left click on users and
in here if you remember correctly before we added
2324.22 -> Amigos code gitup actions so now what we're
going to do is we are going to add a new user
2331.54 -> and here I'm going to name this user as
Amigos code and here I'm not going to
2339.58 -> provide access to the console so this will
be programmatic access only click on next
2346.78 -> and for the user group what you could do is you
could say right so this user is only allowed to
2354.7 -> use the S3 service for example but in my case
in here I'm going to use the admin so I want to
2364.42 -> give full control to all services within AWS to
Amigos code so that user will have full control
2374.14 -> and also you can set permission boundaries but
we don't want to do that and if you don't see
2379.84 -> admin in here you can create a group
so let's just see if I create a group
2385.96 -> and here you can see administrator here provides
full access so basically you then select admin
2395.68 -> and then just say admin in here and you should
have the exact same group as I do so this is
2403.18 -> the admin in here but let me just show you for
example S3 so in here so you can see that these
2410.98 -> are so here S3 full access maybe you just want to
limit the user to have access to S3 and that's it
2419.56 -> or S3 read only that's it right so in my case in
here I'm going to give full access as I said let
2427.66 -> me just collapse that and select admin in here
and let's click on next and you get a summary
2436.54 -> in here so the username is Amigos code and the
group is admin in here no tags create the user
2446.98 -> awesome so now that we have the user next what we
have to do is issue the credentials for this user
2460.54 -> previously when you created the user you would
get issued the credentials but now we have to
2467.38 -> do this on a separate step so click on the user
that you just created so in my case Amigos code
2473.5 -> and then what you need to do is under security
credentials click on it and in here if I scroll
2482.38 -> down we should have access keys so access keys to
send programmatic calls to AWS from the AWS CLI
2494.86 -> tools SDK or API calls so a maximum of two
keys active or inactive at a time so let's
2506.44 -> create the access key and in here what I want
to be able to is to access through the CLI in
2515.68 -> here right so there's no local code there's
no application running on compute service at
2523.24 -> this point so we're not going to do this and you
shouldn't really do this actually you should use
2528.52 -> I am rolls which I will show you later and in
here so the application is not running outside
2535.42 -> AWS so in here what I want is local code and you
plan to use this access key to enable application
2543.04 -> code in local development environment to access
your AWS account so this is exactly what we want
2548.38 -> and in here so let's just basically say I
understand the above recommendation and click next
2558.04 -> in here if you want you can basically add a
tag which I'm not going to and then generate
2565.72 -> access key cool at this point you see that we
have the access key as well as secret access
2574 -> key and we have some best practices on how
to access the key itself so never store the
2581.5 -> key in play text disable access when no longer
needed enable list privilege permissions which
2588.28 -> we haven't done we just you know said that the
role itself or the user is an administrator
2595.78 -> and rotate access Keys often so in here what we
need to do next is take the axis key as well as
2604.66 -> secret key and then store them within our local
machine and I'm going to show you where next
2616.78 -> so in order to store these values the access
key as well as the secret access key if I go
2623.98 -> to the documentation in here so under use the
SDK use temporary credentials there should be
2631.9 -> a section here so basically set up a local
credentials file for temporary credentials
2637.78 -> so here basically what we have to do is
we have to get something like this under
2644.5 -> the home directory dot AWS and then a file
called credentials so if I open up my terminal
2654.34 -> and within my terminal in here just basically
type CD and then tilde or just CD and this if
2661.9 -> I say PWD you can see that this is uses and
then forward slash amidoscope now under it
2668.5 -> so if you don't have a folder called AWS just
go ahead and create a folder like so so say make
2677.02 -> there dot AWS okay so I already have this folder
so I'm going to say CD to change directory to AWS
2687.76 -> and in here if I type LS you can see that
we have credentials so this is a file now
2696.1 -> what I'm going to do is I'm going to
open this with VI and then credentials
2703.18 -> press enter and in here I do have one profile
which is the default so basically have this
2710.74 -> so open square brackets say default close square
brackets and then have AWS access key ID and then
2719.74 -> this should be the ID and then do the same for AWS
secret access key and then the access key that was
2728.2 -> given to you so what I'm going to do is I'm going
to basically press I in here and I'm going to
2735.28 -> press or actually Escape I'm going to press J to
go down W to word and then press basically D and
2745.6 -> then W to delete basically the word and press I
now in here I'm going to paste the access key ID
2754.42 -> so back to the console the access key so this
guy here copy and then here I'm gonna paste I'm
2764.56 -> going to press Escape J and here I'm going to go
back a word and then press d w and basically it
2774.16 -> deletes the secret access key I for insert and
let's basically paste the secret access key now
2785.38 -> here I'm going to show you the value and that's
because after this video I'm going to regenerate
2792.1 -> the access key as well as the secret because
otherwise anyone with these credentials can
2799.12 -> have full control or full access on my account and
I don't want that to happen so these values here
2806.38 -> they should be kept secret so never show them to
no one so here I'm going to copy and then go back
2815.38 -> and then paste and you can find the contents
for this file under the description of this
2821.8 -> video so that you can just copy and paste
but let's press Escape and then colon and
2829.72 -> then WQ so we want to write and quit cool so if
I press cool if I type cat and then credentials
2841.66 -> and you can see that these are the credentials
that we just copy and paste it and this should
2849.52 -> be it if you have any questions drop me a
message otherwise catch me on the next one
2860.44 -> cool back to the documentation in here we have the
credentials out of the way now SDK features so I'm
2868.96 -> not going to show you basically the features and
here work with AWS Services if I open this app in
2877 -> here have a look we've got a bunch of services
and the one that we are interested is Amazon
2885.22 -> simple storage or simply S3 so you can also work
with Dynamo ec2 I am Athena Cognito Lambda Amazon
2896.8 -> poly sqs Amazon translate and basically all of
these all the services in here so the one that
2907.6 -> we are interested is the S3 simple storage service
so basically this section provides a guide on how
2916.6 -> to get up and running with S3 but let me just
show you so S3 if you don't know much about S3
2924.82 -> but S3 basically object storage built to retrieve
any amount of data from anywhere now here so five
2934.36 -> gigs of standard storage for 12 months with the
AWS free tier which is way more than enough for
2941.86 -> what we need because we're just going to store
pictures and here you can scale storage resources
2948.1 -> you can store across storage classes you can
protect your data and it's easy to manage data
2954.82 -> at any scale and more so here they've got a
diagram on how it works which I'm going to let
2961.36 -> you basically go through it but literally
analytics data log files application data
2968.56 -> videos pictures backup and archival literally you
name it you can store anything within Amazon S3
2978.76 -> so basically all you need is just a bucket
so they call it bucket where you can just put
2985.24 -> your files in it or your objects so you can
see like the use cases but it's very popular
2992.98 -> and it's one of the services that you should
know how to use within AWS because now we
3000.24 -> store data more than ever before next
let's go ahead and learn how to have
3007.86 -> the configuration for our S3 client that will
enable us to use Amazon S3 programmatically
3022.26 -> cool within the documentation working with Amazon
S3 in here they give us some code snippet on how
3029.28 -> to get up and running with S3 so let's together
take this piece of code and open up IntelliJ
3038.46 -> and within IntelliJ let's open a project and
within the backend folder let's open up the
3045.9 -> main Java and in here under the root package
let's create a new and then class and here
3055.2 -> we're going to say S3 Dot so this is the name of
the package and the name of the file will be S3
3064.92 -> and then config just like that so you can
create a package like this so press enter
3072.66 -> and you can see that we have the package in
here and the class called S3 and then config
3078.36 -> now this class in here so let's just basically
annotate this with ADD and then configuration
3084.78 -> and it's going to serve as a means for us to
create the client so here let's say public
3094.5 -> and then S three so S3 and then client not
configure S3 client just like this from
3105.9 -> software Amazon AWS SDK Services S3 S3 client
so this is the interface in here and I'm going
3116.16 -> to say basically S3 client and inside here I
want to paste the code that I've just copied so
3125.28 -> just like this now I don't think that we need the
end point override in here so we do need that and
3133.56 -> also let's remove the force path style so I think
all we need is the client provide the region and
3144.36 -> then say build and then we have the client now the
region this is very important so whatever region
3151.32 -> Which is closest to you and where you want your
bucket to reside just choose the right region so
3158.82 -> in my case let me just import class and this will
be so basically EU and then I think it's uh EU
3172.32 -> and then underscore West one now this right here
if I press command and then navigate into it
3180.48 -> so this is just a string like so right so
what I'm going to do in fact is I'm going
3187.92 -> to take this string close the region class and
in here I'm going to have private and then I
3195.96 -> want to say string and then AWS and then region
and don't say final there say at and then value
3204.72 -> and within the value in here so have dollar sign
and then curly brackets and AWS and then Dot and
3214.86 -> then region so the reason why I'm doing this
is so that you can basically just change the
3220.98 -> region from within the configuration file so
here then we just say region and then value
3228.36 -> or actually region of and then the string
is AWS and then region cool so now we need
3235.74 -> to Define this guy in here so let's just open
a project and within project open resources
3242.22 -> application.yaml and then literally anywhere so
here I'm just going to do it here so AWS colon
3251.16 -> and then inside I'm going to say region colon and
then paste the string so EU West one so choose the
3260.58 -> right region for your application now back to the
config so in here we are done and dusted with the
3269.64 -> region the last thing that we have to do is return
the client just like that and we're good to go
3277.14 -> finally let's annotate this with ADD and then Bean
just like that and now we have the client in here
3285.96 -> later we're going to do some extra work in
here because we need a second implementation
3291.66 -> that will serve for basically running the
application without has having to connect to
3298.92 -> S3 directly so maybe we don't want to
use the credentials to AWS and in fact
3305.64 -> we shouldn't have those credentials locally
so we're going to have a fake implementation
3311.22 -> that will store files to our local file
system and also it will be used for testing
3318.96 -> for now this is okay and later we will change this
this is pretty much it catch me on the next one
3332.04 -> now that we have S3 config let's together
create the S3 and then service so here I'm
3339.06 -> going to say S3 and then service and this
class right here so we need to annotate
3348.84 -> this with ADD and then service and this class
will have two methods you will have a method to
3356.7 -> upload or to basically store objects and want to
download objects so let's together here basically
3368.88 -> say that we want to have the clients so the
client now allows us to interact with S3 so
3376.56 -> private final S3 and then client that we've just
configured and let's add this to Constructor and
3385.86 -> now in here we can basically have a method to
put or to store objects to a specified bucket
3394.68 -> within the documentation for S3 in here if
I scroll down they have topics on buckets
3401.88 -> operations and an object operation so here you can
create a bucket so through Java code in here and
3410.76 -> basically what you do is just this right but
we're not going to do this because you should
3415.8 -> never create buckets through code and you should
have a team or maybe the infrastructure team the
3424.14 -> devops team manage the infrastructure for you
I.E creating those resources through code ie
3433.8 -> infrastructure as code with something like
terraform or palumi or cloud formation so
3442.68 -> in our case let's look into object operations and
I'll show you how to create the packet in a second
3448.62 -> but in here upload an object so here they give
you the actual code on how to upload an object so
3456.6 -> here so we have the bucket then all you do is you
just have a put request and job done so what we're
3465.3 -> going to do is let's take this go back and in here
let's have a method so I'm going to say public
3476.88 -> and then void and then put object and we're going
to fill in these in a second but so here let's
3486.48 -> just paste the code let me put this full screen
let's import put object request and here we have
3494.46 -> to pass the bucket name as well as the key so
these will come from so if I extract this to
3502.5 -> a parameter so that will be the bucket
name and the key will also be coming from
3509.76 -> the parameter just like that and what we
need to do in order to store to the bucket
3517.38 -> is invoke the S3 client Dot and then put object
and then pass the object and and request in here
3529.68 -> and more important the actual data so what we
want to store so what we're going to store is
3536.7 -> the request body so here just say request body
and then from bytes and then the actual bytes
3545.88 -> right or you could just say the file
for example here right as a byte array
3551.94 -> so this guy here let's extract this to
a variable and this is pretty much it
3560.76 -> so if you see that this is quite easy so we have
this method that allows us to store files to a
3571.14 -> specific bucket with a given key and the file
in here which is a byte array cool next let's
3581.4 -> implement the download functionality which
basically is just getting the byte array back
3593.1 -> so in here I'm within the official documentation
for S3 and basically this is what we've just done
3600.54 -> with put now what I want to do is to have the
ability of and also you can upload in Parts using
3609.12 -> multi-part upload which we don't need so usually
you do that for large files so here download
3616.86 -> object have a look it's so simple and all you need
is basically just this right so let's just take
3626.1 -> literally everything and then within IntelliJ
let's have the method here so I'm going to say
3632.88 -> public and then here this will be byte so this is
what we get back and right here so we store the
3641.22 -> file and we get it back right as a byte array
so here I'm going to say get and then object
3649.98 -> or you could even say download the file but let's
just say get object and here we need to pass d
3657.78 -> uh actually let's just use IntelliJ to generate
those so paste the code in here import class and
3667.26 -> the bucket name here I'm going to press option
command and then P for parameter the same for key
3675.66 -> there we go and in here so instead of S3 this
will be S3 client or we could even just say
3684.72 -> S3 actually it's a better name right so S3
just like that so S3 S 3 S3 I could use a
3699.06 -> a refactoring but that's fine so S3
get object and this is it right now
3707.22 -> what I want to do actually so if you look
into the return type for this this is a
3715.32 -> response input stream so I'm going to say
response right so response or res in here
3723.66 -> from the response we can actually get the
bytes right so here we just say object
3732.72 -> so here we just say risk so here we just say
res Dot and then have a look read all bytes so
3741.96 -> this in here we need to basically encapsulate
within try catch so here we have the bytes
3749.34 -> so here let's just surround this with try and then
catch and basically in case that there's nothing
3756.54 -> there then it just throws an exception right so
throw in the new runtime exception and then the
3763.56 -> exception in here now obviously if you want you
can add some logging in here to know exactly which
3771.12 -> bucket and what key that you basically failed to
look at but for our case I'm just going to leave
3778.74 -> this as is and that's it so now we can say return
and then bytes or if you prefer we can inline this
3789.54 -> just like that which looks much better and this
is the implementation tool getting an object
3798.6 -> if you have any questions drop me a
message otherwise catch me on the next one
3808.2 -> cool before we write any more code what I want
to do is I want to make sure that this indeed
3814.2 -> does work so in order for us to test this what we
need to do first is to write some code that uses
3822.54 -> these two methods but also create the bucket
itself so let's create a bucket So within AWS
3830.1 -> console go to the main page in here and what I
want you to do is search for s and then three
3840.9 -> and here scalable storage in the cloud also
added to favorites and now it's right in here
3849.96 -> so click on it and in here you can see that I do
have a couple of buckets in here so don't worry
3857.76 -> too much about these buckets in here but what we
want to do is to create a brand new bucket so just
3864.66 -> click on create bucket and if I put this bigger so
in here so bucket name in here just make sure that
3875.52 -> you type anything so in my case let's just say FS
for full stack Dash and then Amigos and then code
3887.52 -> Dash and then customer right so basically
this is mainly for customers and here let's
3895.08 -> just say test maybe you want to have one for
a different environment so maybe development
3901.92 -> staging production so let's just basically keep
this name as is also keep note of this name so
3909.18 -> I'm just going to copy and in here so AWS region
so just make sure you select a region which is
3917.22 -> the one where you are deploying your services so
in my case EU Island IE EU West one and I want
3926.46 -> to leave everything as default no need to change
anything and right at the bottom create a bucket
3935.52 -> cool now in here we should see the bucket so
where it is so here FS Amigos code customer
3944.04 -> test so FS for full stack if I click on it you can
see that there are no objects and obviously we can
3952.5 -> upload the files manually if we want to but I'm
going to show you through code in just a second
3960.96 -> cool next let's write some code to test
that we can indeed upload files to S3
3974.76 -> okie dokie so we have the S3 bucket in here and
which is this one actually and uh basically what
3985.44 -> we want to do is within IntelliJ we want to write
some code that will basically upload a file to
3992.1 -> the bucket so basically we just are testing things
and we haven't done this one here nor the row nor
4001.94 -> storing to the database and these will come later
so let's open up IntelliJ and within IntelliJ
4009.68 -> let's open up the main so here open up the main
method and within Main let's basically I'm gonna
4021.62 -> comment all of this So eventually I'll put this
back or let me just say extract this to a method
4030.44 -> and here create random and then customer cool so
let me just comment this and within the runner
4044.06 -> method here itself what we're going to do is
let's basically have the S3 service so s 3
4054.08 -> and then service just like that and what we're
going to do is we're going to say S3 service
4062.36 -> Dot and then put object the bucket name has to be
the exact same name of the bucket so if I go back
4073.22 -> which is FS Amigos code customer test and
then paste that so that's the bucket name
4080.36 -> and also in here so let me just put this on a new
line also we need to pass the key right so here
4090.32 -> I'm going to say Foo so that's the key and finally
the byte so what we want to upload so in our case
4100.76 -> let's just say hello and then world and then store
this as a byte array and literally we can store
4109.64 -> anything into the bucket cool so basically this
here stores and we should be able to get the item
4121.28 -> back so here let's basically say S3 service Dot
and then get object the bucket name is the same
4134.36 -> so the bucket name is the same like that the
key is also Foo the same and this is it right
4146.24 -> so basically this now is bytes so now if I extract
this to a variable this is the object so I'm going
4158.24 -> to say object so object like that and what we're
going to do is south and then hooray and then Plus
4173.18 -> and here I want to say new and then
string and then pass the object inside
4180.98 -> cool so this is how we turn
a byte array into a string
4185.72 -> now if we run this we should see that we get back
Foo we should see that we get a low world back
4194.66 -> let's run it so here right click run Main
give it a second so it's going to start
4204.44 -> and hooray have a look so we have hello and then
world and this means that we've managed to upload
4213.68 -> a file into S3 let's check it out so before we
had no objects now if I reload this page in here
4225.38 -> you can see that in a second why is it slow
my internet is so rubbish seriously cool
4235.16 -> have a look so this is full and basically we
can download this so click on it and you can
4244.58 -> download if you want but inside is going to say
hello world which is what you saw in the console
4252.5 -> and to be honest this is it and also the path
right so basically this is the bucket and this is
4261.62 -> the key itself now if you want you can store these
you know as a folder structure so you can say
4269.24 -> forward slash and then images and then full
dot PNG or dot txt whatever right so first I
4277.82 -> just stored within the root of the bucket itself
now what I want to show you is within dot AWS if
4287.6 -> I say VI in here and then credentials and
then here if I go to the end of this file
4296.06 -> and then delete so I'm going to press X so delete
a Escape WQ and if we try to run our code again
4310.64 -> and in here I actually have the AWS plugin
installed which tells me right so this
4318.62 -> has an invalid database
connection and if I show you the
4325.64 -> plugin so I think plugin and then installed I
think and I think it's this one AWS toolkit so
4336.38 -> it will basically tell you whether uh there's
something wrong with your configuration or not
4342.62 -> so go ahead and install it and also you can see
so you can manage buckets and upload and download
4348.98 -> from packets as well so here I'm just going to say
okay and what I want to show you in fact is if I
4356.66 -> reload the application this will fail so give
it a second and boom have a look an exception
4365.66 -> has happened and if we look into the error so
in here scroll up or actually down let's just
4375.56 -> try and read the error so here have a look right
the request signature we calculated does not match
4386.06 -> the signature you provided check your key
and signing a method and have a look 403.
4395.3 -> so you can see that how it's important
that you have the credentials configured
4401.3 -> correctly because otherwise you won't be
able to access the resources within AWS
4407.12 -> and also our key is admin which means you
can do anything right but if we restrict
4413.66 -> it and then try to access a resource which
the key is not allowed it will also fail
4419.9 -> awesome let me hide this and go back
to the terminal and VI credentials
4426.08 -> so in here so if I go to the end say I so
this was actually t a and then Escape WQ
4438.56 -> and um this is it let's run once more there we
go and you can see that reloaded credentials
4447.02 -> and in here so the key let's
just say here for example full
4452.24 -> and then let's just say full forward slash bar
and then forward slash and then Jamila for example
4461.3 -> right so this right here is the key and if you see
the result of this so let's just run it once more
4472.88 -> there we go so we have Hello World
which was stored if I open up the bucket
4478.94 -> and here let me just go back now
check this out so full is a folder
4486.14 -> bar is yet another folder and inside we have
Jamila which is the file that contains hello world
4495.2 -> this is pretty much it catch me on the next one
4505.4 -> before we move into the controller
and add business logic what I want
4510.74 -> to do is I want to basically have
this bucket name as configuration
4515.12 -> so open up application.yaml and in here
you saw that we have AWS and then region
4524.54 -> let's have S3 in here and then
within S3 we're going to have buckets
4533.9 -> just like that and here we're going to have a
bucket and here called customer and then here
4544.7 -> and then in here we're going to have the
basically name itself right so the idea is
4552.02 -> that you can have different profiles and you'll
see this later and you can change the bucket name
4559.64 -> without having to change code so that is the
benefit of doing this now let's go to Project
4568.82 -> and in here create a new class under
S3 and we're going to call it S3
4581.54 -> and then buckets press enter here name this as
ADD and then configuration and also add and then
4591.02 -> configuration properties and this will have
a prefix of AWS dot S3 Dot and then buckets
4603.38 -> so don't worry about this in here but this right
here AWS dot S3 dot buckets is AWS dot S3 Dot and
4615.44 -> then buckets and then we can have these as fields
or actually the key as field and then whenever we
4625.46 -> invoke together we get the bucket itself
so let's go back and here we want to have
4633.98 -> a field so private don't say final here just say
private string and then customer and customer here
4644.24 -> is the same as this one here right then let's
basically have the Constructor so add Constructor
4654.44 -> and oh actually
4658.82 -> I don't even think we need to Constructor
here so there's no need for Constructor so
4663.02 -> just have the getter and Setter right
so here get it and setter and job done
4671.78 -> now what we can do is we can
take S3 buckets go to main
4676.82 -> and instead of saying this we could just inject
basically S3 buckets like that import that and
4687.74 -> now I can just say so instead of this nonsense I
can just say S3 buckets Dot and then get customer
4699.02 -> so let's basically try and
reload and see whether this works
4707.6 -> we should get Hello World back and yes we do
cool so you can see that this is a much better
4713.9 -> approach because later we can have a different
file so application Dash Dev for example with
4721.82 -> a different bucket name and the same with
the region and basically you can take this
4728.66 -> and just change it according to your bucket and it
should just work that's another Advantage as well
4736.34 -> cool this is pretty much it I think
I'm going to let's just take this here
4744.62 -> and extract to a method and then test bucket
upload and download and we're not going to
4755.12 -> do this anymore let's just uncomment the create
random user and let's get rid of the service as
4763.76 -> well as the buckets but be aware that if you want
to use them you just have to import them in here
4768.74 -> right because this is is expecting them right so
this is pretty much it let me just put this full
4776.36 -> screen so you see the entire code if you have
any questions and drop me a message otherwise
4782.66 -> next let's go ahead and create the controller and
then the service and start connecting the dots
4795.14 -> cool so I know that from within IntelliJ we can
run the application and we can store images in
4801.98 -> here which is nice this bit here this will
be later what I want to focus now is on the
4808.64 -> controller so we want to expose an API endpoint
to clients and also we want to store the image
4816.14 -> associated with a customer so let's first
tackle the controller so in here open up
4823.34 -> project and then open customer controller and
in here we're going to have two methods so one
4833.36 -> two download and the other one to upload so let's
start with the upload so in here let's say public
4842.18 -> and we're going to say void upload and
then customer profile and then picture
4851.54 -> and this in here will have the ADD
and then path and then variable
4858.98 -> so we need the customer actually in here so path
variable and put this on a new line like so this
4866.78 -> will be the customer and then ID and you've seen
this which is basically the same thing as this one
4873.2 -> and let's just take this and in here we're going
to leave this and in here we're going to change
4881.12 -> this as Post in here so post and then mapping
and this will be forward slash and then profile
4890.84 -> Dash and then image so let's just say profile
image instead of picture so profile image and
4900.2 -> this in here will be the ID which is an integer
so integer customer ID and also what we want
4910.94 -> to receive is so the way that we're going to
receive the file is by receiving the multi-part
4920.06 -> file and this will come as a request and then
param there we go and this will be called file
4929.78 -> and this will be a multi-part and then file so
make sure that it's the first one from Spring
4938.06 -> framework web multipart and here just call it
basically multi-part file or just file if you want
4947.36 -> add a space in there and this should be it now
because this is a file we have to say that this
4959.78 -> method in here so this add and then post mapping
and don't worry we're going to add integration
4966.44 -> tests to make sure that everything works so here
we're going to say consumes so this consumes
4975.44 -> media type Dot and then multi-part
and then form data value
4986.12 -> cool now at this point in here let's just
invoke customer service Dot and then upload
4995.66 -> customer and then image we're going to pass the
customer ID as well as the file just like that
5006.1 -> whoops no like that but like this and we'll create
this in a second so these two methods and we'll
5016.48 -> create this method in a second so the other method
that we want is let's just duplicate everything
5023.14 -> and this will be get mapping so get and then
mapping so here we can get rid of this all
5034.06 -> together and note so in here note the value
okay so here no need for value and the reason
5043.6 -> why we have value in there is because in here
we have consumes as well so this will be a get
5050.02 -> basically to get the profile image this will gives
us the byte array just like that I'm going to say
5060.76 -> get and then customer profile picture no need for
the multi-part in here and let's just say return
5073.24 -> and then customer service Dot and then get
5080.44 -> customer and then profile let's just
say profile get customer profile image
5091.6 -> there we go we pass the customer ID and also
upload customer profile image in there cool so
5102.16 -> this should be it for these two methods within
our controller next let's tackle the service
5115.9 -> cool in order for us to create these two
methods we did IntelliJ let me just right
5120.58 -> click show context action create method and it
takes me straight into the method in here on the
5128.98 -> service class let me go back and do the same for
get customer profile image and there we go cool
5137.68 -> so in here this is going to be straightforward
because we already have the service that allows
5143.86 -> us to upload and download so scroll to the
top in here and what we need is to have the
5154.06 -> private final and then S3 and then service so
the one that we just use within the main class
5161.44 -> add this to Constructor here just say
refractor will go into the test in a second
5167.56 -> and this is it if I scroll down so what we
need to do in here is before we upload we
5178.78 -> want to get the customer or in fact check
whether the customer exists so let's just
5184.9 -> copy some code and we could basically
extract this to a variable and basically say
5196 -> check if customer exists cool now we can reuse
this so here I could say check if customer exists
5210.34 -> or let's just rename this to or so refactor rename
5216.4 -> or and then throw there we go so here pass the
customer ID and if this is the case it's just
5227.26 -> gonna throw and execute the remaining lines now in
here what I want to do is I want to say S3 service
5236.74 -> Dot and then I want to put so this allows us to
upload the bucket so the bucket will come from
5246.52 -> let's scroll up in here and private final
and then this will be S3 and then buckets
5259 -> or we could just call it buckets to be honest
so that we're not tied to S3 but that's fine
5268.3 -> so here scroll down and where is it so it's not
even the lead customer it's this method right
5281.68 -> here right so here we want to get the bucket
so I'm going to say S3 buckets dot get customer
5291.22 -> and the key will be under a folder called profile
and then images forward slash and then percent s
5305.2 -> forward slash percent and then s dot and then
formatted and we need to pass the customer ID
5315.52 -> but also right so this will be customer ID so that
we organize things by customer and then here the
5325.06 -> ID for the picture so the ID for the picture so
this will be you with Dot and then random uid
5334.18 -> Dot tostring and finally so comma so literally
after this so basically this close in parenthesis
5345.4 -> so comma there and the actual file so
basically say file Dot and then get bytes
5354.94 -> now this here this is a checked exception
so let's just surround we try and catch
5361.06 -> so surround we try and catch and I think
this is pretty much it right so also let's
5370.96 -> extract this ID here so we're going to
extract this so I'm going to say profile
5379.9 -> and then image and then ID and let's put this out
5391 -> and let's take this and put it outside like so
cool so if it fails then we want to throw so throw
5404.32 -> new and then let's just say run time exception
so at this point I'm not worried too much about
5411.58 -> exceptions but if you want to organize these
exceptions and have better messages you know
5419.02 -> that within so if I show you so exception
we have the where is it default exception
5428.38 -> Handler and in here you can basically handle
all of the exceptions and have proper error
5434.98 -> codes but for now let's just get the meat of S3
and file uploads and downloads up and running
5443.14 -> cool so let's go back to customer service and
this is it now one thing that we have to do is
5451.72 -> so upon completing this so here let's just have
it to do so to do and then store and then image
5464.02 -> yeah so we'll do this in a second cool next let's
go ahead and Implement get customer profile image
5478.54 -> cool now let's Implement get customer profile
image and I've just basically need to make sure
5485.38 -> that this store image so this to do here is to
postgres so post address and basically store
5495.64 -> profile and basically store profile image ID so
basically profile image ID to postgres or 2db
5506.68 -> cool so now get customer in here so what we want
to do first is get the customer so if I scroll up
5515.74 -> you can see that this is how we get the customer
so here we just copying code I left copying
5524.02 -> code so here we're going to paste that we're
going to get the customer and that's it now
5533.2 -> we need to do few things so one is so here I
want to say to do and we'll do this in a second
5540.88 -> check if profile image ID is empty or no
5554.62 -> right so if so then we say that the customer
doesn't have a picture associated with and
5561.4 -> then what we do is we get the we get the
profile image ID so here let's just say string
5570.7 -> and by the way you are free to use VAR for example
okay so let's just use VAR here so VAR and then
5578.56 -> I'm gonna basically say profile image ID for now
so this will be to do as well in a second so to do
5587.98 -> and we can say return so in here return and then
S3 service Dot and then get object so D bucket is
5603.28 -> S3 buckets Dot get customer and then
the key so the key is the same one
5613.24 -> that we stored so where we put the object
itself so let's just paste that in here
5623.32 -> and this is pretty much it and then basically end
this with semicolon and basically this right here
5631.78 -> so if I extract this to a variable so you see
so this is the picture itself so pick sure right
5640.66 -> or image or profile image profile image and then
profile image so it's easy for you to see this way
5652.6 -> and yeah so this is pretty much it obviously
here we're not doing anything with customer
5658.54 -> and that's because we are going to in
a second right so this customer will
5664.12 -> contain so I think is it this customer so
select by D where do we perform the mapper
5675.34 -> so let's have a look yes I think we
need to even map this customer in here
5682.12 -> so yes absolutely right so here let's just say
dot and then map and then I think it's close and
5691 -> then I think it's customer roadmaper cool so
then this will basically gives us a bunch of
5697.36 -> fields excluding the password and stuff that
the client doesn't really need to know right
5704.62 -> so we'll touch on this next but basically
this is the implementation next before we add
5713.32 -> the profile image to the database let's quickly
open up the test class so customer service test
5720.64 -> and you can see that this basically it's
complaining now so let's just take this
5727.78 -> and basically put it on a new line like this and
what we need to do really so quickly is have a
5737.86 -> mark so I'm going to say at and then mock for
the S3 service so S3 service and also a mock for
5749.8 -> the so private and then S3 and then buckets cool
so we're not even writing tests at this point
5760.3 -> because we're not done but I just want to make
sure that we fix the compilation error cool so
5766.9 -> now that we have everything ready next let's worry
about storing the profile image ID to the database
5781.54 -> cool let's go ahead and shift our attention in
terms of storing the profile image ID to the
5789.58 -> database so we want to take basically this value
in here and then store it against the customer
5799.54 -> that we upload so that when we perform the get
in here we know exactly the key that needs to be
5810.04 -> assembled in order to download the latest profile
image so the first thing that we're going to do
5817.24 -> is open a project and open DB migration and
inside we're going to have a second migration
5827.26 -> so I've just copied or in fact let's just
right click new and then do we have SQL in here
5837.1 -> so SQL no I don't think I can search but basically
let's just say V and then 2 underscore underscore
5848.44 -> add underscore customer Pro
file and this score image
5861.4 -> and then dot SQL cool so this is the SQL in here
and what we want to do in here is simple so alter
5873.88 -> table customer so this is the name of our table
and then we're going to say add and then column
5882.88 -> and the column in here will be profile
and the score image and the score ID
5895.84 -> and in here let's just say VAR char and
then 36. so I think that's the value or
5903.28 -> the length of uits so here don't even
say not no because that's not the case
5909.58 -> right and also this will actually fail because
we have customers with empty profile pictures
5917.62 -> right so this should be something optional
and also I don't want the profile image ID
5922.84 -> to have duplicates so to mitigate against that we
just say alter and then table and then customer
5934.18 -> and here we're going to
say add and then constraint
5942.16 -> and here we need to basically
give a name so this will be
5946.66 -> unique underscore and then profile image ID
and then just say unique and then here so let's
5958 -> basically put it on a new line I think just like
that and basically we have parenthesis and where
5966.4 -> this is unique is on the profile ID just like that
cool and this with semicolon and we are good to go
5977.92 -> cool now let's open up the customer class so
here customer and then class so basically this
5988.18 -> class or this entity and if I put this full screen
so in here what we want to do is so let's start
5995.32 -> with the column so here scroll down and after the
password just say private and then string profile
6008.7 -> and then image and an ID this will be a column
6015.42 -> just like that and here this
will be unique equals to true
6022.38 -> and also we want to do the exact same thing as
we've done with email so here let's just take this
6029.52 -> comma paste that and then this will be the
column that we've just created which is this one
6038.16 -> so where is it this guy here so the
column and what do you call it so we said
6047.7 -> let's just switch this around so profile
image ID and the score and then unique
6056.76 -> so let's take this go back and paste it
here and now we can basically match the
6067.2 -> schema with our entity which is really nice
also so the column actually is this so that's
6074.94 -> the column in here so the same way that we've
done with email nice now let's basically remove
6084.6 -> so we're going to remove the two string in
here we're going to generate this once more
6091.56 -> there we go and also the equals and hash
code let's just get rid of all of this
6100.14 -> and before we create that actually let's just say
get the image profile and also set the profile
6113.4 -> right and now at the bottom let's just create the
equals a nice code so next next next and then next
6124.26 -> and also two strings so two and
then string select all of those
6130.92 -> and possibly we don't need the password in here
but I'll just leave it and this should be it
6140.94 -> and also I want another Constructor with basically
all these so name oh actually sorry this one here
6152.58 -> so ID name email all the way to
gender so let's just take all of that
6158.46 -> so we're going to have another Constructor
that basically takes the string and then
6166.86 -> profile image ID and what we're going to do
is instead of setting these manually we could
6173.94 -> just say this and then pass basically there's no
Auto completion ID name email and then password
6185.22 -> age gender and finally we say this dot
profile image ID equals to profile image ID
6198 -> awesome this is pretty much it now let's
try and start the application so run Main
6206.94 -> let's just run this and hopefully everything
should just work and it failed so let's have
6214.02 -> a look why enable to create constraint on
so it says that the column profile image ID
6224.22 -> not found oh yes so it's not found because so
basically this is the name so profile image ID
6234.54 -> in here so instead of actually not here
but here so I thought it was the SQL
6242.88 -> column in here but now it's the
entity so paste that and then run it
6251.46 -> fingers crossed should just work and hooray
you see that it works and we have an insert
6261 -> which comes from the main class awesome this
is pretty much it catch me on the next one
6272.7 -> cool if I open a project and
remember we have the customer
6277.8 -> not customer dto but customer Dao and in
here so in here we have select all customers
6287.7 -> and basically when we select customers we're
gonna have to select the profile image ID as well
6298.32 -> and also if I open up where is customer service
so customer service in here so we need the ability
6310.14 -> when we upload we want to update the customer
profile image ID with this new one which is
6319.56 -> basically here right so let's start there and then
fix the select So within customer Dao we're going
6328.26 -> to have a new method in here and the reason why
we have this interface is because we are using
6335.04 -> both jpa and jdbc so here let's together
say void and then update customer profile
6348.36 -> image ID in here we're going to take
the ID right so image profile or profile
6359.82 -> and then image and then ID and then integer
6365.28 -> and this is the customer ID
so customer ID just like that
6372.72 -> and let's fix in here so customer
ID so that we are consistent
6379.62 -> and now we need to Implement basically
customer jdbc data access service
6386.64 -> we need to implement methods update so this one is
straightforward and is a symbol AS saying VAR SQL
6397.56 -> and the SQL within it is going to be update and
then customer and then here set and then profile
6413.88 -> and then image and Discord ID equals to and then
a value basically cool so we have basically the
6425.46 -> SQL statement in here and all we have to do is
just say return or not even return because this
6431.64 -> is void so we just have to say jdbc template Dot
and then update SQL and here we have to pass the
6441.42 -> arguments so profile image ID and customer ID
and there we go you can see that this actually
6450.3 -> now is highlighted for whatever reason which
I'm not entirely sure so let's just indent this
6457.86 -> and hold on so I think what I want is it that
it's weird it's at the same level as this one
6467.58 -> no so why why are you playing up IntelliJ so this
is pretty much it now for the other implementation
6477.78 -> so customer dial then we have the jpa so this
is quite easy so let's just Implement methods
6486.9 -> and in here what we are going to do so let me
just expand all so what we're going to do is
6495.6 -> within the repository so customer repository
we're going to have one method in here so
6501.9 -> this will be at and then modifying and at
and then query so we want to have a query
6510.54 -> and the query for this will be so I think this
returns an integer whether it worked or not or
6518.04 -> the number of rows affected actually so here we're
going to let's just say first set and then profile
6528.84 -> and then image ID so we need to receive the
string profile image and then ID and then
6539.76 -> the customer or actually integer customer ID and
within the query itself so this is where we have
6549.78 -> basically jpql so update and I think we can do it
uppercase so update and then customer and then C
6561.48 -> set and then C so the customer dot profile
image ID equals to question mark and then one
6572.94 -> where C dot ID equals to question mark and
then two so this C right here is this one so
6585.06 -> this is how it works and then from here we can
basically access the attributes to perform our
6591.06 -> query cool so now we have this query right here
so set or we can even say update let's just say
6599.58 -> update profile image ID and let's go back to the
data access service scroll down and in here we're
6611.28 -> going to say repository so customer repository
Dot update profile image ID pass in D image ID
6621.72 -> and the customer ID and this is it we also need
so we have a third implementation customer list
6632.4 -> which at this point I think we might just delete
it all together because we're not using this right
6638.82 -> so this is just a static list in here so I'm going
to leave it here just in case you want to play
6645.84 -> around but in here I'm gonna say to do implement
this cool and let me just add an emoji here
6660.12 -> and then this all right cool so this is pretty
much it one last thing that we have to do
6672 -> is within the customer jdbc data so this
guy here within this selects we have to
6681.18 -> select basically the new column that we just
added and that's what we're going to do next
6692.88 -> now let's go ahead and open the customer jdbc data
access service which basically uses jdbc and in
6701.94 -> here when we select all customers let's include
our brand new column called so if I show you the
6710.04 -> migration so this is a new column so let's just
take this command C go back and then paste that
6718.38 -> cool now I think we also need to select it here
comma and then there and so when we insert we
6728.04 -> don't have to insert the new column so also we can
get rid of this right here so we no longer need
6736.56 -> that or in fact it's just because of this right so
we can get rid of all of that so we don't use that
6743.64 -> cool so let me just scroll down so exists we don't
need delete also so at this point I'm going to or
6753.3 -> you know what let me just leave the results there
cool so maybe for debugging purposes but usually
6759.18 -> you wouldn't have these print line statements
so let's scroll down update customer all good
6767.94 -> So In Here Also select user buy and then email
we want to select the new column just like that
6778.02 -> and we have this brand new method that we
just added update customer profile image ID
6785.82 -> now what we want to do is
the following so we want to
6794.34 -> change so if I show you where is it so we have
the customer row mapper So within customer
6801.6 -> real mapper we have to change it slightly so
now here we need to include the new column
6809.82 -> so here say comma and we're going to say RS Dot
and then gay string and then paste the new column
6820.86 -> now remember we have this new Constructor so this
one here that we added so that's the reason why
6827.22 -> we did this so that we can also provide the
profile image ID cool and I think this should
6836.52 -> be it we'll run the tests and if there's any
failures we'll fix them in a second but I think
6843.78 -> this should be it if you have any questions drop
me a message otherwise catch me on the next one
6854.64 -> all right so let's go back to our to-do's in here
so within upload customer profile image and their
6862.38 -> customerservice.java and let's fill in the gaps
but as I said we'll focus on testing and make
6868.86 -> sure that basically everything is working so in
here what we have to do is we have to basically
6875.1 -> store the profile image now the way we're going to
do this is by invoking the Dao so customer Dao Dot
6886.62 -> and then update and then customer profile image
ID so you see how this is coming together so here
6895.56 -> the profile image ID is the profile so profile
image ID just like that comma and then customer ID
6907.08 -> cool so basically what we do is
we check if the customer exists
6913.08 -> then we generate the profile image ID we store
that within AWS if this fails then we don't update
6921.72 -> if this exceeds we basically reflect that in the
database and when we get the profile image in here
6932.4 -> we have the customer we perform a select customer
by ID we have the customer row mapper so customer
6942.54 -> dto row mapper if you look into this guy here
this needs the ID so let's just here say comma
6952.68 -> and then customer Dot and we have the profile this
guy here now obviously the dto itself right so the
6965.04 -> dto itself doesn't have the ID so let's go into it
in here and we can refactor let's just refract it
6975.9 -> like so so right click and then refactor change
signature in here I'm going to add so add so
6985.56 -> click on the plus sign so this will be string and
the name is customer profile [Music] or profile
6999.36 -> image ID and for now let's just refactor
this cool so basically indent things
7008.96 -> and now so wherever we use the dto and you can
see that there's a bunch of tests in here that
7015.92 -> we might have to go into and change this around
but if I go back to customer detail mapper now
7023.12 -> you can see that this error went away now let's
go to customer service and within customer service
7031.04 -> in our beautiful method in here so we get the um
customer here so at this point we map the customer
7041.42 -> to the D dto and now here we have the profile
image ID so what we can do is so in here let's
7053.36 -> just get rid of this all together and then put
it here so customer Dot and then profile image ID
7063.26 -> and also we want to check right so if
so if for whatever reason the customer
7073.1 -> and then Z profile image ID so
here I think we can say is and then
7084.26 -> blank in here so if it's blank right we
basically throw so we're going to throw
7092.72 -> new resource not found exception and then let's
just take this put it here on the new line
7104.54 -> and I want to say customer so customer
with ID and then blah and then profile
7116.72 -> image not found instead cool and this is pretty
much it so obviously here if you want I think we
7126.44 -> can change this to a VAR so I wanted to use vars
throughout this so yes we can and also if you want
7134.36 -> you can just return but let me just keep this as a
byte array so that you know the data type for this
7141.86 -> cool as I said if you want you can inline this if
you prefer just like that I think it's better but
7147.26 -> for readability I'm going to leave it as so and
this is pretty much it catch me on the next one
7160.58 -> cool before we move any further let's just
try and run all tests in here so let's open
7168.8 -> up tests and not the integration tests for now
let's just run all the tests and the customer
7176.6 -> so I want to make sure that everything works
and yes so we have a compilation error which
7182.54 -> we have to fix and that's expected because
of the dto so in here remember so I said that
7190.82 -> so have a look so we have the customer dto
so this guy in here I think is going to be no
7198.44 -> so there's no profile image there if I press
f2 this takes me to the next error so have a
7206 -> look F2 next highlighted error and this
also is the dto so I'm going to say no
7214.52 -> just like that and let's
try and run the tests again
7222.44 -> cool so I think that was it
now it's running all tests
7229.16 -> and everything passed apart from the row mapper
now this roadmaper let's have a look why it's
7236.6 -> failing so click on difference and it looks
like the password is null and the profile
7250.64 -> so okay so this is no so why is it a password no
so I thought that we had this fixed but maybe not
7261.5 -> so let's just in here let's go to the customer
row mapper so command e customer row mapper
7273.02 -> and in here so we made a change to include the
profile image ID that's fine if I open up the
7281.48 -> test class for this so we didn't change the
test class so here we don't have the password
7291.62 -> right so I think that we forgot to add the
password before and if we look into the customer
7302.48 -> so probably it's because
now the two string contains
7308.3 -> basically everything right so what we are going
to do now actually so let's just basically say oh
7317.9 -> in fact we should have actually so if you look
into customer row mapper RS dot string right
7323.66 -> so this is actually returning no okay so that's
why it's now so let's fix this so let's here say
7331.7 -> basically duplicate this and
then when and then password
7338.36 -> so we want to return password just like that
and also so yes so also we're not even comparing
7352.04 -> the new column right so if you want you can
basically add it as well so this was customer
7361.52 -> or actually it was a customer so what was it
so here profile image ID so profile image ID
7371.42 -> and then here I'm going to say basically I'm going
to say profile image ID or actually let's say one
7378.86 -> two or two two two five twos cool so this now so
we can change this to B five twos and let me just
7390.08 -> put this all in a new line just like that so this
is much better oops like this like this and let's
7402.86 -> now try and run tests so in here click on run
and I want to run only the failed tests for now
7415.1 -> and yes so this works cool so let's
run all tests once more so in here
7424.1 -> I think yeah so if I close
that let's run all tests
7429.62 -> just to make sure not that but all tests so
open project and then this will be customer
7440.48 -> there you go I think yeah so 38 tests should
pass Bingo and now let's basically run everything
7451.28 -> including integration tests so at this point
make sure that your database is up and running
7459.02 -> with docker so the integration tests I think
they they run already yes one of them did and the
7468.08 -> authentication ID or the authentication ID also
run and you can see that we do have every existing
7476.66 -> Test passing cool so one thing here so customer
service so this guy in here so customer service
7486.86 -> so not the test but the actual class so we have
get customer profile and also upload customer
7495.86 -> profile in here and within S3 so S3 where's
S3 so Java not on the test so in here so S3
7509.12 -> buckets so this doesn't need any tests S3
config probably this doesn't need any tests
7517.58 -> and S3 service so this we can test this
here as well right so next let's go ahead
7525.8 -> and focus on testing so we're going
to write unit as well as integration
7532.28 -> tests if you have any questions drop me a
message otherwise catch me on the next one
7542.06 -> testing is something which is kind of out of
the scope of this crash course but yet very
7548.96 -> important so you saw that we wrote lots of
code but how do we guarantee that the code
7554.36 -> that we wrote does work well we have to write
tests okay now I always ask this question would
7561.38 -> you ever board on a plane that hasn't been tested
and the answer is absolutely no right so there's
7568.22 -> no chance that you'd risk your life so it's
the same thing with software so in this crash
7572.72 -> course I'm going to skip testing all together
um the actual videos but I'll show you that I
7579.74 -> actually you know tested the entire thing
including unit testing mocking as well as
7584.78 -> integration tests right so this is the beauty so
once you test everything then you have you know
7591.56 -> um you know you're a bit confident um in the
sense that you know that your code will work
7597.98 -> if you deploy to an environment such as
development or testing or production so
7604.82 -> make sure to test your code and as part of the
full start course I covered testing from the
7613.04 -> ground up and basically everything you need
to know about testing but testing is out of
7618.62 -> the scope of this crash course so um yeah this
is pretty much it and catch you in the next one
7630.38 -> if you've managed to get this far in here what I'm
going to do is the following so let's look at the
7636.68 -> stop this and open up the terminal and in here
what we're going to do is we're going to say git
7645.26 -> checkout and then Main so basically this now will
contain all the tests so I'm not showing you how
7653.78 -> to write all the unit tests as well as integration
tests but I just want to show you that we do have
7660.14 -> a bunch of tests in here so I'm gonna leave things
as this in here and so the changes that I've made
7668.78 -> so if I open up the test folder and then S3 you
can see that we have a bunch of tests in here
7676.52 -> and also for customer we change things and we
tested everything fully as well as an integration
7683.36 -> test under so under Journey and then customer ID
and if I scroll down in here you should see that
7691.46 -> we have so if I scroll down in here so can upload
and download profile pictures and basically we
7701.24 -> test all of this now I would say from this point
onwards right so everything should just work the
7707.6 -> same so when we deploy things but if you want to
see how I wrote the tests and whatnot just check
7714.62 -> out domain and then Carry On from there okay so
in here so let me just basically run all tests
7722.6 -> and you'll see that whoops so in here
why isn't this working right okay cool
7730.46 -> so let's together click on file and then
invalidate caches and invalidate and restart
7740.66 -> there we go and hopefully this should
fix itself just give it some time now
7745.82 -> cool still that didn't fix so let's
try to in here reload the project
7755.72 -> and there we go cool so that fixed the problem
so this sometimes you'll encounter these issues
7763.46 -> so here we've just fixed during the course which
is awesome and cool so let this finish and now
7772.46 -> we are able to run the tests so let's just run all
tests and tests it's vital in any application okay
7782 -> so if you don't know testing so I'll urge you
to learn about testing so you can see 56 tests
7789.92 -> and everything just ensures that we have the
correct implementation awesome so this is pretty
7798.98 -> much it if you have any questions on testing
as always you can ask and I'll try my best to
7804.98 -> advise you otherwise you can check the courses
that we have on testing and as part of the full
7811.52 -> stack where we learn where you learn all of this
I'll show you how to basically test so in S3 what
7819.92 -> we've done is we created a fake implementation
which is used for unit testing purposes so this
7827.12 -> actually stores images in our local file system in
here you can see that this is the implementation
7833.48 -> for basically running the application locally
without us having to connect to AWS directly
7840.2 -> cool I'm going to leave it here let me just close
this and this as well and this is pretty much it
7851.78 -> what I want to quickly mention is if you
want to upload larger files you need to
7857.9 -> configure the application.yam also and the spring
7862.46 -> and then have the servlet and then here include
multi-part Max file size Max request size and
7871.28 -> also Max in memory size so with all of this
you will be able to work with larger files
7878.06 -> so in my case 10 MB is absolutely fine but if
you are uploading videos and other files then
7886.58 -> you might to increase these numbers so go ahead
and add these so that you can work with larger
7892.28 -> files and actually before I go let me just show
you that the default so max file request size
7898.52 -> so the default is 1 MB in here the same for
this one oh this one is actually 10 MB and
7907.4 -> then the max in memory is 256 kilobytes awesome
this is pretty much it catch me on the next one
7923 -> for this section what I want to implement is the
ability for us to update the profile in here so
7930.86 -> if I click on update and what we want to have is
the ability of dragging and dropping any picture
7937.88 -> in here so if I basically get these pictures
that I have in here and this is Maisha and it's
7945.74 -> a male and let's say that here I want to take
this picture and then upload just like that so
7950.96 -> I can drag it actually in here or I can click
in there but eventually this should upload so
7958.52 -> I think it was my issue so let me just search for
Maisha there we go and you can see the animation
7964.1 -> now in here has the picture updated so again if I
click on update you can see that the picture now
7972.02 -> it's present in here and I can basically click
in here and this will bring the pop-up where
7978.68 -> I can where I can select pictures if I cancel
and basically this is what we want to achieve
7989.84 -> in order for us to upload files or in
our case a profile image from our react
7996.5 -> application to our backend we're going to
use this Library called react Drop Zone
8002.98 -> so this is a library that basically makes it
super easy to create drag and drop zone for files
8010.72 -> and in here you can see the usage and you can
find the link in the description of this video
8015.04 -> but basically it's very simple and you
could just use the hook in here or the
8020.68 -> component and then you have the ability
of uploading files to any destination
8028 -> so let's go ahead together and install the react
drop zone so let me just take this command in here
8036.7 -> go back to IntelliJ and within IntelliJ if I
open up the terminal and in here we can open
8042.94 -> a new session and let me CD into front end and
then angular and then react and inside let me
8053.5 -> just paste the command so npm install and then
dash dash save react and then drop zone press
8060.1 -> enter and to be honest this is pretty much it next
let's go ahead and learn how to use this Library
8074.92 -> cool you saw when we run the back end we
basically get a customer which is added
8080.98 -> to our database so in here let me just take
this customer and this is from the logs from
8085.84 -> our spring blue application and let me first
log in so here localhost and then colon 5173
8098.8 -> and I want to add the email that I've just
copied and the password is just password
8105.1 -> and then login and here if I go to customers you
can see that we have Christopher and basically
8111.76 -> this is what we want to implement right so
Christopher um basically this is a random name
8118.24 -> which is generated but basically this picture
right here is randomly generated and we want to
8124.78 -> have the ability of when we click update and here
we want to have the Drop Zone component in here
8132.16 -> so that we can upload a picture to our backend so
let's open up this component in here and add Drop
8141.34 -> Zone and in here if I Collapse this and then open
up the front-end folder we have react and within
8150.76 -> react we have SRC components and then customer
and in here we have the update customer drawer
8158.98 -> as well as the form so what I'm interested is the
form itself so here let me just collapse this and
8166.36 -> if I scroll down you should see that we have the
form itself in here update customer form now here
8173.56 -> at this point is where we want to add the Drop
Zone component so actually just before here so
8181.36 -> basically if I say H1 for example in here and then
say hello go back you can see that we have hello
8190 -> in here right so hello but we want this to be the
Drop Zone where we basically can upload a picture
8197.979 -> So within the documentation for Drop Zone you can
see that the usage is quite straightforward so
8203.8 -> they basically give you the option of using the
hook or the wrapper like so so what we're going
8211.84 -> to do is let's it doesn't really matter which
one you use but let's use the hook in here so
8218.14 -> just take this in here so take this command C and
you can find this in the description of this video
8226.24 -> and then go back and just before this form let's
have the drop zone and by the way so this right
8235.479 -> here I'm not going to have it as a component so
that you can reuse it I'll leave that up to you
8241.18 -> so I'm just going to leave it in this file for
now so this is where we need it so I'm just going
8245.8 -> to leave it here so here I'm going to leave the
name as my drop zone you can rename this if you
8250.84 -> want then we have to import the use callback so
let's just import that and use drop zone as well
8260.08 -> so let's just import that from react Drop Zone
just like that and this is pretty much it so now
8268.479 -> at this point let's also so rename this so drop
the and then picture here and then drag and drop
8279.16 -> and then picture here or click to
select picture select and then picture
8287.38 -> there we go so this is much better
and what we're going to do for now is
8293.62 -> take this so actually let's just change this
from const and then my drop zone equals to
8303.64 -> so basically equals to a function this is an arrow
function actually and this is much better cool so
8311.439 -> now let's basically in here instead of hello
we're going to say my drop zone just like that
8318.22 -> and this can be a self-closing tag so let me just
remove all of that there we go and if I open up
8326.26 -> my web browser now you can see that it says drag
and drop picture here or click to select picture
8333.46 -> so basically I can drag a picture or I can click
to select so here if I select or click my bad you
8342.64 -> can see that it opens the window Explorer where
I'm able to pretty much just select any picture
8350.02 -> cool let me cancel out of this next
let's style this component in here
8361.359 -> all right let's change this component so it looks
a little bit more appealing so let's open up
8366.82 -> IntelliJ and within IntelliJ if I open up my drop
zone in here and what I want to do is you see here
8375.28 -> we have this div in here so I'm going to change
this from a div into a box in here so just say box
8385.54 -> and this comes from Chakra UI and at this point I
can basically customize it so here so here within
8397.359 -> here basically within the Box itself right so I
want to add the width so w and this will be equal
8408.1 -> to 100 and then percent I also want to align
so text and then align and this will be Center
8418.06 -> and let me just format things and also let's add a
border oops Border in here and the Border will be
8428.08 -> dashed let's also Define the border and then color
so border and then color and this will be Gray
8439.359 -> and then let's say great.200 let's also add
some padding and here I'm just going to say six
8446.859 -> and you can basically fine tune these numbers
according to your liking let me also say that this
8452.26 -> box will be rounded so rounded and here I'm going
to say let's just say MD for medium So within
8462.1 -> quotes just like this and also the Border radius
so border and then radius so this should be in
8475.479 -> here so color and then the radius so this should
be something like three Excel so three Excel
8485.62 -> all right so let me just put that in there
like so now scroll down where we actually
8492.04 -> use the Drop Zone let's cut this and I'm going
to encapsulate this within a V and then stack
8500.859 -> just like that and within this v-stack let's
add some spacing so you can say spacing
8508.12 -> and here I'm going to say five let's also
add margin and then bottom so MB and this
8516.64 -> will also be five now if I paste the Drop
Zone like so and let's basically save this
8526.78 -> go back and you can see how this is
looking so it's looking really beautiful
8532.24 -> so let's also add an image in here in case there
is one so let's go back and in here I'm going to
8541.18 -> say image so make sure this comes from Chakra as
well and in here we can basically pass few things
8549.399 -> so one is the Border and then radius so this will
actually be full so I want this to be completely
8557.979 -> a circle and then box and then size let's say 150
pixels so 150 pixels like so and object fit so if
8571.84 -> the image is too big I want it to fit basically
so I'm just going to say cover so cover and we
8580.72 -> also need the SRC which we'll add in a second but
this is pretty much it so I think for SRC we need
8590.26 -> to add an empty string in here cool if I go back
to Chrome you can see that basically we have this
8597.58 -> circle in here which is an empty image and when we
drag and drop the picture this right here should
8605.14 -> be reflected next let's take the picture that
we upload in here and save it to our backend
8617.38 -> cool The Next Step that we need is when we drag
the picture in here or when we select the picture
8623.74 -> to upload it to our backend and then from our
backend it goes to S3 or to our local file
8631.06 -> system depending on the implementation so let's
open up IntelliJ and within IntelliJ let's open a
8639.28 -> project and within project open services and here
client and in here we're going to have two methods
8648.939 -> so let's basically say export and then
const upload and then customer profile
8660.7 -> and then picture and equals to A sync and in
here we need to take the ID and then the form
8669.819 -> and then data so basically I'll show you this
in a second so when we pass the information but
8679.54 -> now let's say try and within this try and catch
block we're going to return the acios so acios
8688.84 -> Dot and then this will be a post and let's
take this right here so this will be the same
8697 -> across basically everything say back ticks
and within backticks have the dollar sign
8704.979 -> and then curly bracket and then paste oh
actually I just had it there just like this and
8711.1 -> then say forward slash API forward slash and then
customers forward slash V1 forward slash customers
8723.1 -> and then dollar sign oh actually
forward slash and then dollar sign ID
8729.7 -> and what we need so let me just
put this on a new line like this
8737.56 -> there we go so then we say forward slash and then
the end point which is profile Dash and then image
8746.979 -> so this right here is the
controller so here remember
8754.3 -> the customer controller in here
customer ID profile image let's go back
8761.92 -> and in here so let's just say comma and we
need to pass the form data as the payload and
8770.92 -> also the headers so here this will be an object or
actually the config which is going to be an object
8778.66 -> and basically I want to get the token
so say dot dot and then get auth config
8787.06 -> but also what I want to add is so here I want to
add content and then type so content Dash type
8799.96 -> and this will be multi-part
forward slash form and then data
8809.5 -> so have a look so if I open up customer
controller this is exactly what we've
8814.72 -> done before multi-part form data so here
I'm just specifying on the client as well
8821.979 -> and this should be it now let's basically end this
with semicolon and we're going to basically catch
8831.16 -> e and at this point I'm going
to throw oops not tribe throw
8839.5 -> and then e and it's as simple as this
8844.3 -> cool next let's use this method
within our Drop Zone component
8855.939 -> okie dokie so let's open up the update
customer form and inside of our Drop
8863.08 -> Zone in here so instead of the job Zone
you can see that there's a method on drop
8870.46 -> so on drop has the accepted files and what
we are interested is in just one file right
8878.08 -> so basically we just upload one file and process
that so what we're going to do is we're going to
8884.02 -> use our method called upload and then the profile
picture in here and we need to pass the ID so
8894.46 -> let's just say ID which we don't have and I'll
show you in a second how we're going to pass that
8899.319 -> and then the form so form and then data which
we also don't have and I'll show you in a second
8908.74 -> all right so what we're going to do is the
following so in here we need to create first
8914.92 -> the form data object so const and then
form data equals to new and then form
8924.16 -> and then data like so and within form data
so I'm going to say form data dot append
8932.08 -> the file so file and then comma and then accepted
files and I want to grab the very first file
8941.439 -> just like that and this is basically the
form data now this name in here so name
8950.26 -> file is basically what we accept in here
multi-part file the request param which is
8958.42 -> file so it has to match with a client sense
so if I go back in here and now we need to
8968.2 -> pass the ID now the ID will be passed as a prop
so basically have curly brackets and then say ID
8977.2 -> and the way we get the ID now is so in here
where we use the drop zone so in here have a look
8986.08 -> update customer form fetch customer initial
values customer ID so here let's just say customer
8995.74 -> or actually ID and this is customer ID
and in fact let's just call it customer ID
9006.06 -> so where is it so customer ID so now you can see
that this Drop Zone actually is mainly focused
9014.939 -> on customers right so I'm not refactoring to be
generic because I don't have to at this point
9021.84 -> I just needed to upload profile pictures but
if you want to refactor go for it so here we
9028.5 -> need to also pass the customer ID instead
of ID and job then now this is complaining
9036 -> because we need to say dot and then then so if
basically we have the response so R in here or
9044.22 -> res which I'm not going to do anything with it
so I'm just going to say success notification
9052.5 -> and then I want to say success and
let's just put this on a new line
9059.7 -> just like this success notification that's
the title and then I'm going to say profile
9070.979 -> and then picture uploaded so if this fails
so then and then here I'm going to say dot
9082.14 -> and then catch and here basically the error and
if there's something wrong with it this actually
9091.979 -> has to be like this so air and if there's
something wrong with it I'm just going to say
9099.899 -> I think it's Error notification yes air
notification and here I'm just going to say failed
9107.399 -> or error it doesn't really matter you can
choose whatever message you want for the title
9112.56 -> and description so profile picture upload
and then oh actually let's just say failed
9118.8 -> failed upload and it's basically like this
right and also if you want you can say log
9126.54 -> and you can log the error to have more
visibility but for us I'm going to remove
9133.319 -> all of this in fact and also the response so
we're not doing anything with it so we just
9139.68 -> leave it as is and to be honest I think this is
pretty much it next let's go ahead and test it
9152.819 -> and see whether we have uploaded a
picture for this customer in here
9159.3 -> So currently it's not storing to S3 because the
implementation is to store in my local machine so
9166.56 -> in here I'm within the database and if I say
select and then start from and then customer
9175.8 -> and let me just say backslash X and then run the
exact same command and you can see that we have
9183.78 -> the profile image ID in here and the customer ID
is 43. so let me just open a new shell like so
9193.62 -> and I'm going to CD into so basically dot Amigos
code and then S3 and inside we have the folder
9206.58 -> or basically this is the bucket name and inside
we have profile images and inside we should have
9216.66 -> so here if I say LS you can see that these are
all the IDS and we should see 43 in here so 43
9225.06 -> so here I'm going to say CD and then 43 and inside
LS this right here is the ID of the picture itself
9236.939 -> so if you look at this ID is the exact same
thing as this one in here and this actually
9243.78 -> is our profile picture so if I basically say
open Dot and this brings the window Explorer
9251.52 -> and if I select this image and then press spacebar
you can see that hooray it did work cool so let me
9261.42 -> basically cancel out of this and out of this and
the next thing that we need to do is basically
9269.46 -> we also have to close this and then fetch the
customers but we'll do that later but let's
9275.1 -> basically get the profile picture back in here so
here you can see that we need the profile picture
9282.42 -> in here and also if I close this in here also if
I click on update and what I want to show you is
9290.88 -> so if I bring the file explorer in here let's try
and basically drag and drop so you can see that
9299.58 -> also works so we can click but also
we can drag and drop so if I drop
9305.04 -> you can see that profile picture updated or
uploaded my bad and if I open up the terminal
9312.479 -> and if I press LS now we have two pictures in
here and they are both the same cool so I'm
9322.56 -> not going to open this one because they are the
exact same pictures and you can see that this
9327.72 -> is working if you have any questions drop me
a message otherwise catch me on the next one
9337.5 -> cool in order to see our profile picture that we
just uploaded in here and also in this card we
9345.66 -> need to do the following so let's open up the
client.js first so here client.js and what we
9354.54 -> need is so let's just take this right here and
we're going to say export and then cost customer
9365.64 -> profile and then picture and then URL equals to
and here we need to pass the ID of the customer
9378.84 -> and so on a new line I'm going to basically return
the URL like so so basically this will be the ID
9390.359 -> and I need to remove that
and this is pretty much it
9397.5 -> now I think I need basically oh actually not
that but I need to remove the return from here
9404.34 -> cool so on a new line so this will gives us the
customer profile picture URL and you can even say
9411.54 -> get in here if you want but now let's open up the
update customer dual form and in here so where we
9421.319 -> have my drop zone so if I scroll down my drop
zone remember we have the SRC so here I'm going
9430.92 -> to say get or actually we call it customer profile
picture URL and then pass the customer ID inside
9443.939 -> and let's import this so insert import at the very
top and we go to go let's open up the web browser
9453.24 -> and if I click on update check this out you
see that the picture is in here which is cool
9460.62 -> now let's close this and also add it in
here so let's go back to IntelliJ and
9469.2 -> that will be part of the customer card and
within customer card we have the Avatar in
9478.14 -> here and the Avatar now will be so the
SRC for the Avatar will be so in here
9487.439 -> customer profile picture URL and then we have
the in here I think it's just the ID so this ID
9499.319 -> and we just pass it yes that's the ID so we just
pass it where is it Avatar I lost you so in here
9510.72 -> ID there we go save let's go back and check this
out so this is beautiful stuff so if I click on
9520.2 -> update you can see that now we do have the profile
pictures in place next let's go ahead and fix the
9527.46 -> fact that when we upload a new profile picture we
should have the UI reflected on the new changes
9538.2 -> cool the last thing that I want to do is in here
when we update the customer so in here with the
9545.819 -> new profile what we want to do is basically
invoke so we should have done this before but
9551.28 -> that's fine so fetch customers have a look so
in here we use fetch customers like so and also
9562.2 -> think we do close I think
we do close the model Maybe
9569.22 -> but let's go ahead and do this so here
all we have to do really is basically
9576.24 -> pause the fetch customer so here
we're going to say fetch customers
9582.899 -> just like that and then inside so where we
have fetch customers so we also pass it so
9590.46 -> fetch customers equals to fetch customers
and let me put this on a new line like this
9599.399 -> all right so in here I think this is much better
9603.84 -> and and then things like this cool so this is
looking good now let's go to our my drop zone
9612 -> and upon success upload we want to invoke Fetch
and then customers like this and there we go
9623.34 -> so I'm really bad with JavaScript so here
I'm missing a bunch of semicolons and you
9630.06 -> know with JavaScript this is actually optional
so you'll see that some places I do have like
9634.92 -> here and other places I don't cool so this is
when a backing engineer works with JavaScript so
9643.26 -> let's now test these changes so in here I do have
basically a new picture so if I click on update
9651.6 -> and let me bring this picture so here female and
then two I'm going to drop the picture in here
9660.3 -> and you can see that now it updated the picture
and we are pretty much done so here update
9668.52 -> and you can see that the picture now has
been reflected and this is pretty much it
9675.42 -> next let me show you something which I
forgot to change on the back end early on
9685.979 -> the last thing that I want to do is if I right
click on this picture inspect and in here so let
9692.58 -> me put this bigger so you see so if I scroll down
you can see that we have the image source in here
9698.58 -> and I can click on it so if I click on this you
can see that I do get gibberish basically right
9705.899 -> so this is the byte array that we get back so
what I want actually is when someone visits
9715.08 -> this link right here then we want to display the
actual picture well to fix that on the back end
9722.04 -> all we have to do is within customer controller
in here so have a look so we have in here get
9731.16 -> customer profile image and here get mapping say
comma and then inside say produces and when the
9741.24 -> ad produces it adds a value to the endpoint URL
and here we can say a media type Dot and you can
9752.88 -> choose PNG or jpeg it doesn't really matter there
we go indent things and let's reload the back end
9765.66 -> there we go so now we have a new customer let's
go back and if I reload this same picture in here
9777.78 -> you can see that now we get the profile image in
here and also in here so if I basically close the
9784.74 -> console close this we have a new customer you
can see that this other customer doesn't have a
9792.359 -> picture so this is actually a male so let's just
say update and here I'm going to click this time
9799.979 -> and then mail open and check this out so this is
nice if you have any questions for what we've done
9809.34 -> in this section feel free to let me know otherwise
next I'm going to deploy all of these changes
9820.5 -> all right now let's deploy these changes
and watch our CI CD pipeline take action
9827.16 -> for both the back end as well as the front
end so in here let's open up IntelliJ
9833.22 -> and I'm going to commit these changes
so here I'm going to basically
9838.74 -> commit through IntelliJ and what I'm going to do
is I'm going to say react Dash and then profile
9854.22 -> picture and then uploads there we go so commit
and we also change the back end but that's fine
9865.5 -> which is basically these changes in here
for image JPEG value and I'm going to push
9874.319 -> and this will push straight to
Main and in here I need to rebase
9883.859 -> give it a second awesome now let's watch the
changes being deployed so in here of course
9891.899 -> slack and this is the repo if I go to code you can
see that we have now react profile picture upload
9902.819 -> so this will trigger the backend CI CD now you
can see that deployment Started Black profile
9910.38 -> picture building with Maven so while this is doing
this what I'm going to show you is so this is
9917.1 -> the back end so if I open up AWS console so in
here within the console if I go to AWS amplify
9927.84 -> and we have the full stack course and then react
9934.26 -> and now you can see that so
basically oh I think already deployed
9944.46 -> no it hasn't right jobs failure oh wow all demos
never go according to plan so it must be like an
9953.7 -> integration test so let's open up IntelliJ
quickly and in here so I do have so project
9960.78 -> and let's close this go to the back end and
that's because of this so we've changed this
9966.24 -> and we didn't update the tests so SRC test Java
and then basically the customer I.T in here
9979.38 -> so let's just right click and I know that is
this test basically so let's just run this test
9989.28 -> so just give a second and you can see
the benefit of CI CD right so this fails
9995.64 -> and it says so in here if I
scroll down right 500 no content
10006.5 -> right no acceptable representation that's fine
so I know exactly what it is and even IntelliJ
10012.979 -> will tell me so intelligence telling me that
it's failing right here now remember we change
10018.2 -> this from I think before it was application.json
the default but this now is jpeg so J and then Peg
10027.319 -> and if I run the test again I think
this time should work fingers crossed
10035.6 -> hooray cool let me just
basically commit this as well
10039.8 -> and bear in mind that I'm not using pull
requests in here so fix and then test
10049.1 -> there we go commit and push
10053.54 -> and then push
10056.66 -> and let's watch it again awesome so in here so
if I refresh this you can see that we have the
10064.399 -> new commit hopefully this time we should just
pass there we go it kicked in building with
10070.58 -> maven and at this point basically I can even show
you so if I go to actions you can see that this
10078.439 -> is running and deploy and you can see that still
building oh okay so you just push the docker image
10088.04 -> right here and now it's deploying to elastic
Beanstalk so hopefully this should also pass
10095.06 -> and you can see that all the tests actually passed
so if he reaches this stage it means that all the
10100.34 -> tests did pass so just wait a minute or so and
hooray you can see that this was success awesome
10109.46 -> now let's open up AWS amplify and in here you can
see that the full stack course react is running
10118.28 -> so you can see the last deployment
which is literally just now
10122.12 -> and to be honest this is pretty much it next
let's go ahead and test our deployed application
10134.96 -> cool let's go ahead and test this so in here um
not in localhost anymore so this is localhost and
10142.939 -> this is the live application full stack react
and then Dot amigoscope.dev and you can try
10149.06 -> this for yourself as well so let me just log in
with this user in here and feel free to sign up
10155.42 -> and create an account if you have to I'm going to
log in and bad credentials okay so I think I need
10163.1 -> to create a user so let's just say in here uh
Foo and then bar and here I'm going to say full
10172.34 -> bar 2000 so hopefully nobody picked
this name at and then amigosco.com
10180.26 -> let me just take this just in case
22 the password will be password
10186.979 -> so feel free to hack my account and the mail
submit and cool so now let's go to customers
10195.859 -> and hooray you can see that this is working
beautifully so let's in here update so we're
10204.38 -> gonna try hold on let's if I refresh do
we get the same user so two nine eight six
10210.8 -> refresh 2986 cool so let's just update
and in here let's just grab a picture
10220.399 -> and Aussie two it's a male so let's just put
Amigos code in here and oops it worked but
10232.939 -> so the customer went I don't know where because
there's so many people in here trying to use the
10238.04 -> application so what I'm going to do is I'm going
to oh actually I was going to delete everyone but
10245.24 -> here it works hooray we've done it so this is cool
so let's try let's see any females in here so V
10259.16 -> male no I think yeah I think yeah no
females so basically we could just
10266.84 -> add a picture anyways so Lorraine in here
update and we're going to add this picture
10276.2 -> there we go and it worked you can
see that Lorraine is right here
10284.06 -> and you can basically take this picture also
so we can basically inspect and we can grab the
10293.84 -> URL so here I can click on it and you can see that
this is my picture and it's coming live from the
10302.06 -> API which is under https and everything is working
beautifully awesome I might delete everyone and
10311.06 -> add maybe some logic to say delete everyone after
I don't know maybe 24 hours or something like that
10318.92 -> so that there's not many people so there's over a
thousand people here which is crazy cool this is
10327.5 -> pretty much it and if you have any questions
on what we've done throughout these last few
10334.1 -> sections as well as the exercise feel free to
let me know otherwise catch me on the next one
10344.3 -> okey dokey if you enjoyed this video literally
just smash the like button comment down below
10349.64 -> let me know what other things that you want to
see next and I'm going to leave a coupon code
10355.34 -> in the description of this video so that
you can take benefit and you know learn
10361.1 -> the full-time professional course that I have
for you which is a course that is changing
10366.439 -> lives many people are managing to secure jobs and
people that work for companies meet developers
10373.04 -> senior developers all are benefiting from this
course so this is a course that you won't find
10380.6 -> anywhere else apart from a vehicle's code this is
pretty much it and I'll see you on the next one
Source: https://www.youtube.com/watch?v=9i1gQ7w2V24