Full Stack Development with Java Spring Boot, React, and MongoDB – Full Course
In this course, you will learn how to create a full stack application using MongoDB for the database, Java and Spring Boot for the back end and react for the front end. Farhan Hasin Chaudry teaches the back end section of this course. And Gavin Lon teaches the front end section of the course. Both these instructors are very experienced and have created many popular courses. The project featured in this course is a great example of the creation of a separation of concerns between the client code and the server code. By implementing a loosely coupled architecture. These two parts
implemented using different technologies can evolve in parallel and independently from one another. So let's start learning from Farhan. Hello, everyone. Welcome to the Java with MongoDB course on the freeCodeCamp YouTube channel. I am for Han has ensured three one of the instructors in this course and I will teach you all about developing a back end API using Java EE Spring Boot, and MongoDB. The other half of the course will be taught by Katherine lOn. Hi, I'm Gavin
lOn. I'm a full stack developer and have over 20 years experience working as a software developer. In this course, I'm going to be playing the role of a front end developer. And my
responsibility will be to demonstrate building a front end using React js. The Spy application that we are going to create will use HTTP GET requests to appropriately retrieve data from a remote server through communicating with the relevant API's endpoints. And HTTP POST requests will also be made to the relevant endpoints to appropriately save data on the server side. Of course, our data will be stored within a MongoDB database on the relevant remote server. So without further ado, let's jump in and start working on our API. In the beginning of the course, you will have to download two new software's from the internet. The first one
being Java Development Kit, or JDK. If you already have JDK installed on your system, you should be good to go with that. But just in case you do not have it installed, I'd suggest you navigate to oracle.com/java/technologies/downloads The link will be in description. Once you have landed on the
download page for Java, you may find multiple versions of JDK available as of the recording of this course there. The latest version is Java 19. And the latest LTS version is Java 17. lts C stands for long term support and JDK 17 will receive updates until September 2020 For JDK 19 On the other hand, will receive updates only until March 2023 and will be superseded by JDK 20. In many cases, when you are deploying a Java application on a production server, it's suggested that you use LTS release for better stability.
And for this course I will stick to Java 17 Since that's the latest LTS. Now depending on when you're watching this course, there may be a new LTS release so feel free to download and install that. So I've switched to Java 17 And since I am on Windows, I will go to windows and the 64 bit installer. As you can see, it's only 150 2.85 megabytes and
depending on your internet connection, you it may take a few minutes to download. Once you have downloaded the installer, make sure you have installed it on your system like any other software you have done before. And since the instruction is so straightforward, I will not spend a lot of time showing you the entire process. After you have finished installing JDK on your computer, open up your terminal window and write Java C space double dash barsha. And if you don't get any errors from this command, this is a positive sign and as it says Java C 17 point 0.5 which
indicates that I have successfully installed seven point 17 point 0.5 version of the JDK. Now Java C is the short for Java compiler which you may or may not have already guessed. Apart from this command, you can also use Java double dash version to check the version of your Java Runtime Environment and as you can see it says 17 point 0.5 lts which means we are good to go. Since you have successfully installed the jdk on your computer Next up you will need a good code editor or IDE. When it comes to Java, there are plenty of options out there. You can go
into Eclipse or maybe configure Visual Studio code. But I would suggest that you go with IntelliJ IDEA. Now the people at Jet Ian's are known for making really good IDE s and when it comes to Java IntelliJ IDEA is pretty much the industry standard. Although the ultimate version can cost you some money, there is also a free version available by the name of Community Edition. Or to download IntelliJ IDEA, navigate to jetbrains.com/ideas/download. Again, the link could be in description and look for the Community Edition. This is the
flag download button here. And depending on your platform, ie Windows, Mac OS or Linux, you may get a different format. For example, if you're on Mac OS, you will get a DMG image. And if
you're on Linux, you will get a tar file. So I'm on Windows and I want to download the exe installer and not the zip one. So I'll select exe, and then hit download. Now the IDE is a bit larger than the JDK in size at 649 megabytes. But again,
depending on your internet connection, it may take a few minutes to download. Once you have downloaded the software, please go ahead and install it like any other software that you have done before. Congratulations on you're getting the JDK and IntelliJ IDEA getting installed. Next up, you will need an account at
MongoDB Atlas. Now you may or may not already know that MongoDB Atlas is a platform from MongoDB themselves that allows you to spin up MongoDB servers on the cloud. So in order to use MongoDB Atlas, you will have to maybe get to mongodb.com/atlas/database. Again, the link will be in description and use the Sign In button. Once in the sign in page, you can either use your Google or GitHub account to log in or you can sign up with your other email addresses for a new account. Now, I already have an account on MongoDB Atlas. So I will just use those credentials
to log into my account off screen. As you can see, I have successfully logged into my account. And For first time users, you may have to set up a new organization of sore just just put any name as the organization name and you should be good to go. Since we are using these for just our
development purposes, it's okay to just use any data that you have. So once you have set up your organization, you can create new projects. So I will hit the New Project button here. And I have to give my project a name. Now since you are creating an API that is related to movie I'll just call my movie API. And hit Next I will just go ahead and create project since I don't have any other member to add.
Extra now we are inside our movie API project. And we are ready to create a new database. So you can use the builder Database button here to create a new MongoDB database on MongoDB Atlas. So just go ahead and click this button. And there are three different categories there is server list there is dedicated and there is shared. Now for development purposes, our shared server should be fine and it's completely free. But if you're working on an application that
that has some user and have some real life usage, you may go with dedicated Serverless is something else and maybe we can talk about it in a different course some other day. So select Share, and hit create. Okay, next up, they will ask you about which provider you want to use, I always go with AWS. Since AWS has a server on Mumbai, which is near Bangladesh and has the lowest ping for me, but if you like you can go with Google Cloud or Azure. Now select whatever region is the nearest to you to make sure that you are getting the lowest amount of being possible. Next, you can choose a dear.
Again, for free usage, we use the aim zero sandboxed here it will give us 512 megabytes of RAM which is more than enough for our usage we will have a very small amount of data to be honest. And then next step there are additional settings you don't have to touch them and the cluster name. Now you can customize the cluster name if you Wish but I will just leave it as cluster zero since I like it that way, then hit Create cluster Okay, next up, you will have to create a new user for this cluster. You can also use an SSH certificate, but I will just go with the old trusty username thing. So I will name my usernames Solid Snake since I'm a Metal Gear Solid fan, but you can name it anything you want. Now, when it comes to password, make sure you are always choosing a very strong password and not ones that are easy to remember. Use a password manager
maybe but always use hard to guess passwords. So I will just use the auto generated secure password. And I will also make sure that I am copying my password to the clipboard, since I will be needing this later on. But then hit the Create User button. It shows Solid Snake and the password.
And finally, you will have to set up some IP access list. So the way it works, once you have set up a new database, you will have to allow a set number of IP addresses that can access that server. You know opening up a database server to the world is not a good idea. Security wise, so you should always use your current IP address here. But since this is just a course, and we are using this database for development, I will open up the server for all the IP addresses out there. And to do that, you can write 0.0 dot 0.0
slash zero and in the description, you can just write a view and hit Add Entry. See that that's there. And then click on finish and close. Okay, they will congratulate you and whatnot Hi quickstart guide Yes, go to database disclose it. Excellent. Now we have a database up and running on
MongoDB Atlas. And we can use this database ganache to eat read and write data from and to eat. And using just like a local database that you may have used in your computers, you see MongoDB Atlas is a very beautiful service. I have used it for development as well as for production in the past and I have never had any bad experiences with it. So next up, you can use some sort of database client to connect to this database, maybe something like MongoDB compass, so you can go ahead and click on Connect. And MongoDB will give you multiple options that you can choose from. So first, you can connect to your database server
using MongoDB shell, you can connect to the MongoDB server using your application that you're working on right now, you can connect to MongoDB server using MongoDB compass which is MongoDB own graphical user interface for working with databases and I will just show you that. Finally you can also connect using VS code. And let's be connect using MongoDB compass for now.
And I do not have MongoDB compass on my computer. So I will be Windows 64 bit and I will just hit download compass. Once you have downloaded and installed MongoDB compass on your computer, you can start the software from your start menu or desktop. Once you start MongoDB compass it looks something like this where they are giving you the option to connect to a new database by using this kind of URI. Now where do you get this
URI. If you come back to MongoDB Atlas, you will see that they are actually giving that URI right here. Just use this copy button to copy the entire URI and go back to MongoDB compass. Now remove this localhost URI from here and paste it yours. Now as you can see it says MongoDB plus SRV Benue username, followed by a colon and then it's looking for a password right. So what we are going to do, we will use the
password that we created earlier and paste it in here. And then we'll leave everything as is and we He can say Save and connect. You can name it anything. So I'm naming it V Avi, you can change its color if you want to, and say Save and connect. Okay, so it took a few seconds. And as you can see, we have successfully connected to our moving API cluster. Now, as you
can see, there are two databases, one of them is called admin. And the other one is called Local. Now, we do not have to do anything with these, these come by default with all the clusters out there. So just leave them be and we will create new databases very soon. To create a new database, you can always go and click this plus sign.
And inside database name, let's put b What really, let's call it movie, API deep. And inside collection them. Now if you're new to databases, like like MongoDB, or document based database, you may or may not know that collections are like tables in case of relational database systems. So in something like MySQL, or Oracle database system, you have databases, and inside those databases, you have tables. Now, in case of MongoDB, and other non relational databases, you have the database name first, and then collections. For example, in our cases, we will have a collection of movies where we will save information about different movies. So we can say movies and in create
database. So as you can see, we have a new database sitting here movie API dv, and there is a collection called movies. So right now, there is no data at all. Now in order to work with our API, it would be convenient if we have a bunch of data in our collections. And if you navigate to github.com/ach, si n ch y, which is my username and slash
movies, you will get the entire code for this API already written. And inside that repository, you will see a folder that says underscore data. Now inside this folder, there is a JSON file that you can use as a source of data for the collection we have just created. So I would suggest you go into this JSON file, then select raw, and then hit CTRL S and say this JSON file somewhere on your computer. So once you have downloaded the file, you can then import it to your collection. To do so, come back to MongoDB compass. And
while you have the movies collection selected, you can click on this Import Data button or this Add Data button. Then select Import File. And our format is JSON. And we'll select the file from our downloads and movies dot JSON. And you can also take a stop on errors, then hit import, wait a few moment. It done. And viola, we have the information of n different movies on our database. So as you can see,
each of this movie is a document Okay, as it as it says documents then. So inside the collection, each of this movie are a single document. And what do we have inside these documents? Well, we have an ID we have the IMDB ID for this title whose inputs, we have the release date, which is a string, we have the link for a trailer on YouTube. Then we have an array of genres. So this
particular movie belongs to five genres. Then we have a link to our poster. We have linked to end backdrops that will be later utilized in the front end application as you can see, finally, we have an empty array for review IDs. Now, this will come into play later on in this course, so just be patient with me for now. Okay, so one thing that I'd like to mention right here I am using the tmdb.org API for this images are TMDb is an excellent website. And they provide a free
to use API for developers as long as you are giving them credit. So I do, so I will be using the API for portraying the images. So now that we have created a new database on MongoDB. Plus, we have set up a new collection, we have imported some data into it, it's time for us to start working on our API code. Now the first step to writing our API using Spring Boot, is to initialize it first. To do that, navigate to start.spring.io. Again, links will be in the description. And let's start
initializing our project. First, we'll have to pick a programming language, which is going to Java in this case. But if you're familiar with groovy or Kotlin, you may go with them, then we will have to pick a project autumn build automation tool. And the initializer supports both Gradle and Maven which are not the most popular build automation tool for Java, I am doing with Maven, simply because I have more experience working with this then Gradle. Next up, picking up the Spring Boot version 3.0. Point one is the latest stable version. And we
will be using that throughout the course. But if you would like to try out some more bleeding edge features, you can use the snapshots once you have become more familiar with the framework. After that, we will have to fill up the project metadata. Now the group is usually written in reverse domain format. So for example, my website is Farhan dot Dev. And I would like to name my group date dot for her. So if you do not have a domain
of yourself, you can name it anything you like, as long as that package group is not referring to someone else's project nextra that artifact name, the artifact name is simply the name of the project. So in this case, I will be putting movies in here, but feel free to call in something else if you feel like that. Next there is a description field and you can put something like after that, we will have to pick up packaging for now java is a very popular packaging format for Java and it stands for Java archive wire. On the other hand, it stands for web archive. And you may think that will wire is more suited for this project since it's going to be a web application, right? Maybe yes, but since jar is more widely used than where I will be going with. Next speaking the Java version, obviously, I'm going to pick 17, since we just spent quite some time setting up Java 17 on our computers. Once you are done with the left column, let's
focus on the right column. In this one, you will have to pick the dependencies that you would like to use in your project. So use this add button, and you will be presented with a long, very long list of dependencies. And the first one that we are going to use in our project is Lombok, it's an additional library that saves you from writing a lot of boilerplate code. And you will see what I mean in action very soon. So please be patient. Since we are going to pick multiple dependencies, you will have to keep pressing either Ctrl on Windows or Linux and command on Mac. In fact, it says here,
right on the right corner press Control to multiple apps. Okay for multiple ads, so I'm pressing down on control and I will pick Lombok Lombok has been picked. Next up spring web. And finally, let's see.
No nada SQL under no SQL, we will need Spring Data MongoDB Yeah, that's that's pretty much it. You can also search for things here, for example, dev tools, and let's add that as well. Once done, you can exit out of this selector by pressing Escape on your keyboard and have a look at the list of dependencies and make sure you have the Everything. Now there are other dependencies that you may learn about later on, such as the reactive web, or Graph QL, or rest repositories or something like maybe spring security, which can be used for authentication and authorization. There is more to client if you're into auth, and things like that. But since we will not be getting into authentication and authorization in this course, we will stay out from the get go. Once you are happy with the configuration in this
initializer to go ahead and click Generate. It will take a few seconds to generate the SIP archive, and it will start downloading automatically. Once downloaded, you have to extract these movies dot zip or whatever you have named your artifact dot c file to somewhere in your computer easily accessible. After you have extracted the downloaded zip file somewhere on your computer, you can go ahead and open it in your favorite IDE or code editor. In my case, it's IntelliJ IDEA and I have
extracted my project on my D drive. So I will go ahead and click on open first. Then come to the folder where I have extracted the project and I will pick it up. Okay, so IntelliJ IDEA will ask whether you actually just this project or not. This is a safety feature to save you from
malicious code from running on your computer. So since we are writing it ourself, I just pick trust project. And give ideas some time for resolving all the dependencies. And once it's ready, you are free to go.
Let's try to understand the project structure first. So ignore the dot env and folder, it's managed by Maven. So you don't have to worry about it right now. There is the src folder, which is short for source. And it will contain your program source code as well as the test code. So we are not
going to write any tests. So let's jump into the main folder. So inside main there is Java and resources, we will have to work inside both of these directories. So let's go inside Java. And as you can see, here is the name of our project after
400 movies, it it may be different in your computer depends on what you have chosen in the initializer. But it should be something similar. Then there is a class that represents your applications names. So since I have named my artifact movies, it says movies application, which is pretty appropriate to be honest.
In other movies application class contains around 10 lines of code minus spaces in between. So let's try to understand what it's doing. The first line is actually declaring a package which is pretty self explanatory. Next, there are two input statements. The first one is a class called Spring application. Now this particular class contains a method called
Run. And to start your Spring application, you actually have to call this run method, and then pass your application class to it. And then you can also pass some command line arguments which we are not going to touch the second import a statement imports like the Spring Boot application annotation. So annotations in Java are usually used to let the compiler know about what this class does. So other than this class, there is more or less nothing inside this package. So let's try to run our application and see if we can we can have anything on our browser. Okay.
So you can actually click on this play button, besides the main method to run the program or this class play button, or this play button at the top. Let's use this one. Okay, so if your IDE says Lombok requires enabled annotation processing, just go ahead and click on Enable annotation processing and it should be fine. Now, if you look at the terminal, you will see that there is a nice arc that says the spring the springs version and there's bunch of logs and There is an exception. That exception states that the application is failing to connect to any MongoDB database at all. Which is true, since we have not let the application
know about our, our cluster, our username, our passwords and things like that application cannot connect to our MongoDB database. Now, it's fine if you want to leave this error here. Or if you want to get rid of this error, you can just first stop that application. Open the POM dot XML file, which contains a list of all the different dependencies that we are using.
And then look for MongoDB. It should be here somewhere yeah, there you go. Dependency artifact the Spring Boot starter data MongoDB. So just highlight the entire thing. And press ctrl and the forward slash which will comment this out. Then right click on form dot XML and then go to Maven and go to reload project now try to run the application once again.
No your whatsoever. So if you look at the logs, it will say that Tomcat started on port 8080 Tomcat is actually an web server that will serve as the web server the development web server for our application. Now, you'd have to switch to a web browser to see the application in action. So let's do that. And then you can navigate to localhost 88080. There you go. Now it says whitelabel error page, that's fine. At least we know that the application is booting up and we
are actually hitting the API itself. And not just some other page when what is zero states is that there is no endpoint at all. So although we have an API, there is no API to hit. I hope that makes sense. Now let's go back to our code and try to write our first endpoint. But after where it says the Spring Boot application, we will say Rest Controller.
It's another annotation that lets the framework note that this class is actually a REST API controller and not just another class. Then inside this class, you will have to say get mapping. And next we'll have to create a new method called public. And the return type will be string. And the name of the method can be anything but let's just call it API index for now. Because this is the route endpoint or or list, let's call it API route.
And we can say return. Have no or I know have our programs are boring, but it's essential, you know. So this gate mapping and notation to each, what it does, is that it lets the framework know that this method right here, API route, is a good endpoint. So if I put a bracket right here, and then inside, I'll say slash just a forward slash. Let's stop our application and run it again. Let's see if there are any errors.
looks fine to me. Let's switch to our web browser and do a refresh. As you can see, it says hello world. Let me just increase the zoom level a bit. So you can
tell alright. Now instead of putting a forward slash here, if I say for say slash route, rerun the application you will see that the whitelabel error page is back. But if you navigate to slash route, you will see Hello world. I hope this makes sense. Although DCS are valid eight point, we are not going to make our API like this, we will actually divide our application into separate layers, there will be a service layer, there will be a data access layer, and there will be an API layer. So let's go forward and get rid of this code and restart to put together our movies API. Now, in my opinion, the first logical step would be to configure the database for our application so that we can successfully connect to the MongoDB cluster that we have set up previously, and talk to it.
To do so, open up the src folder right here, go inside main, go inside resources, and open the file that says application dot properties. Now, in this file, you will have to write the different application properties that is related to your project. For example, right now, we are trying to configure our MongoDB dependency.
And to do that, you will have to write spring dot data dot Mongo DB dot database equals to the name of the database. I hope you remember that we named our database something like movies API dB. So we will write movies API dB, and next spring dot data dot Mongo DB dot URI. Now in here, you will have to
actually write that URI to your MongoDB cluster like you did with Compass. I have my URL already copied to my clipboard. And I hope that you have saved it somewhere safe. Like I said in the beginning of the course that I will just go ahead and paste it right there. And you can get rid of this slash test thing. And the last slash, and it should be fine. Okay, so
our application should be able to connect to our database. Now to test it out. Let's go back to POM dot XML. Let's remove the comments. And then let's start our application. Oh, see, we have forgot to reload our project. And the IDE is actually suggested me to load the map and changes. So I can
just click this button or you can go ahead and right click and go to Melbourne and reload project. Let's use this button and see if it works fine or not. Of course it does. Let's run the application.
And now the Euro is called. And actually it says some things about the MongoDB driver cluster. And this is a positive sign. If it failed to connect to the database itself, it would
have screamed at us and whatnot. But thankfully, it's fine. Now, if you have worked with any applications, specifically web applications in the past, you've may already know that putting sensitive data like this in a file that's going to be in your GitHub repository is not safe at all. Instead, what you should be doing is putting all these things in a dot env file. So we can right click on Resource, go
to new and create a dot env file for ourselves. And we can write down a few properties here. Mongo database, then Mongo user, then Mongo password, finally, Mongo cluster. Now you can go back to the properties file, and you can start moving these values one by one to your env file. So this is
going to be the Mongo database. Next up the Mongo user name which is Solid Snake in my case, good among but then Mongo password. Finally, the cluster. And I sometimes like to put them inside quotes, this makes sure that if one of the passwords or username or clusters contain some special characters in them, it would not disturb the order of things. So I like to put this quotation marks around each fabs. Okay, now we have our env file ready to go, what I would suggest that you create another env file, simply called dot env, dot example, for later reference references then make sure you open up the dot Git ignore file. And as you
can see, the Initialize project actually comes with a pretty good Git ignore file already. But we'll have to add a few things for ourselves, right. So you will say, you can actually copy this thing from here and paste it and say, in the white.
Yeah. And then you say.in With this will make sure that you do not accidentally commit that dot env file into your repository and open up your database to the word. Now, the only problem with this spring is that spring doesn't support reading dot env files out of the box. So what we'll need is we actually need to install a new dependencies to our project. And I would like to
take this opportunity to show you how you can add new dependencies to the project later on. So I'll switch back to my browser. I'll open up a new tab and I will search for Maven dependencies, something like that. Yeah. And here is Maven repository. Then let's search for something along the line spring. Dog
Ian's. Yeah, I am referring to this one by Paul Suarez. I apologize if I have pronounced his name wrong. Let's select this one. And we can see that it says this spring
plugins 1.0. And it says Central and whatnot. Okay, so the name of the thing is made up Paul Torres spring dot EMV. So as you can guess this is his group, group name and thesis, the name of the artifact or the or the project itself. So we can go back to our code. Let's open up POM dot XML. And inside the dependencies bar, make sure you are inside dependencies and not outside somewhere here. After the last dependency, we will create a new one.
So it is a dependency. And the ID helps us by auto completing this. And we will say that the group ID is mi dot Paul is he h, w A are set just to make sure you can always copy from here.
No one's going to judge you for that. And then name of the artifact which is spring dot E and now it's not strictly necessary to define a version as well. But you can do so by saying version and then put maybe the latest from two point 5.4 by one. Yeah. So that's it, let's reload Maven. And yet now our project has the ability to use the spring dot env artifact and three dot env fights. Let's go back to our
application properties and replace these hard coded values with our dot env references. To do so open up the resources and we need the env so Mongo database Mongo user Mongo password, okay? So you will first have to get rid of this value and then start with $1 sign and curly braces. And inside the set of curly braces, you will see say e NV dot Mongo. What do they call it? Database? Yeah, Mongo database, and you can kind of copy it from here then replace Solid Snake by Mongo user. And then they should be Mongo password. But sore tricked.
Yes. And finally a cluster. Cluster Yes. Does this mean? Okay, we can ignore this typo. And if you want Singapore, you can actually come to this problem step and have a look at what are what's the ID is complaining about. So the annuals property, let's just ignore them from now. Which ones per year? Yeah. Okay, let's ignore these for now. And the typos. Okay, Mongo is not a typo.
Except let's try running our application once again and see if our env file has taken any effect or not. So as it turns out, our MongoDB connection is fine, which means the end file has been read successfully. And we have successfully secured our confidential information from going out into the world. Now you, you don't have to write everything inside an env file, you can actually use this en v dot name of the variable notation to access any environment variable variable in your operating system. But I will not get into that anymore since we don't need it. Let's go ahead and get along with our project.
Now in our application, there are two types of data that we are going to work with. First there are the movies and then there are the reviews. So we will need to first create two separate classes for representing these two entities in our application. So first, let left click on your project name new and Java class let's call it movie. And inside this movie, we will first have to annotate this class as a document. This will let the framework note that this class sheet presents each document in the movies collection.
And we will also define the name of the collection here movies. Then inside here we will have a bunch of private data. So private object ID ID this will represent the ID of this movie and private IMDb ID sorry, string IMDb ID which will represent the IMDB ID of this movie. And
preferred string, title, private string release date for private string Schadler link this will be a link to the YouTube page for the trailer private is string poster a link to the image on the internet private list string this will be the genres because there can be multiple genres of a single movie. And these lists class need to be imported at Java util by any private list string and this will be the backdrops now this backdrop images will actually be used in the front end application as you will see later. Let's just quickly jump to MongoDB compass and make sure that we have indeed written all the necessary properties for this class. So as you can Let's see we have written high D IMDb ID title yes released a trailer link genres poster, backdrops, air review ID. So you
you, we will add review IDs, a few moments later. Now, we will have to also annotate this ID field as an actual ID, this will lead the framework know that this property should be treated as the unique identifier for each movie inside the database. Okay, apart from this we will also need getters setters that do is string methods and some constructors. So instead of writing out getters setters to a string for each of these private properties, we can just say at the read data, and this is one of the annotations that comes from the Lombok project. And it takes care of all those different gators setters and two string methods. Next, we'll also
add all args constructor, this is basically an addition for creating a constructor that takes all this private field as argument finally, no args constructor, which means another constructor that takes no parameters whatsoever. Okay, next, let's create the reviews. So Java class reveal, it's the same deal. So this will be document and the collection name will be G fields. Now, we haven't
created this collection yet. But the application itself has the ability to create new collections. So we don't have to worry about that. We'll add data just like before. All args constructor, Nords. constructor, and then
there will be two private properties for a strong private object ID. ID, this will be the ID in this case. And then private review body just just body string body. Okay, so as you may have already seen in the database design, that each of these movies has an array of this review, and we haven't yet added this this area of reviews to the movie model yet. So to do that, we will go back to the movie class, go near the end and say private least review.
Review IDs. Okay, so it matches this name review IDs, and the hall that our names are matching as well. Yes. Now if you write it like this, this will be an embedded relationship. So all the reviews that are related, this movie will be added to this list of reviews. Now this is completely fine. In fact, if you are modeling a one to many relationship, such as one movie can have many reviews, this is the way to go. But since I'm trying to demonstrate some of the features of Springboard MongoDB data, I will show you a nifty annotation right here. So
I will say document reference. So this will cause the database to store only the IDs of the review. And the views will be in a separate collection. So this is called manual reference relationship. And there are some other ways to
create relationships in MongoDB. I would suggest that you search them up on Google or MongoDB sufficient documentation and read about them on your leisure. It will give you a lot of context. So now that we have our movie and review models ready to go, we can go ahead and start writing on controllers. So I'd
right click on my packet then a Java class. This will be called Movie controller. And this is our first official day API controller that we are writing in this API. Previously, we wrote a simple controller in our movies application class, but this time, it's going to be a bit different. So first, we will need to annotate this class as a Rest Controller.
And instead of mapping it to localhost 8080, I want to make it sorry. Mapping request mapping, I want to make it map to slash API slash v1 slash movies. So any requests to slash API slash v1 slash movies endpoint will be handled by this particular controller. Next, I will create a new gate method. So I will say get mapping. And then
public. Let's return string for now. All movies, and then we can return all movies.
OK, let's try to run our program and see if it works or not. Let's hit the play button. Okay, it's compiled fine. Let's go back to our browser. And here localhost 8080 slash route.
We will get rid of fruit and say slash API, slash V one, slash movies. And it works. Now although it's okay to return these strings from this endpoint, it's better to return a response entity I'll show you why in a minute. So this is a generic pipe. So we'll say string. And then instead of returning or returning, and instead of returning all of this like this, we will say, new response entity of type is String. And this is the value. Then HTTP status dot O.
HTTP status dot okay means 200. Let's read on this program. Refresh, and it works just as expected. Now, you may not see
any difference there. But if you go back to your terminal and say, curl, I HTTP localhost 8080 slash API slash v1 slash movies, you will see we are indeed returning the 200 response code. This comes in handy when working on a front end application and any REST API out there should return proper status codes. Since we have the movie model right here, let's try to use it and pull some data from the database. For that, we will need a service class as well as a repository class. So let's create the repository first, because that's the shorter one. So it's a Java class. And we'll select
interface because repositories are of type interface. And then we'll say movie in repository. Yeah, now this interface will extend Mongo repository. This is the generic type. And we will have to let it know what type of data we are dealing with. So movie,
and we'll also need to let it know what type of ID we're dealing with, which will be object ID, there you go. That's all for this interface, you will need to unnoted this interface as a repository. So that framework knows that this is a repository. And then let's create a service class which will be movie service. And this class will not extend anything, you will just need to annotate as service. Now, inside this class, we will write the database access methods. So the first one will be public
Get on movies. Let's just name it all movies. And let's just change our controller method name to get on this because since it's a get mapping, we're saying get all modes. And the return type will be list of what will return a list of movie from this method.
Now, inside the service class, you will need a reference of the repository to do that you will say movie repository it will be a private field. And its name will be movie repository. Now if you know Java, you may know that you will have to first initialize this bit of code, you will either have to initialize it using a constructor, or you can just use auto wire an audition what this will cause it will let the framework know that we want the framework to instantiate this class here for us, okay. Let's go inside the method now. And we will say return
move the repository dot find all these find all method is described inside the Mongo repository class. As you can see, it says right here find all and it will return and least of the data type that we have passed right here certainly stock movie. So that's our service class right there. And then let's go back to our controller, we will need a reference to our service class. So we will say private movie service movie surface. And just like we did in the service
class, we will auto wired the service class. Since it has the service and audition right here, we will set auto wire. Excellent. And it's also now inside the good old movies. Instead of returning a response entity of type string change it to list so we are returning a response entity of type list movie.
Then inside the method, we will have to write return movie service.of movies new response entity of type list movie and inside movie service drug called movies comma HTTP status dot okay. Yeah, let's take a look at our repository. Once again, it's all set up. Services fine, the controller is fine. Let's cross our fingers
and see if this works or not. Going to go back to our browser and hit refresh. And the reason behind this problem lies in my EMV file. So as you can see, we have called our database movie API dB. But in our configuration, we mistakenly put an S right here.
So we'll get rid of the s. Res restart the application and hope for the best. And yeah, it works. As you can see, there are 10 movies in this list. Since it starts at zero and ends at nine. There are 10 movies in this list and the code is perfectly fine. Now let's go
back to the code and let me re iterate on what we have done so far. So in rest API's, usually there are multiple layers. So one of the layers is the API layer, which is this controller and it will only concern itself have about the task of getting a request from the user and returning a response and nothing else. And that's what it's doing. All it's doing is it's using a service class and delegating the task of fetching all the movies from the database. And give me giving it back to the API layer. So it calls the all movies method inside the service, gets the list of the movie and returns them with HTTP status. Okay, it doesn't know what's going on inside the service class. Now, when we come back to the service class, this
is where most of our business logic will go. For now, there is nothing to be worried about in this classes. But soon, we will work with a little bit more complex business logic in this API. So the service class does is it uses the repository class, and talks to the database, get the list of the movies and returns to the API layer. Finally, the repository layer is kind of the data access layer for our API II does the job of actually talking to the database and getting the data back.
I hope that makes sense. Now, since we have a list of all the movies in our databases, let's complicate it a bit more by trying to access a single movie. Now, we will begin by creating a new get mapping. And that is get mapping and this will actually take an parameter. And we will have this a slash that inside a pair of curly braces will say ID. So we are trying to search a movie by its
ID. So we can set public response entity. This time, we will return a single movie. And we'll say get single movie. Sorry for the type book. We'll close the pair of parentheses and we'll start our method. Now inside the pair of parentheses, we'll have to say PATH variable, which lets the framework know that we will be passing the information we got in the mapping as a path variable. Or we will be using the information passed in the PATH variable as a string, or just object.
Id ID. So what this does is it lets the framework know that whatever we are getting through this path variable, we want to convert that to an object ID called ID. And then we can say return first we'll have to go back to our service layer and write a new method here. Public movie single movie and we will say return movie repository dot find by ID and we will get that ID right here.
And it goes here it David and the squiggly line it says that whichever option okay? So the thing here is that the find by ID method may not find any movie at all, maybe the ID you have passed doesn't exist. So in those cases, you it will have to return now, so we'll have to let Java know that it may return null by saying optional movie and we will just import the optional class we will also have to fix our response entity movie will say optional. Movie optional has been imported nice and then We can say return new response entity optional movie. And inside there we can say movie service dot single movie, we will pass the ID that we have received comma HTTP status dot. Okay.
Let's restart the application let's go to our MongoDB compass inside the movie collection and copy one of the object IDs right here let's copy for Roald Dahl's Matilda the musical. Let's copy the object Id go back to our browser. And we can say movies, slash and then the object ID. As you can see, we have found Roald Dahl's Matilda the musical. Now, the problem is that I do not want to expose the
object IDs of my collection entities to the public. Instead, what I want to do is use this IMDb ID to search for new movies. So let's see if we can find a way to do that. Now although the repository comes with built in methods for searching with ID, it doesn't come with methods for searching with IMDb ID so what we'll have to do is we'll have to implement that method ourselves. And it's really easy because there is something called automatic queries that lets you farm where it is dynamically from.
property names so we will say optional. Movie because it may return null once again, we'll have the input optional movie and we will call it find movie by in dB ID and it takes a string I am DB ID. Now just by naming this method find movie by IMDb ID MongoDB data Spring Data MongoDB will understand what we are trying to do. It's that much intelligent. So now we can go back to our service class.
We are no longer getting an object ID but we are getting a string IMDb ID and instead of find by ID we will say find a movie by IMDb ID, IMDb ID and that's it. Let's go back to controller. We'll change this from ID to IMDb ID by the way you do not have to name the ID IMDb ID exactly in this method. It's
It's just that I know what I'm doing in a later date. So we will replace object ID by string IMDb ID and then response entity optional movie. This is fine. Yeah IMDB.
So technically, this should do our job. Let's check it out let's see seems like there has been a mistake. Let's go up it looks like there is a problem. Let's go back to
our movie repository. And the music It is it should be IMDb and not IMBD. So as you can see, the framework is clever enough to see that I have misspelled the property name right here. So let's run the program once again and see if you're trans or not fine tuned by cannot find up here, I have to correct terrorism, DIA. And yeah, it shouldn't be fine let's go back to our browser. And as you can see API slash var slash movies. And then I have used the IMDB ID for this movie.
Hit enter, and it works just fine. We can use the IMDB ID to search for movies. Now, you can actually form dynamic queries like this using any property name in your model class.
As long as they're unique, because if that's not unique, you will get multiple movies with the same ID or same name. Okay. Now that we have our movie controller sorted out, let's start working on our review controller, where we will let the user send us review. And we will add those under a movie name. So let's first create a new repository. View posit Ori and it spends Mongo D. B, Mongo repository and the die will be revealed.
And object ID is our type. Yeah, yeah, that's their next let's create a new service class. Oh, I almost forget to enter this as repository. So, create a new class called the views service. And this will be a service class. So I'll go service here I will say public then this method will create a new reviews so it will return a new review then here she view by creative then this method will take two parameters. The first one will
be a string which will be the reveal body and the since the second one will be string IMDb ID so what we are trying to do here we will first look for the movie with the given IMDb ID. And then we will create a new review and associate that review with the found movie. So let's first create a new review. Review few quotes from new review.
Now you may now you may remember that in the review class, we have an pol arcs constructor and an aurochs constructor. But since IDs are auto generated, we cannot pass an ID to this class. So what we will do we will also generate a custom constructor that takes only the body. Now in IntelliJ IDEA you can right click inside a class go to generate and then constructor and we only need the body part of this class. So that's now let's go back to our service class and new review and we will pass the review body Excellent. Now that we have a new review, we will have to associate these to one of the movies now that we have a new review object, we will have to insert it to the database and for After that, we will need a reference to our review repository.
So review repository view repository and needs to be auto. Fine. And we will say, review repository dot insert, and review. X. And that's the review taken care of now we can have to
associate with this with one of the movies, right? To do that, we need a few things. Now the first thing that we need is called a template to create a template with set private Mongo template, Mongo template. Now, you have already learned about repositories as one of the ways to talk to the database. The other way is using a template. You see there are times when a repository just doesn't cut it, maybe you have an operations so complex that it cannot be implemented within a repository, or even if you can implement it within a repository, it will be not suitable. So what we need, we need a template, you can use this template to form up a new dynamic query and do the job inside the database without using the repository. So we will alter this.
And then down here, we will say Mongo template dot update, since it's an update operation, and we need to say which class to you do we want to update. So we want to update all of the movies. And then come to the second line and put a dot here. And then as you can see, there are multiple operations that we can perform.
So we want the match. Now inside the matching of version, we will need a new criteria. So we'll set criteria dot fire. And inside where we will say IMDb ID, make sure it's matching up with the column name or the property name inside the database then.is the IMDB ID that we have got. Then come to the next line and put a dot once again and then we'll say Apply.
We'll say new update. This is called an update definition dot push review IDs and then dot value sheet view. See, that's pretty much it. Okay, so what we are doing is we
are using the template to perform an update call on the movie class. Because I hope that you'll remember that each movie in our collection contains an empty array of review IDs. So what we need to do, what we need to do is we need to update this array and push a new review ID into this. So we are saying movie dot class then we have to perform the matching. So which movie are you updating? We are updating a
movie where the IMDB ID of the movie in the database matches the IMDB ID that we have received from the user. Okay, then we want to apply this update. To do so we call apply. And then we create a new update definition which does the job of making the change inside the database. So we say Update, push and review IDs. So we want to update the review IDs in this found movie and the value of this movie will be revealed. So
that review that we have just created it will be pushed inside the review IDs array okay. Now, finally, we will have see the First, to make sure that we are getting a single movie and we are updating that. Now one thing that I have done, which I shouldn't have is we cannot new up a review like this.
Rather, what we need to do is we will just save the review on insert, because when you call insert, it actually returns the data you just pushed inside your database. Okay? First, finally, we can return that view we just created. So let's review the Create review method. We are taking a
new Mongo template, we are using it to update the movie with the new review, we just pushed using the repository. So likely say sometimes you will have to code up complex business logics by yourself. And as you grow as a software engineer and an web developer, you will start to understand all these things all by yourself. So let's go back to our review service. Yeah. So I mean, our review is is fine. If you're in positions where you feel service, yeah. Now let's create a new review controller.
And inside this controller, we will have only one post method. But you may think, why only a single post method? How are we going to get all these reviews that are associated with a movie, I'll show you how. Now let's begin by annotating it as a Rest Controller. And then of course, we will have input request mapping which is slash API slash v1 slash mobile movies Okay, since the review form will be inside a movies Details page, or in the page where you are viewing a single movie so we can make the requests to the movies and point instead of creating a new if we use NS N bar. Now when it comes to creating endpoints like this,
it really depends on the on the developers preferences, you may you may choose to organize your API differently from what I am doing here. And in a real life project I maybe I will do something different but since it's just for learning, and we are just getting started, I think it's fine. Inside the controller, we'll first need our service. So we'll
say private reveal Service Review service and we will auto add this nice then we'll create a new post mapping and then a new method of Lake will again return a response entity and this will be of type review. And we will call it create review method. Inside this pair of parentheses we will say request body then map string, comma string and we will call it payload so we'll import map. So, what we are saying to the framework here that whatever we get as the request body we would like to convert it to a map of the key string and value string and we want to name this map as payload you will see why this is then we will say return new response entity.
And yeah we can say review this review and then it says Service Review service dot create review and we will pass two tests. First one payload dot get is the review body and the second one will be payload Don't get IMDb ID Okay. Finally we say comma HTT be status dot created, it will be 201. Since we are creating a new review, we want to send 201 instead of the plane 200 Because this means created and that means okay. So now that we have the post mapping done, we need our REST client a separate risk flying to test our test out our code. But before that, I can see that there is this squiggly line underneath the view controller.
So I will just go to problems and see what's wrong. cannot resolve symbol IMDb ID Okay, let's see where I missed a typo here. So it should be inside a pair of quotation mark. And that's gone. See, this is the beauty of IntelliJ IDEA. It
helps you a lot. Now let's restart our program. And I will use postman to test out our API. In fact, I just thought instead of mapping the reviews request to API slash API slash movies, let's just go with reviews.
Because that sounds more appropriate. Now let's start our application and let's jump to postman. So inside postman first, I'll create a new collection. And
I'll call the movies API. Then let's create a new GET request get all movies so it would be localhost 8080 slash API slash VLANs slash x. So it works out just fine. Let's copy the IMDB ID from one of these movies so that we can test out our next request which will be get a single movie and we should be able to carry everything from the previous request will host slash view and slash movies slash then the IMDB ID. Let's execute and the works just fine.
Finally, let's try to create a new review here to review. And let's say v1 slash reviews. Okay, that's I set that because by mistake so it has to be post inside body I would say raw data in JSON format. So I will say review body will be I really enjoyed the movie with I.
Yeah. And then I will say IMDb ID, column and timed ID. Now you have to make sure that the name or the key in this JSON data review body and IMDb ID exactly matches the two keys inside the payload which is review body and IMDb ID. So what will happen is this endpoint will receive a JSON data from the user and then convert it to a map where the keys are extreme and the values are history. Then from this map, we'll be able to access the review body which is a string and the IMDB ID, which is another string. And then through the service layer, we can create a new review on the database, update the movie to be associated with that review, and then return the review. And of course, there's a repository
that works as the inte
2023-01-22 01:38