Spring Boot Tutorial for Beginners - 2023 Crash Course using Spring Boot 3

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome back friends my name is Dan Vega spring developer advocate for VMware and today is an exciting day this is a video I've been wanting to put together for a long time now and it's finally here this is my spring boot crash course so I get a lot of questions how do I get started with spring spring does so many things so we're going to talk about that today what is spring what can it do what is spring boot uh that sits on top of spring why are there two different uh projects if you will so we're going to talk through that and then answer the question how do I get started with spring for one of the use cases which is building web applications that's what we're going to do here today and you're gonna learn what you need to learn to get up and running with that so we'll talk through some prerequisites we'll talk through what is spring what is spring boo we'll talk through the application that we're going to build here today and we'll go through what you're going to learn and then we'll jump in and write some code so there's a lot to do what are we waiting for let's get started all right so here I am in one of my favorite tools Excalibur and this allows me to just provide some graphics and talk through some of the things that I want to cover today so let's start with the prerequisites what do you need to take this spring boot crash course so you need some experience with Java we're using the Java programming language you should have a beginner slash intermediate experience with Java experience with Java build tools Maven or grade it we're going to be using Maven today at least understanding what Maven is and what it provides that would be a big help software we're going to use Java 17 today so you should have Java 17 installed you need an IDE or text editor for Java development I'm going to be using IntelliJ IDEA Ultimate Edition this is a paid version you can get a 30-day free trial or you can use the free version use Visual Studio code which is free you can use the string tool Suite which is free so any of those will work fine you need an API testing tool something to like test your apis with so Postman is a very popular tool that's free you can use Curl from the command line or a really nice utility called HTTP 8 t t Pi I never know how to say that correctly or in IntelliJ what I'm using today there is a built-in HTTP client which is really nice Dr desktop not totally required uh there are we're going to use H2 for an embedded database at times we'll switch over to postgres and instead of installing a postgres database locally you can use Docker compose to spin a container up really quickly and in fact when we get to production we'll have to kind of step back and use postgres as well in our development environment we'll see when we get to that but those are kind of the prerequisites so if you fit that mold and you want to learn about spring and spring boot you're in the right place so let's kind of slide over here maybe zoom out a little and see if we can't get into spring and spring boot here the first thing we start with is a spring framework the spring framework is used uh it's a pretty massive project that's used for a variety of applications so we could build web apps uh we can build a secure responsive web applications connected to any data store these are which we're going to go through today is traditionally an imperative style programming using something like spring MVC we also have a reactive stack so if you want some asynchronous non-blocking architecture you can reach for something called Spring webflux you can use spring to build microservices quickly deliver production grade features with independently evolvable microservices so if you have these services that often change and you want to kind of split them out into their own service you can do that with spring spring cloud is this really great project your code any Cloud we've got you covered and there's a whole bunch of services within spring Cloud that allow you to help help allow you to build Cloud native applications serverless serverless is a big thing these days and if you want to build functions or we have something called Spring Cloud function which is really great it allows you to kind of write these functions in a spring programming Paradigm but not for a specific platform but if you want to plug in and use something like AWS Lambda or Azure you can but you get to keep that same code base no matter where you're going to move your serverless functions to you can do things like eventually event driven architecture you can integrate with Enterprise react to business events act on your streaming data in real time you can use it for batching so I want to have some automated tasks I want to do some offline processing of data at a time to suit you spring batch is a really great project for that and set my banking into lately is spring shell so if you want to build some command line interface CLI applications using the tools that you're are used to using like spring spring shells are really great project for building CLI applications so spring is this massive framework that allows you to build all these different types of applications that's great so what do we need spring boot for then Well Spring boot kind of takes that a little bit further and says okay we're gonna help you simplify your spring development and it does it by a lot of different ways but there are three kind of core principles in Spring boot spring boot starters Auto configuration and production ready so in Spring boot starters we um when you want to create a new project you declare something in your palm.xml so in traditionally in the past you would have to declare all of the kind of dependencies that your project needed so you'd have to list them all out listed all the versions and figure out which versions played right together now what you do is you list out a starter so in this case spring boot starter web and Springwood starter web goes oh I know all of the things you need to build a web application you need spring core spring MVC you need some logging support you need an embedded version of Tomcat and you need Jackson and whatever else you might need so that's spring boot starters kind of bundling all the required dependencies together and using the correct versions Auto configuration is a way for us to say okay in the example of a spring boot starter web if you're building a web application and you're connecting to a database so I'm going to connect to a database you probably want something like a data source configuration configured for you why would you want to go in and create that yourself we know that you've put a database driver on the class path let's go ahead and configure a data source configuration for you so you don't have to so we provide a bunch of sensible defaults but we also based on the type of applications you're building we Auto configured some things now you can always change how that configuration looks but we're going to provide to you what we can out of the box and that gets you all the way you know half the way there so instead of having to create this data source configuration it's already there you're connected to a database you get to worry about the things that you need to worry about to build out the requirements of your application all right the next is production ready so we start with the actuators spring boot actuator module provides all of spring boots production ready features we get things like endpoints so we have a bunch of endpoints that can give us some insight into our application what are all of the beans in our application we'll learn more about beans today what is the health of the application is it up and running is the connection to the database healthy Etc we can find out info metrics mappings and so much more through spring boots actuator in Spring boot 3 there's a big theme of observability which is the combination of logging metrics and distributed tracing the spring boot actuator kick-starts all of that and with some settings you get a whole lot of metrics and tracing out of the box finally the ability to build something for production we have a bunch of different ways that you can build an artifact that you can use wherever you're going to host your application so if you want to create an executable jar great anywhere that has a jvm this jar will go ahead and run now what about where we don't have a jvm we could build a container using Docker or something like the cloud native build packs to build an oci compliant image finally in Spring boot 3 we have this idea of native executables which is really really exciting some really cool new features in Spring boot 3. so that's a little bit about spring boot I don't want to go too much further I want to talk about what we're building and what we're going to learn today so we're going to build a traditional kind of web app where we have a client that makes a request to a rest API this is really what we're building here we'll build a simple front end for one of the examples but most of the time we're just going to use a tool like some API testing tool to call out to the rest API this raised API that's built in Spring we'll talk to a couple different things at first we'll just start off with this kind of in-memory collection of things because we haven't talked to a database yet so we're going to kind of gradually build on those Concepts then we'll move to a database we'll use some different approaches to querying data from a database so we'll dive into things like the jdbc template and spring data all of which are going to return Json responses back to the caller we're of course using Java all the project source code for this will be listed on GitHub you can find out more about it in the description below so we're building a Content calendar I had to pick a domain I went with this I have a lot of content that I'm building and I'm just gonna kind of create a calendar of things that I have built or that I am building so we're building out this calendar it's a very simple domain it has a Content domain things like the title description what is the status it could be an idea it could be something that's in progress completed or already published what is the type it could be an article I'm working on a video a course or a conference talk when was it created when was it updated and what is the URL to it so what we're going to do throughout this is it may seem pretty simplistic but there's a lot that we're going to learn by just building this out so we're going to start at start.spring.io which is this really great website that you can go ahead and bootstrap a new spring boot application from from there we'll talk about dependencies what are dependencies how should we go about selecting them what if we need to create some later we'll examine the project that gets created for us including talking about those spring boot starters that we mentioned earlier and diving into like how our dependency versions declared we'll take a look at the main application class look at The annotation within that class we'll talk about how to start our application how do we start it from the IDE how do we start it from say a command line finally we'll get into how do we structure our code we can kind of we're given free rein on how to structure our code what are some different approaches and where should our code live once we've done that we're going to go into a whole bunch of different topics talking about you know spring core what are the core kind of fundamental concepts that you need to learn when you're developing spring applications things like inversion of control the application context beans and dependency injection these seem like terms when you first hear them that might be a little scary they're not at all they're very approachable we're going to talk about that here in this course spring NVC is how we build our MVC apps our model view controller this is our web application so we'll talk through a lot of the annotations that you see when you're building this out we're going to build out a crud rest API we're going to test it using our API testing tool we're going to talk about cores so when you're calling an API from a front-end application there's something called cores that you need to think about and we'll talk about validating that data that comes in next we'll move over to the data world so let's talk about jdbc and how traditionally we use jdbc to connect to a database and query or get data in and out of a database we'll talk about how to configure a data source how to populate data into a database we'll talk about the jdbc template spring data and repositories next we'll talk about production ready so we're we've built our application out we got to start getting this ready to move to production we'll learn a few more kind of Core Concepts like how do we work with configuration how do we inject values using the add value annotation or more structured data using configuration properties what do profiles do and when we need them and what is that spring boot actuator that we just heard about a minute ago finally we'll talk about moving this into production we're not just going to talk about it we're going to do it here's our options but we're going to take this and actually move this to a host this is a free host that you can sign up for an account for it's going to be free it's not one of the big cloud providers it's a really nice app called Railway that allows us to just get our application out there into production the most important part here is you're going to follow along but after this crash course I want you to take what you've learned today and apply it to another domain so say that you're very interested in maybe starting your own blog you know that could be another domain or maybe you want to create a place where you can keep all of your recipes whatever things are interesting to you go ahead and take these Concepts apply it to another domain and this is where some of the the real learning will come in not only following along here today but building your own projects using the concepts that we talked talk about today so just jumping out I will try and include this in the resources for this project we talked about prerequisites what is the spring framework what is spring boot what are we building and what are we going to learn today so with that what are we waiting for let's just jump in and get going when you want to create a new spring boot project you should head over to start.spring.io this is the spring initializer it's a way to bootstrap a new spring boot project this is a website where anybody can use it now this same spring initializer is built in to a lot of the Ides and the text editors that we use so what we're using today is an IntelliJ if you're on the Community Edition it's not available start here at start.spring.io so what this is is again a way to bootstrap an application and the way that we do that is by filling out some data about the application that we're going to build so we've already gone over that we know what we're going to build we know what things that we might potentially need in this application once we have that now we can come over here so the first thing we have to select is what type of project is this going to be Gradle or Maven I'm going to go ahead and choose Maven you have to pick your language I'm selecting I'm keeping Java as the selected language then you have to pick your version of spring boot if as long as you are so at the time of this recording the latest version is 3.0.2 if you're watching this in the future this could be a lot higher that's okay just take the current version you should be okay unless we get into a situation where we're on Fourth then we might have some breaking changes so let's talk about metadata this is data that describes your project so we're going to start with a group this is kind of the default package right so this is usually your domain in reverse order so for me that is Dan Dev dot Dan Vega because my personal website is danvega.dev so if you were abccompany.com you could say com dot ABC company the artifact is the thing that we're building so the thing that we're building today is a Content calendar and then you can go ahead and describe the project if you want so let's say content calendar application let's say rest API and then we have our full package name here the packaging is going to be jar the version of java that we're going to use is Java 17. then what we can do is we can start to add our dependencies now the dependencies the way that I like to think about this is before I go shopping at the supermarket I have a pretty good idea of what I need to get right I know what meals I'm making tonight I know based on those meals I know kind of what ingredients I'm going to need so I write them all down on a list that way when I go to the supermarket I know what I need to get we've already kind of done that with our application right we've sketched out what we're going to build today we kind of know what we're going to be building in the entire application but for the foreseeable future for right now we know this is really just a spring MVC app this is going to be a rest API so what I'm going to do is go into my dependencies and I'm just going to choose spring web now if you go in there and look there are all kinds of things so if you want to do things like graphql or um spring data or oauth 2 or anything that you could really think of is in this list this is really just a starting point remember that our application is going to use a lot more than spring MVC but that's okay we can always add dependencies later so I want to just start with this and then we'll go ahead and add some dependencies as we need them from the spring initializer here you can actually go in and explore this is what your starting project is going to look like you can also share this if you want to share a similar project with a friend or you can go ahead and click generate and what this is going to do is download a zip file with all of that code inside of it now what you can do is open this up in your favorite IDE or text editor so we know that we're using IntelliJ ultimate so what I'm going to do is go ahead and say show me this in finder and then I'll go ahead and unzip this and that gives me a directory with all of those files in it and then I'm going to go ahead and open this up in IntelliJ so one way that I can do that is I'm just going to drag this onto my IDE and there it goes it opens up and it's ready to go alright so before we do anything I want to take a look at our palm.xml if you're not familiar with what a palm is this is part of the maven build tool when we picked our dependencies from start.spring.io and filled in that metadata it kind of builds this file out right so here it declares the version of spring boot which is 3.0.2 here's our group ID our artifact the version of this particular artifact and then name and description we're using Java 17 and then here in the dependencies these are all of the dependencies that we are going to be using in this application so right now all we selected was web so we got this dependency and whenever we build a spring boot app we get the spring boot starter test to give us testing support out of the box then there's the spring boot Maven plugin which allows us to run the application via Maven build it compile do a whole bunch of things we'll take a look at that in a second so I want to talk about this idea of spring boot starters so if you haven't done a ton of java development or been around as long as I have there was a time when you had to kind of figure out all the different packages or libraries or classes that you would need in an application you would maybe stick them in a lib folder and uh hope to God everything worked those days are long gone we now have this tool called Maven and it allows us to say hey go ahead and pull this particular project or Library into this project that I'm using and then you declare a version you say I want to use um Jackson data binding version 2.19.2 right here we don't do that we're just declaring this thing called a starter and what a starter is is comprised of all of these other different things so if you remember back from the beginning of this crash course we talked about being able to say hey I want this one thing go ahead and pull all these other things in that's what this starter is we can command click into this here in IntelliJ and it will dive into what that starter is and you'll see it's nothing more than um in a bunch of dependencies that are included so the spring web includes the spring boot starter if we were to jump into there you'd see some more dependencies it also includes Jack Json support it so that Json support is including the dependencies like the Jackson data binding uh the data types for jdk8 data types for jsr 310 and our Jackson module here so as we dive into these we're going to see um then there's the spring boot starter Tomcat so this is how we get our embedded Tomcat there's spring web so this is going to bring in the basic web support and then the webmvc stuff is going to allow us to create these rest apis that we want to work with today so just by declaring that one thing this is a set of dependencies and particular versions that all work well together and give us the ability the functionality to build a web application so these starters are really really handy the official spring boot starters start with spring boot starter Dash and something else so we'll see some more of those later but as you can see here here spring boot starter Dash tests we can tell that that's an official starter the other thing we want to talk about is dependency version so if we come back up here there's a spring boot starter parent if we click into that there is a spring boot dependencies if you look in here there is a bunch of dependency versions declared so when you go to use something like the db2 jdbc version we have a version declared all of these things have versions numbers associated with them and this is so that you don't have to declare them when you go ahead and include them we know that those particular versions work well with the things that are in this particular version of spring boot now again that's just to get you started if you need to override that and declare a specific version you can there's nothing stopping you from doing that but this is just what we know is to be tried and tested again just one less thing you have to worry about figuring out which versions of which software play nice together so we're done with the palm the next thing I want to look at is kind of the folder structure here and what is included so if I go in here we have this dot idea this is for IntelliJ IDEA there's a DOT Maven folder this is for the maven wrapper so you don't have to have Maven installed to be able to run this application from the command line that is because of the maven wrapper um there is a source folder we'll get into that in a second there's a git ignore file which is pre-populated with some stuff already in it which is really great there's just a quick help file and then the mavenstuff the palm.xml so if we look at source we this is a normal Java project setup we have Source Main and Source test so main is where our mean code is going to go we have a source mean Java and then we have that main package generated for US based on the metadata that we filled in so we have dev.danvega.content calendar and we have this content calendar application this name is a little long for me I always like to come in here and just rename it I'm just going to name this application and we'll click OK and that works for me so now I have just this main application class this is the main class every Java application has to have a mean class with a public static void main this is it so we have public static void main taking takes in some arguments and what it does is it calls this app this spring application.run and passes in this class has the class to run so we say if we look at run this is a public static returns a configurable application context even though we aren't really returning anything in this instance we'll talk more about this when we get into application context and beans and so forth but this is the magic that makes it happen and this is how we can run our application now this main application is annotated with this at Spring boot application annotation I don't want to go too far into this but as we start to build out our spring boot application or using spring framework you're going to see a lot of annotations and it may seem like a lot at first but it is way better than the contrary which is we used to define everything in XML so you have these huge blocks of XML defining how your application works right now we just have these annotations so we just annotate a particular class or a method or an argument and we can do some cool things in this case we are annotating this with at Spring boot application and what this does is it does a whole bunch of things here A whole bunch of more annotations that are on top of that annotation so this is just a way to go through and configure your application and do some other things that we're not going to get into right now it doesn't really matter for this point I just wanted to point that out that your main application class is going to have the main at Spring boot application annotation on it and then you can always come down here and write more code inside of here if you wanted to and we will do that at some point but right now this is enough so now that we know what what the kind of structure of the application is we probably want to know how to run it so there are a few ways that we can run our application the most glaring one here is Right within our IDE So within our IDE we have these little play buttons here in IntelliJ we can run the main application we can run this main method we can also come up here and click this play button to run it we can also debug it so there's a debug here if you right click you can go to debug or run application with code coverage or profile it with intellij's profiler um so I'm going to go ahead and just click this play button here to run our application and as it starts up you'll see some information in the console we got this awesome ASCII art here spring so spring Boot and it displays the version of spring boot you're on and then there'll just be some logging here so this is logging by the system you haven't done any logging yet this is the system kind of logging some things out letting you know what's happening in your application so we see that we are starting our application using Java 17 we no active profile set so we're falling back to a default profile we'll talk about profiles at some point through here and then we can see that Tomcat was initialized on port 8080 so that is the default Port as you'll come to find out everything in Spring boot is configurable well not everything mostly everything but we provide sensible defaults like we have defaults so that you don't have to go in and configure everything to just get something started we provide some defaults and you can always come back and change this later so if you wanted to change the default Port you can so we start on 8080 that's using Tomcat we are on the latest and greatest here which is Tomcat 10.1 this is as a spring boot three we have moved to Jakarta ee10 uh so again we'll talk more about that as we go so now that we could see the application has started on 8080 and this is how long it took to run now if I want to stop this I'll just go up and click this big old stop button and our application is stopped so how else can we run our application if we go to a terminal we can open up a terminal again we are using this Maven wrapper so if we go Maven wrapper there are some commands that we can run in Maven so if we look at in IntelliJ there's this nice Maven tool here that shows us what is available so we have different profiles we have different life cycles plugins so we have a spring boot plug-in and these are all the commands that we can run as a spring boot plugin so we could do things like build an image Run start stop so what I'm interested in is this spring boot colon run so what I want to say is spring boot colon run and it's going to do its thing and at the end of the day this is running this is the same application that started up before you can just see um here in the terminal we're doing all the same things and it's exactly how it was now if I want to stop it on Mac here I'm just going to hit Ctrl C and that kills that process so I'm going to go ahead and close that and close my Maven window and I'm going to start it up one more time here and with it running I'm going to head over to the browser and I'll go to localhost 8080 and this is the default page that you're going to get this white label error page this application has no explicit mapping for slash error so you are seeing this as a fallback so you can Define your own slash error page we can see the error there was an unexpected error type not found status 404 so there is just nothing available at the resource that we're looking for so at the root context there's nothing available and that's true we have not done anything yet in our application so there is nothing available so I just wanted to point that out because if you see that you might think well something's not working it's just because we haven't done anything yet and we can also do that via the command line so we have different um so if you view it in a browser or you view it from a command line we we see that as a different context right so we have this idea of context and we know how to display information to you based on where you're coming from so here I'm using a tool called HTTP and so what I'm going to do here is just make a get request to localhost 8080 and as you can see we are getting some information back so we we see that it's a 404 error so in the context of a command line we're just going to send you back Json we're not going to send you to a page right so we send you this here is the content type application Json here's the response and then here's the actual response you're getting an error the path is this and that is not found okay so one final thing in this section I just want to talk about structuring your code so now at some point you're going to start writing your own code so remember we have this Source main Java and then this main package the first kind of advice that I will give you is that you want to place all of your code within this particular package you don't want to start creating code outside of here so if you create something in the Java folder it will basically be a default package which means no package and you don't want that it's not going to find it it's going to be really hard to use here inside of our application and it's just going to make things a bit messy so kind of tip number one is whenever you create something new try and make sure you create it underneath this package you can create sub packages so I can come in here and create a new package called controller and you can create classes inside of that package and so on but this is the root package try and keep all of your classes inside of here now the next thing I want to talk about is kind of how you would structure your application the nice thing here is that spring doesn't really care this is up to you and your team so you could put everything inside of this main package and not you know create sub packages you can just stick a whole bunch of classes in there if you wanted to probably not the easiest thing to maintain that way but it's it's going to be just the same it'll work so there are a bunch of different approaches to how you could structure your application so you could structure them you'll see me do a lot of this in my kind of demos where I'm structuring them by the type so in this case I have a package for my controller I might have a package for model I might have a package for um service and then config and repository and all that and then no matter all the different types in my system so if I have like a Content so when we get into this we'll have like a content type a status type a tag type A type those will all go in the model folder and then I have a Content controller and a status controller Etc so that's how I'm organizing my content in this particular course but you could come in here and say I want to kind of pack you know I want to separate these by the different resources in my system so I may say like I'm going to have a content tent and I'm going to have another package called user and inside a user all of the things are going to be there the model the controller the service the repository all the things that deal with a user are going to be in that particular package um so again there are some pros and cons to each I don't think um you know somebody can come along and tell me otherwise I don't think it's at least for what we're building here it doesn't really matter so I think the thing to to just take away from this is that it's really up to you how to structure the your project but the one thing you want to do is try to keep everything under that main package okay so with that we know how to run our application we know where code's going to go let's go ahead and talk about some of the fundamental Core Concepts of spring before we dive in and start writing some code I think there's we need to take the opportunity to talk about a few Core Concepts in spring now we could talk about a lot of the Core Concepts in Spring and a lot of the fundamentals of spring boot but I just want to cover a couple and then we'll start writing some code I don't want this to be too much Theory I want us to to learn a little bit Theory and then apply that in code so I'm over at spring.io if you go into projects and go to Spring framework and you go to learn there is the reference doc so let's go ahead and click on the reference Dock and just so we're clear 6.0.4 is the latest that is GA when you select springboot 3.0.2 this is what you're pulling in you are pulling in whatever the current is most of the time when you're on the latest version of spring boot 3. so we go over to the documentation and I want to take a look at the core section so we're going to talk about the spring ioc container the application context and beans and again we're going to cover this at a very high level we could spend a long time doing this but I I want to be more practical with this and kind of apply this stuff in code so you can take the chance to go through this documentation but what we're going to talk about here is mainly the ioc container and what that means and when it comes to kind of the application context and beans in Spring and so these are two terms that you're going to hear that you may hear and they may kind of start to scare you off because you're like what the heck is that what is an application context what does it mean and I want to take the chance to kind of go through there so let's start with the ioc container and the application application context to do so I'm going to head back over to IntelliJ I'm going to go ahead and on the Mac option command o there's a way to get up here and go to I'm going to type command o here and I'm going to look for something called the application context and we're looking for the one here in Spring framework so if I go ahead and click on that and pull down the sources we can see that this is a interface and it extends a whole bunch of other interfaces so let's kind of scroll up here and take a look at the definition here and this is a central interface to provide configuration for an application this is a this is read only while the application is running but may be reloaded if the implementation supports this and then here are the different things that the application Pro context provides one of which is a bean factory so we can think of kind of the application context the container of the application I like to think of it as this bin let's say I had a bin in my house here and I had a bunch of books in the bin each of the books have titles on the side but the bin is really just a place to store all these books right so I have a bunch of books in a bin or on a bookshelf and when I want to get a particular book I ask for it by title so give me that new book on Spring boot 3 in action right give me that book by that title so the container or the ioc container or the application context is a way for us to get classes when we need them and we can get them by name we can get them by type we can do a whole bunch of things but at the end of the day the container is just this bin that holds all of the classes in our application and at any time we can go ahead and ask that bin for a particular class so I want to see this in action this application context extends a whole bunch of other things and that's what gives us some of the functionality that the application context has so if we look at the packet structure here we can see that in this application context we can do things like get the name get the display name not a whole lot here at this level but then if we go into something like the listable bean factory we can do things like find out all the beans in my application or get all the names of all the beans in my application so there's some more functionality here and then as you go down into some of these different interfaces there's a whole bunch of functionality that we can get out of this so that's where I want to start what is this kind of application context the reason I bring that up if we go back to this remember that this static method this run method actually returns something called a configurable application context configure about configurable application context extends that application context that we were just looking at so what that tells me is if I come back here and I introduce a variable so say here here's our context now I have um an instance right I have this context that I could probably do some work with so one of the things I can do is remember the context has that get bean definition names so what is this this is going to return a an array of strings and this is all the beans defined in the factory so hey this is great I can get all the beans that are in my application right and what one thing that I might want to do with this is turn this into let's say a stream so we're going to use a raise dot stream we're going to have all of the beans at least all the bean names and then all we're going to do is say for each I want you to go ahead and print them all out so let's go ahead and print them and again this isn't something you'll have to do in your application I just want to kind of show this off so we can see what's going on here so if I go ahead and run this application you see a whole bunch of things were printed to the console here and again these are all the beans in our application I say Dan I didn't I didn't write anything yet what are all these things going on in the background here and that's exactly what they are they're happening in the background these are beans that the framework has created for US based on the type of application that we are building with one exception there is one here called application and that is our application so that is also a bean so these are all the things that are going on in the application right now again you won't need to do this this is just a little handy trick and I wanted to point that out because I want to talk about beans so we keep hearing the word Bean what is a bean Dan so I wanted to go ahead and virtually I know you can't see you but go ahead and raise your hand if you've ever created an instance of a class okay I'm looking out virtually over the entire audience right now and I see a lot of you raising your hands that's great um that most of us have done that right well at the end of the day that's all we're doing we're creating instances of classes a spring Bean is nothing more than an instance of your class with some configuration metadata around it things like what is the name what is the scope there's a whole bunch of things and if you want to go back through the spring documentation you will see that so now the question becomes okay this application class was created how do we create our own beans fan how do we do this so let's go ahead and take this for a test run let's create a new Java class and we're just going to call this a message so if I go ahead and create this class and I save it and let's say maybe we have a method in here maybe we have just a public string get message or actually let's say git yeah that's fine and then we're going to return hello so this class does nothing more than have a method called get message which returns hello world so now if I go ahead and restart my application here and I look for something called message I see a bunch of things called message in here but that's not the beam that I just created so what happened I created this class why isn't spring adding this to this big container we keep hearing about the application context and that's because spring needs to be told about the classes that you want it to manage for you there are a couple different ways to do this there is at a class level we can use annotations so the generic annotation that you'll see all the time is at component and if we go ahead and dig into this you'll see that this indicates that an annotated class is a component in such classes are considered as candidates for auto detection when using annotation based configuration and class pad scanning which we are using if you do some searching for spring out in the wild you may see a bunch of old examples where there's all this XML defined and we just don't do that anymore we use annotations and Java based configuration so much easier so that's what this is saying this is saying okay if you add this annotation to your class we are now going to know about it the application will know about it um and the application context and it will add it to its container so let's go ahead and run this again and now look for message and you see there is a bean called message now the way that the bean name works is it just takes this class and uses camel casing so it'll start with lowercase M if this was like message Source it would be lowercase m capital S right so that added it to it now there are again I don't want to get too far into the weeds there are ways to configure like what is the bean Name by default this is a Singleton they'll only be one in existence in the application there are ways to to kind of customize that again look through the documentation I think it's a good just to kind of get this overview and then you can dig deeper if you want so that's a component there are specialized versions of this which we're going to see throughout this crash course there is one called a service there is one for a rest controller which we're going to be building on today which is nothing more than a controller and as you'll see with all of these specialized annotations they are just made up of other annotations but at the end of the day they're all components so if you wanted to just use component you can if you wanted to use the specialized versions of these there's repository um and yeah so there's a handful of them so that's it so now I'm going to go ahead and delete this message I'm going to revert this because we aren't going to like I said need this anymore and I just want to show you one other trick so if you don't want to have to Output all the bean names which you probably don't want to you can just run this application if you're in IntelliJ IDEA Ultimate Edition you can come down to our spring tab here and you'll see there's a beans tab so we can click on content calendar we can click on the application on the application and these are all the beans in this app we can see application we can see kind of how it was configured so if we go down to something like the cache manager we can see that there is a simple cache configuration and then the bean is coming from that cash manager so real nice way to kind of dig into kind of the internals of what's Happening Here but instead of having to just kind of print these out to a console which you won't want to do there's this nice UI in IntelliJ to print out all of these beans okay so now there's one more instance so we saw all of the annotations component controller service repository those will all work at a class level but what happens if you don't have a class what if you are creating an instance of a class maybe that you don't have the control over maybe you can't just slap a annotation on it let's look at an example so I'm going to create a new package and we're going to call this config and inside this config I'm just going to call this my my web config so in here in my web config I may create something of a type called rest template so rest template is something that the spring framework provides and it's a client that you can use to say call out to a public API or another service within your organization and so what I want to do is create an instance of this rest template so I would say return new rest template Builder dot build and that will return a new instance of that now the name of the method is the name at the end of the day will be the name of the bean that we use but how do we create a mean so we can't use that component like I said this is a class level annotation so it's going to tell us that that we can't use it here so we have a method level annotation and that is beam so the bean annotation if we go ahead and look at that indicates that a method produces a bean to be managed by the spring container again there's some really good information here in the documentation you may want to dig into that but that is the being the name of the bean is going to be the method name so this name of this beam will be rest template and if we go ahead and we're to run this now nothing would work why is that then when you want to define a bean you need to do so inside of a configuration class so you need to mark this class with at configuration and now it will go ahead and say okay I'm going to look for bean definitions and in fact I found one I'm going to go ahead and use that and put that in the application context so if we were to run this again look at the bean definitions you would now see an instance of rest template and again why this is important is anywhere that we want to use an instance of a rest template before we had our message class now the application context is handling it for us so we can just get an instance of it and to show that off let's go back to our class here and let's say that we want to create a bar let's do this again context and what I could say is context dot get bean and get it by the name so I might say rest oh whoops I'm sorry rest template and that is going to be so it's going to be an object we cannot go ahead and cast it to that if we wanted to let's say rest template because we know that's what it is and let's just go ahead and do that and we'll run this and you see that we just get that signature there so um but then we can go ahead and use this if we wanted to so one of the methods in a rest template is to go ahead and get for an entity so we could call a URL and get a response type of type whatever so yeah just an example of using Bean so at the app Bean annotation is used when you need to define a bean on a method that returns some class so again I think you can take some time to go through the documentation after we go through some of this stuff I wanted you to kind of get this high level overview we'll write some code that will help kind of reinforce it and then you know after this crash course come back and dive through the documentation and really go through and and take a look at what the container is what these beans are there's some really really great information in here it can just be a little inundated if you haven't done anything with it yet all right so let's start writing some code the first thing that we're going to focus on here is the domain in which this application is kind of built around as we talked about this the idea here is we're building out like a Content calendar so I'm going to start with content and to do so again you can kind of split this up however you want to divide your application I'm creating a model package here I'm going to create a class inside of here and not just a class I'm going to create a record so we are going to create a record around the idea of content so that is going to be our main type now when you define a record you don't define properties you define these components of a record and as you can see uh get up Copa it's getting really good at this let's go ahead and turn GitHub copilot off just for now so we can work through this so I'm going to start with an ID we are going to have a title so what is the title of this piece of content that I'm working on we're going to have a description to describe that content I want to have a status for the content so this is going to be an enum we'll go ahead and create this in a second I also want a type we'll call this content type this is like is this an article or a video or anything else we'll create that in a second as well that should just be an enum as well and then I'll have a local date time for when this piece of content was created and a local date time for when this piece of content was updated so this could be null to begin with then we'll have a URL where this content is located so cool that is pretty good um then what we're going to need is a status so in IntelliJ I'm control clicking control enter we're going to create an enum for this right inside our model package so this is going to be let's talk about um so status I want to start with an idea so I'll have an idea then after it's an idea and maybe a work in progress then when it's done I'll say it's completed and then after it's completed it's now published so those are some good statuses to start with next I'll go ahead and create a type this is also going to be an enum and we will go ahead from here and these could be we could have a whole bunch of types here I'm going to start with article video course and then maybe a conference talk those are some good ones that we could expand on this later but that's a pretty good start I think so there it is that's our record uh we have an ID title description status type Day created date updated and a URL we may add the something in the future for like tags so if we wanted to like tag this particular thing with like spring Boot and graphql or whatever were the topics or categories that we're kind of talking about um but we'll revisit that later so I think this is a good start with our model in place we can now start to write some code around uh this idea of a piece of content in our system all right so with our content model in place we can begin writing some controller code so I'm going to in a package called controller I'm going to create a new Java class now the convention for this is the resource that we're working on so that is content and the suffix of controller this is not a hard roll you do not have to follow this rule you will just see this in a lot of spring applications so in this case it's going to be content controller and this is a class that's what I'm going to stick with here so as as we've created this class we've done nothing special it's just a class in the system right now what we're going to do now is Mark this with the at rest controller annotation so we've already kind of gone through this you understand that this is a specialized data uh specialized stereotype which is really just annotated with ad controller so this is saying Hey I want to go ahead and I want you to pick this up and and create an instance of this controller for me and stick it in the application context the next annotation we're going to mark this with is request mapping so request mapping is hey what is the path to this controller how do I go ahead and get to this and in this case we'll just be API slash content so now what is a controller a controller is really just a class that is going to accept requests so I'm accepting a request and I'm going to return a response you'll find a lot of the crud methods in here so hey I want to list all the pieces of the content in the a application whether it's stored in memory or in a database hey I want to find one particular piece of content I need to create read update delete filter sort page you know all of the things you might do around a particular domain like content that we're working with so that's the first two kind of annotations that you need to understand as we're building out an MVC application now before we go further in here I want to create a another class so we're going to create a new package in here I'm going to call this Repository and Insider repository I'm going to create one called let's create a Java class called content collection Repository so I'm not just going to call this content repository because we're going to call that one later when we create a spring data repository so this is not a spring data repository we are not talking to a database but I am going to mark it with that repository because again that is a specialized stereotype marked with that component so now our spring application context will pick this up and what we're using this for because we're not talking to a database yet is to just keep a collection of pieces of content in memory so that we can work with them in our application so to do so I'm going to create a private final list of content and we'll call this content and this is just going to be a new arraylist so we're going to initialize this arraylist here we're going to have a Constructor and then we're going to have a couple methods let's just start with one to list all of our content we'll call this find all and that's just going to return content then we need a way to get a single piece of content and I'm going to have this return an optional so if you're not familiar with optionals in Java this is basically a way that a value may or may not contain a non-null value so it's just a way to kind of not have to deal with nulls and get those like null pointer exceptions so there are methods around this to say like is this thing present if so then I can go ahead and get the actual value out of there um and so the reason I'm doing this is this is what ultimately the spring data repositories contract looks like and I want to keep this kind of similar so we're just going to say find by ID and we're going to take in an ID now why is this an integer because our content has a integer ID so when we're looking for a particular piece of contact content we're asking for it by its ID so I'm going to get that arraylist so I'm going to get that list of content I'll just turn that into a stream real quick I'll filter on that and now I can say hey go ahead and give me the ID of the content and I want you to see if it equals the ID that was just passed in if so go ahead and find the first and that returns an optional so if we look at that that will return an optional of type t Okay so with that in place now we can come back to the content controller and talk about dependency injection so we've learned a lot of the concepts of this already and I'm going to leave a link to a video that I've done on an in-depth tutorial on dependency injection in Spring I don't want to go too far in this because I don't want to make this video too long so we'll just cover this very quickly but let's say that we had a uh actually let's go ahead and generate this let's say we had a Constructor here and we need an instance of this content collection repository right we need that because we are going to use it here we're going to use it in our controller when someone asks for all the pieces of content I'm going to delegate to that content collection repository to say hey go ahead and find me all the pieces of content in our system so one way you might do that is you might create let's get rid of that you might create private content collection repository and call this repository and then here in your Constructor you may say repository is equal to new content collection repository so this might be your four your first kind of take on how to accomplish this but anytime you see the new keyword in Spring it kind of should raise your eyebrows right because we've talked about this thing called the application context which is responsible for managing all of the instances of our classes in our application that is why it's also called inversion of control we are no longer responsible for creating new instances of our classes we are putting that onus on the framework the framework is going to handle it for us so we no longer should be doing this and we know based on what we've learned already that marking it within that component there should be an instance of this in the application context so ultimately what I'm doing now is creating two instances of this in my application when I only need one so we want to get this from the application context we want to inject any dependencies that this controller has into the Constructor as one form of dependency injection so we are dependent on this class for our controller to work so that is a dependency so there are ways to get this dependency into this controller class I'm only going to mention the one because it's the preferred one again go back to the video that I'm going to link to if you want to kind of learn about all of them so what we're going to do is make this an argument to our Constructor we'll call this content collection repository and now we can say this dot repository is equal to content collection Repository now an easier way that I like to do this especially if you're here in IntelliJ we are going to make this final because we don't once it's created we don't want to have to change that we don't want to recreate it this is a final variable once it's created it's done when you do that IntelliJ will put this little squiggle here and say hey oh do you want me to add a Constructor perimeter for you yes I do now I automatically get that created for me so now I have that Constructor this little icon over here in the gutter says is telling me that we have a auto wired Bean being injected into this Constructor for me this is also the same as saying at Auto wired on the Constructor at Auto wired is basically saying hey this is a um this is something I want injected so um this is an alternative to this annotation um but when you only have one public Constructor in your class this is implicit so you actually don't need it on here it's the same thing the framework will kind of add it for you but that's what's happening so now I have an instance of the content collection or pository so now I want to create something that allows someone to make a request and find all the pieces of content in the system right so how do I do that well first we write a method we're going to write a method right this is going to look eerily similar to that one we created before we want a list of content where are you at where are you at um there you are and we're gonna call this one final again you can name this whatever you want but how am I going to get all the pieces of content I'm going to use that repository that we had injected into this controller for us and there's a method called find all now I know because we just wrote it that also returns a list of content so I'm going to do that so now I have my method now I need to make this available to the outside somehow so there is an annotation called request mapping which we already saw up here but there are also specialized versions of that request mapping annotation one of which is git mapping so git mapping says I want to go ahead and handle get requests and what is the path I'm going to leave this as an empty path because we've got a request mapping on the class itself so the path for this is going to do is just be slash API slash content that means once we start up the application if we go ahead and visit localhost 8080 slash API content we should get all of the pieces of content in the system so if we do that and we go to generate a request so here is that request if we look at that everything is fine we got a 200 we just got an empty array because we don't have anything in the system yet which is fine we can go ahead and create some if we wanted to so we could do this a couple different ways we could go ahead and do this in the Constructor if we wanted to you can also use something called a post construct so this is hey I'm going to have some method that is going not going to return anything I'm going to call this a knit and now this post construct will get called after this let's just double check with the documentation says I believe it's like after the um it's a post construct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization so again all we're doing here is we're saying con um let's create a piece of content so content C is equal to new content so now we have to provide all of the information for this so I might have one what is the title uh let's just call this my first blog post and I'm gonna see if I could get this on separate lines because this is going to get pretty long so I have a title I now have a description so that is going to be um same thing my first blog post then I'm going to have a status so let's just say that this is an idea the type is an article they created is right now has not been updated yet and the URL is just an empty string for now so there's my first piece of content so now what I can do is say um on the content this is the list of content I could say content dot add and then I'll just add that particular piece of content so now if I go back to this and actually restart the application we can see that in there and again I don't think we've gone over this yet I just assumed that we did um so let me go back to the browser and remember localhost 8080 is going to be uh have that error because we haven't created anything there but we did at API slash content so this is one way that you could test it I'll show you the um the HTTP client in IntelliJ and in a little bit so before we would we would have gotten this empty array now we have a single piece of content in our system so with that in place we have a way to kind of list all of the pieces of content in the system we really want to build out the rest of Crut which is create read update delete and we won't get to them here today but this could also be any other methods that need to be in this controller so if you wanted to like filter by something or do some like paging and sorting or whatever else you needed to do so let's go ahead and build out the rest of that in the controller now all right so next we need to provide a method to go ahead and get a particular piece of content by its ID so we're going to use git mapping again but this time we're going to want to use an ID so I might do something like this right I might say okay at slash one go ahead and get me the content for uh that has an ID of one but this doesn't scale very well right like we would have to create this and do this oops and we'd have to do this like 27 000 times if that's how many pieces of content we had so what spring does is gives us the ability to use a dynamic placeholder here and we could say Okay ID is there I want to look for something um for some ID but this is going to be dynamic and then we can reference reference this in our method so I want to go ahead and return an optional piece of content and we'll call this find by ID and now the ID is going to be of type integer and how are we going to map this thing to this thing and that's what the path variable annotation is used for so it's going to assign whatever's in the path to this particular argument name all right so now that we have that we can go in our method and we can say I want to return let's think about this so if we just return return whatever the repository dot find by D and pass the ID that may work let's see if that'll work so we're going to restart our application we're going to go over to the browser and we're going to get all of them and now we're going to say give me one by its ID so if I do slash one great we get that one particular piece of content this is great so at this point you'd also want to probably handle for what is going to go wrong so like if I ask for something that is at 99 I'm basically going to get null back so what we could do is say we're not actually getting that we're saying uh or else throw let's throw a um new response so response status response [Music] status exception so we're going to throw a response status exception we basically want to say that the status is not found so that's like a good 404 and then I provide a message and say content not found okay this is complaining why uh this required type is optional but what we provided was content so I think this is because of our fine by first right so we're actually returning the content here and not the optional okay that makes sense so let's go ahead and restart that and check this out as well and so now if we throw this we are getting a 404 we can't find that one and if we ask for one we are getting that particular one so so far so good um this is looking good now we need the ability to create a new one so let's go ahead and say public void we'll call this create and we need to take in some content right then what we can do is we can use our repository we can call something let's just call this save and we'll pass in our content now save does not exist over here so what we need to go ahead and create this so here all we're going to do is um we're actually going to say content dot add oops so we don't want to call this content because our collection here we should probably rename this this is a terrible name Dan let's call this content list right now I can say content here call this content if I wanted to and I like this to be last okay so content list dot add this piece of content right um so this is almost going to work but we will have to like provide the ID for this which is okay we can create like an atomic integer here and maybe we'll do that in a minute but for now this should work okay so now the question becomes okay well I need to handle this in a post request right when we're creating a new resource and a rest application we're using a post request um so the way that we handle this is by so again we have specialized mappings for get so as you can imagine we have a specialized mapping for posts so we call this post mapping now this can take in whatever the path is so like API slash content but again we've already set that at the class level so we can just do the same thing we did with the git mapping and have an empty mapping here so now this post mapping is going to respond to a post request at slash API content now the only other thing is we have this content but we need to somehow tell spring that this is going to be sent as part of a request body in a request right so the way that we do that is by using the request body annotation and so if we dig into this and download the sources it'll tell us that hey this annotation is going to indicate that a method parameter should be bound to the body of the web request and so we'll see what that looks like in a second so now we can't really use the browser anymore so we've done some initial testing I'm using testing lightly and in air quotes the testing is just hey let's make a request and see if it works but we've done that in a browser because the browser can handle a request we can't do a post request just by putting a URL in our browser we need a tool for this so there are some great ways to do this you can do this from the command line using something like curl or one of my favorite HTTP IE which is just a better version of curl that adds in a lot more support for doing things like this there's a tool called Postman which if you've been in this world I'm sure you've seen or used I like that one as well the one I kind of showed you already was the HTTP client here in IntelliJ and I really like that because I don't have to leave the tool that I'm in to do something so I'm going to do that so I'm going to go to well you could just say generate generate this request in an HTTP client but I'm also going to show you a trick here which is you can create a new file in your project and I'm going to just call this uh content it's content.http so anything that ends in dot HTTP will be one of these files that the HTTP client can use so we've already seen we can um do something like where is this one let's just show what this one looked like so let's copy these back to our one so the um triple triple pound sign here is like a comment so I could say uh find all content I can say get content by ID and now we can do is say create a new create new content and so what we want to do is we want to do a post right so we want to do a post to this particular URL oops this URL so how do we add the body for that now well the first thing that we need to do is we need to set the content type to application slash Json and then down here we can just give it a body so here is what the body is going to look like so one trick I have here is let's just run this one where we get a particular piece of content and all I'm going to do is copy that now and this is what the request body is going to look like so I'm going to say this is my second blog post my second blog post this is an idea this is an also an article we'll just keep that same day created date updated and our URL which is going to be blank so if I do this I'm going to go ahead and restart my application so this should take into account the new post mapping that we have I'm going to try and post this particular request body to slash API slash content that would create a new post now the the response as it was a 200 I have no response body because in fact if you look at my controller I've basically said I'm just going to return nothing for this so the only way to kind of check this now is if we go ahead and list out all of our content we should see that we have two in there and we do so we have my first and then my second so this is great but one thing I want to add to this is whenever we create a new resource in a system the caller who's making this request should have a better indication that something was actually created and to do so we can use the response status annotation and say that we want to return an HTTP status HTTP status dot created and that will create a 201 so now when we restart our application we only have one in our system because that's all that loaded up I'm going to go ahead and create that second one and now you see we get a 201 so at least we have some indication that a new item was created in the system all right so we have our lists we have our get we have our create we need a update and a delete so let's work on the update now so the update is going to look pretty similar here we're going to have a public void we'll call this update we are going to take in the request body of content content we are also need to figure out exactly what piece of content we're trying to update so we may say integer ID let's just return null for a second so actually we don't even need to do that because we don't return anything from here so this should be an integer Dan and now we're going to use um so so whenever we create whenever we update something we are not performing a post we're performing a put and so we also have a mapping for that called put mapping and again this is going to be similar to the read we are going to be working on a dynamic ID so we're going to say slash ID and then we can go ahead and use the path variable to get that idea out of the path so now that we've done that the first thing I want to do is make sure that that ID exists so let's write something to say if um the repository let's create a method called exists by ID and we'll pass in the ID so if it doesn't exist by ID then we're going to do something similar to this we're just going to say row new response status exception content not found and then we're not going to do this in this crash course we'll probably jump to this in more of a full course but I would probably create a custom exception for this like my content not found exception uh you can go ahead and do a search for that and it's fairly fairly trivial to do so uh if you want to replace this later you can if we don't throw that exception though I'm going to use the repository dot save method and pass in that content so we've already created the save method so I just want to create a method called exists by D and this is going to return a Boolean so this is going to look pretty similar to this except we're not going to find first right we are going to say we can go ahead and call count on this and we can say does that equal one so if it does it's going to return true if it doesn't it should return false so let's go back here um that looks good um sure let's go ahead and test this out so I'm going to do something similar to this and I'm going to say um update existing content so I'll pass in a one we'll see that we are calling slash one um we'll just say my let's just do this all caps my first post we'll do the same this is how we know it'll be kind of updated um the and then what I want is oh yeah that is the and then what I'll do is I'll just create like an updated time stamp as well I'll just pass this in here this is all the same and then maybe we have a URL now localhost 8080 slash some or my first blog post right okay so let's see we are going to create a put so we are sending a put request to local cd80 CPI slash content and then the ID of the one we are trying to update so we'll test this out first and then we'll test one with like 99 to see if it throws that 404. uh we are sending some Json here's the payload this is the request body uh the ID is one um title description yep okay this looks good let's go ahead and try this uh let me just restart this I don't think I did yet and then I'll go ahead and make this and I have a 200 so I think that is good let's go ahead and just list out all of our content we should only have one and there we go so we have oh nope we've created a second one oh and I know why that is okay so we've created a second one but the right one that we're you know it actually created one which is good the update part worked in our controller but in our save method here we didn't uh write the logic to say hey if this particular uh post or content already exists in there go ahead and just replace that one if it doesn't then go ahead and add it so uh we can go ahead and do that so let's get the ID uh basically out of the content if it yeah so let's say oh actually it'll be there no matter what all right yeah so I probably would have created an update integrate but to handle both um let's just go ahead and do something so there is a if we look at content list there is a remove if that takes a predicate and so basically we could just say hey if that piece of contents ID is equal to uh content dot ID then go ahead and whoops content.id then go ahead and remove it so we're just removing it and then we're adding it back in again this is kind of arbitrary because we aren't going to use this in-memory collection in a real world application we're going to move to a repository that talks to a database but I just wanted to put this in place so we can understand how this works before we move on to the database stuff so let's go ahead and try that now I'm going to go ahead and restart the application I'm going to go ahead and put so we're going to call put we get a 200 if we look at find all content we see there's only one in there now and it's been updated to use the new information so conversely if we will go ahead and do this and we say update existing content with uh invalid ID let's just go ahead and do this at 99 and try to run that and we do get a 404. all right so we're getting there um create read update we just need a delete actually I'm going to do one more thing here we I forgot about this on the create we use the response status to say hey basically this is being created I like the idea I'm going to put sending back no content like yes you got a 200 but I want to change that status to say like everything's okay you just didn't get back anything because we're not sending back the newly updated one we don't need to you already have all that info so I'm going to use the at response status and say HTTP status um dot no content so that will just give us back a different status code and actually I'm going to do the same for deleted so let's do that and then we are going to public void delete so delete is just going to take in the ID of the piece of content that we want to delete and then we will say repository dot delete by ID or we can just call it delete for now so we'll pass in the ID now we're going to get this from the path variable and again if you've been following along you can kind of guess what this mapping is going to be yes it is a delete mapping and so again we will pass in a dynamic ID assign it to this argument and then we will call delete on here now we do not have this delete method in here so we need to go ahead and delete it so we'll just say our content list dot remove if and again we just did this up here so this should look pretty similar to this so C dot Eddie equals and then we'll just say i d okay so let's go ahead and restart application and let's go back to our HTTP client and all I'm going to do is copy this and we'll say this is a delete by ID and we'll give it an ID of two let's create that second one and then we'll go ahead and delete it so we'll name one in there now let's create that second one uh more is our post so let's create that now we should have two so we have two in here so now let's delete the second one and remember this should return no content so um did we 204 good now if we go back to find all we only have our one blog post in there so this is great um that is all of our crud operations we kind of knocked those out and again what I really love about this HTTP client is now this file in here is in the repository this is something you could pull down with the final code you can take a look at it and you can run your tests right right from the IDE instead of having to go out to a separate application so I'm a big fan of this I'm a big fan of what we've done here again we're just kind of using an in-memory representation of all the pieces of content in here we're going to move this over to a database soon but before we do I want to touch on just one or two other things here in the NBC world all right so I want to talk about something called cores but to do so I have to create a little bit of a front end and that's okay I've created a very simple one that we can take a look at I'm using Veet Veet is this really great kind of framework agnostic tool that can create a bunch of different front ends in whether it's vanilla JavaScript or viewers felt or react whatever you're using you can use V4 so check out veetjs.dev I've created something very similar simple this is a vanilla JS project all it has is an index.html IT points to a main.js in main.js I am fetching I'm using the fetch API to say go ahead and call localhost 8080 slash API slash content that is that URL that's going to give me a list of all the pieces of content in the system when you get that back turn it into Json we know we are returning Json on from our application and then just log that out to the council pretty simple in here I can I have a live server that I can use it's an extension to basically run this application again this is our front-end app it opens up in the browser it goes to 5500 and I don't see anything if I look in the console here is our problem this is a problem you're going to run into if you're kind of building clients that talk to this rest API on the back end so it says access to fetch at localhost 8080 API content from the origin so origin is local basically localhost 5500 so it's a different port has been blocked by Coors policy the no access control allow origin header is present on the requested resource so ultimately what this is saying is this is a feature of the browser that is helping us with security saying you have two different apps trying to talk to each other on different ports or domains or both I'm not going to let you allow you to do that so what we can do is in our server side code so in our spring boot application we can set up cores to basically say uh this is the these are the resources that I'm going to allow to talk to this API so how do we do that so let's go back to uh IntelliJ we're going to do this at the controller level so I have a video on this as well that goes in depth into this on how you can do this at the controller level and the method level and hey what happens when Spring Security gets involved so go ahead and check out my YouTube channel for that if I haven't mentioned that already there's a lot of really great resources there youtube.com at Dan Vega so what I can do though is come over here and say cores so this is the cross origin annotation and then you can start to Define some different parameters in here so let's look at the cross origin and we could say okay we we can have different Origins so a list of all the origins for which cross origin across origin requests are allowed so this could be like a specific domain and Port so in our case that's like localhost 5505 I think it was you can get very specific on what headers are allowed so um possibly star to allow all headers um methods so maybe I only want to allow get requests to this maybe I don't want to allow anyone to do like posts or puts or deletes and then you can have credentials and then a max age to keep this very simple I'm just going to add the cross origin annotation here which by default so if you look up here permitting cross-origin requests on specific handler classes um it says the default values are applied via cores configuration.applypermit default values so let's go ahead and do that so I'm going to do that restart our application go back to the browser and visit my front-end application and now you can see that the blog post the one blog post that we have in our system was now returned to the application so that is now something that we could do we could use in our application we could turn that into like say an array of pieces of content and then just write a normal front-end client to kind of iterate over those pieces of content into slam or display a single one again this is I do a lot of this in my blog actually I do it via graphql but that's neither here nor there so just a simple front-end example talking to our API to bring up this idea of course if you're getting this error that error that we saw in your console that is a course there that is something that you need to handle on the spring boot side okay one final thing that I want to talk about here in the spring NBC section is data validation so we talked about building out our controller to kind of header have our crud methods in here right two of which are the ability to create a new resource so create a new piece of content and update a new piece of content but what we haven't talked about is the content that we are accepting from someone so whoever's calling our API this content needs to be in a particular format if it's not then our same method may not work so at some point we need to do some validation on the data that is coming in to us right we don't want to just blindly accept anything that comes into us so I'm going to go back to my palm and this is our first kind of introduction to adding a new dependency that we haven't thought about and that's okay as you start to build out your application you're going to realize oh I need uh this particular dependency or that one how can I go ahead and add it so right here in IntelliJ I'm going to go ahead and say dependency and the dependency that we need is the spring boot starter validation so as we type validation it'll now give us a list we of course want that from orgspringframework.boot and then we don't need to provide the version because again this is a spring boot starter all that's kind of been figured out for us after you add a dependency you got to go ahead and reload those changes here in Maven if you didn't do that when you came over here into content and tried to use something from that validation dependency it would not work so what I want to do on this record now is start to Define what is considered a valid piece of content okay so the first thing is I don't want someone to be able to pass in an empty title like why would you give me an empty title as a new piece of content you must have a title if we want to move forward so what we can do is use these validation constraints so this is coming from jakarta.validation.constraints and you'll see we have one called not empty so if we look at not empty we can basically see that this must not be null nor empty so you can use not empty on say a string a collection a map or an array if you wanted to so this is really nice so you can say not empty you can also use blank so hey I not only do I want this to be empty but I don't want this to be blank it must have at least one non-white space character so I like that now again here are the constraints if we go ahead and look at them and if we dig down into constraints we can see that there are a bunch of them hey I want to I want to make sure that this is an email or the date is in the future or there is a Min or a Max or a null or past or present you know there are a whole bunch of constraints that you can use kind of right out of the box if you want so for me not blank is good I like that one um I may put that on um description as well I may put date created or the date updated as you know future or present dates like I wouldn't create this in the past or update this in the past so those are some other constraints that you can put on as well you can also create Customs constraints if you need to there are a whole bunch of things you can do in the validation world I just want to show you this tiny one just so you have an idea of what to do so once you have that constraint in place if we just did nothing else that wouldn't work what we need to do is when we have a create here we need to mark this with the at valid annotation so the at valid annotation now says okay we see that we're taking in this content via the request body but hey that content needs to be valid if it's not we won't even go into this section of trying to save this piece of content it will automatically kick back and say hey this is a bad request what you're sending me is not something that I want to work with all right so this is a really nice feature so let's go back to our DOT HTTP actually I'm going to restart the application so those changes take effect and in here um in my post I'm going to go ahead and try to send a title with a blank title and if we go ahead and submit this request you'll see that we get a 400 bad requests so now our validation is working you could start to stack validation so if one particular class like our content had another class and say like a list of tags for instance that we were talking about earlier you can go ahead and validate that on the content class to make sure that you don't get an empty list of tags or that inside of that tag you know all those validation constraints are passing as well so you can do a lot with validation it is that extra dependency so just don't forget that you need to add to the spring boot starter validation to go ahead and bring in those constraints at the heart of any application is the data that drives it and traditionally Java has made connecting to a data source reading and persisting data a little bit verbose and complex while on the other hand spring Boot and spring data in particular take this process and simplifies each step of it so you can focus on building your applications spring boot integrates with a number of data Technologies both SQL and non-sql I want to start this discussion by taking a trip down memory lane what I want to look at is an example application on how we used to use jdbc that stands for Java database connectivity to connect to a database in Java and execute queries so here we are in an example application I don't have this up for you just kind of follow along and we'll we'll talk through it so in here I have a Docker file to go ahead and use a Docker compose to kick up a postgres database and it also has some volumes here so it will initiate some schema so once it does this now we can get into our Java application our Java application is just a single public static void Main and we need to talk about how we can connect to a database so first we need a jdbc URL this is the convention this is a string that looks like it has some different parts to it right it starts with jwc colon and then the database type which in this case is postgres and then the URL that we're connecting to the the port and then the database name so all of these things together comprise a jdbc URL then there are different ways that we can create a connection to our database right there one of the easier ones is to use a driver manager to get the connection so that driver manager takes in the jdbc URL that we just talked about the username and password for the database and it will return a connection and when you're doing this in Java we're using a try with resources block here to basically say if anything happens go ahead and throw an exception and get out of here right so if we do have a connection then we can come in here we can check to make sure that that connection is valid we can make sure that we connected to the database so we say if the connection is valid or if it's not valid go ahead and print this out and exit now that we have a connection to a database we need a way to select some data from the database and we use this class called the prepared statement if we look at prepared statement this is an interface that extends statement this has been around since Java 1.1 since the beginning of time time and you can see if you look at this you can see the different implementations of prepared statement in postgres we have this PG callable statement and PG prepared statement so once you have that prepared statement you can pass in something you can pass in some SQL so I'm saying hey go ahead and select star from run and then what happens is you need to use the prepared statement to execute a query and get back a result set so again the result set is an interface that's been around since the beginning of time time time and as you can see we have some implementations of this so if we go down we have things like uh in postgres we have a PG result set and there are some other implementations of it so once you have a result set now you can say all right while there's a next value well there's a next row let's go ahead and extract some data out of that row right out of that result set so I'm going to for each row say give me the title the way that you do that is you use the result set and whatever type you're working with you say okay get me a string get me an integer these are pretty basic but can get a little bit quirky when you start working with different types and enums and local date times you know the things that are kind of out of the norm of just like string and Boolean float Etc once you do that I just print this out and everything works so I'm not going to run this but there are a lot of things that you need to think of when you're working with databases now this is just one particular Connection in more of a traditional web application like the one we're working with you wouldn't want to create a connection for every request that comes through you can use something like a connection pool we have these different pool of connections and as someone comes in and makes a request we just kind of use that connection and then return it back to this pool and so that type of connection is set up a little bit differently what I'm trying to get at here is again this is a little bit verbose all we're doing is making a simple select statement here you can imagine as we're starting to do a lot of crud operations from a database this is going to get a lot more complex so spring boot is going to simplify Our Lives when it comes to not only connecting to a database figuring out these URLs and how to make that connection and how to get a connection pool and hand all that for us behind the scenes and then it's also going to help us with kind of giving us some abstractions on top of this stuff where we're kind of doing this low level database work to get values in and out of the database so that's what we're going to look at in this section we're going to take a look at a couple things and talk about some different abstraction layers that spring gives us and we'll go from there and again we're going to replace our in-memory representation of our collection of content with something that is now stored in the database so let's go ahead and do that okay so the first thing I want to talk about is the spring jdbc API so spring provides a starter that gives us database connectivity API that defines how a client May connect and query a database to get started we would head over to start.spring.io and from the dependencies you can select jdbc API now it's important to understand that if you've heard the word spring Data before this is not spring data we are going to cover that a little bit later I'm giving you these abstraction layers and it's going to be your choice to kind of choose which one fits into your application so the jdbc API will Define some things and kind of give us that Springs jdbc core functionality out of the box we'll also need a database one option is to use something called the H2 debuted database and this is a fast in-memory database that supports the jdbc API and r2dbc access what's nice is it's very small it's very fast it has a built-in browser-based console application that you can kind of look at the contents of your database I'm a big fan of it so we wouldn't generate a new application here but I'm just kind of showing you that if you're starting a new one that's what you would do we can also explore this oh and we didn't choose Maven let's choose Maven we can also explore this and say okay what are the dependencies that I need so I'm going to go ahead and grab this dependency and this dependency copy those and head back to our application our content counter application and here I'm going to just copy these dependencies in so we have spring boot starter jdbc and our H2 database so I'm going to go ahead and refresh Maven to get all of those dependencies back all right so I'm going to go over to Source main resources and open up application.properties remember this is where we can start to kind of configure our application and I want to enable one thing there is the H2 Council by default it's disabled because we don't we don't want to just expose this view into your database on all of your applications you need to specifically enable this so we're going to go ahead and enable this all I've done was add one property here to enable a database console with that I'm going to go ahead and run my application and we're going to take a look at what's going on here so there's a lot more logging happening our application has started on 8080 and now you can see down here hakari pool so this is that connection pool we were talking about before we've added a connection pool for jdbc H2 that's the database type so now that we know what this data this jdbc URL looks like it's an H2 and it's in memory because you can use H2 as a file based database as well and then the name of the database is this weird long uuid and the user is assay so it says it's completed starting up and oh the H2 console is available at slash H2 Council and this is the particular database that you can check out there so let's actually try this let's go back to the browser go to localhost 8080 again we're going to have our error page but now if we go to slash H2 Council we get this little uh login screen that has some settings so what are we logging into this is the H2 database login so if we paste in that jdbc URL that we saw before the username is essay password is blank we can test our connection and we can go ahead and connect to it here on the left is our database with our tables now we don't have any tables because we haven't set this up yet from here you can run select you know you can one run query so if I want to like select star from content I could do that if I had something set up what I want to point out here is that we have done nothing to connect to this database you saw how much trouble that we had to go through in just a normal Java application to connect to a database well we don't have to do that this goes back to some of the things we talked about when we started this crash course which was what does spring boot provide us one of the things it does is auto configuration it saw in our Palm that we are using spring boot starter jdbc and oh we have an H2 database so put these two together there's some configuration Class Auto configuration class behind the scene that goes well if you have this jdbc stuff and you have this database you probably want a data source connection created for you of course if you need to somehow get at that and customize it you can or override it sure but out of the box we're just going to give you one so you've done nothing and you have this connection to a database which is great because these are the trivial things that you as a developer don't want to really deal with you want to work on the actual requirements of your application and this what is what allows you to do that so with the database in place I am going to change a couple properties we are generating this weird unique name and that's okay for a test but I don't want to do that every time so I'm going to say generate unique name equals false and I'm actually going to set a data source name so I'm going to call this content so now if I go ahead and restart this application you can see that we're started on 8080 but now content is starting so jdbc H2 mem the database name is now content so if I go over to my H2 Council and reload this instead of all of this it's just going to be content and if I test that I can connect to it same thing no actual tables yet because we haven't gotten to that yet now at this point I know exactly what you're thinking I've said it before I hear it in the comments all the time Dan this is great but this is an H2 database this isn't a real database I'm using quotations in the air uh it must be way harder to connect to a real database so I'm going to show you quickly that that is not the case and then I'll kind of revert back to the H2 because it's great for prototyping and you don't have to rely on things like Docker to stand up like this new postgres database you can just use H2 in the code that you bring down so I like it for kind of portability and especially for these demos and tutorials it works out great but what if I want to connect to a real database stand so I'm going to use Docker here again I don't want to go through the tutorial of how to set up postgres on my local machine and connect to it and make sure everything works I'm going to use Docker to basically spin up a postgres container so let's say 3.8 and then we want to create a service so Services DB [Music] we'll call this DB this DB is going to have an image of postgres postgres I think it's called Alpine yeah so we're going to use like a lightweight version of postgres we'll set the ports so we're going to map ports which is going to be five four three two two five four three two um that looks good environment oops environment we will set postgres username and again I'm just pulling this from the docs so you can find those in there postgres password is password and what are we complaining about here sorry okay um so that's it that's my Docker compose file if I go ahead and start this up and run this let's see if it starts it looks like it's done database is up and ready for connections so in my application.properties now I'm going to comment this out oh actually we're going to need a database driver so I'm going to comment out ch2 for now so let's say that we're gonna need a postgres database driver again you can grab this if you select it from start.spring.ao this would come over the same but this is what I'm going to use so let's reload this and go back to our properties and just see how uh how not hard this is to do so I'm going to set a data source URL so again the URL is going to need to be that jdbc URL format so I'm going to say jdbc postgres SQL and this is going to be localhost 5432 and the name of the database since we didn't Supply one is by default going to be postgres so we're going to set a username this was postgres and a password of password so let's go ahead and restart application and that's all there is to it um you know if we have one we're going to get in and like create some data and once you have some data then you can kind of validate that this is working correctly but for now just kind of take it out my word that we are connected to our postgres database and if we add some data in there we can go ahead and select it so again you can use this going forward if you have something like Docker installed and you want to run a real database for prototyping though this H2 database is really great I really like it so if you want to stick with me go ahead and just use that for now and move to your quote unquote real database later so I'm going to go ahead and refresh this stop the application and now we can move on to how do we populate this database now that we have a connection to our database we need a way to populate it we need to create some tables insert some data and there are a few ways that we can go about doing this we could use a ddl script so a schema file to go ahead and create our table structure and a SQL script to insert the various rows into our database so that's number one number two programmatically we could use some Java code to insert some data into our database and number three a database migration tool so as we are creating databases and making changes to them and then adding or deleting rows we can use something like Flyway which is a database migration tool to make the changes to a database scriptable so we can kind of commit those to git if you will so we're not going to look at the third one but I will talk about the ddl script and programmatically as we start to move throughout this tutorial here so let's talk about the first one which is that ddl script let me close all this up let's go back to Source main resources and application.properties so we have our database stuff in there now what I want to do is talk about two other properties that we're not going to change but I just want you to know that they are available so if you go into spring.sql there's an init mode so a nip mode by default when we're using an H2 database an embedded one in memory one is going to be set to always this means that it's going to look for a specific file in a specific place to go ahead and execute so that we have this schema that can get created or rows that can get inserted if you are not using H2 if you're using postgres and wanted to stay on that you would need to set this to always because if not if it's not an embedded database this is not going to act in this mode so let me keep that up for a second the other is spring dot SQL dot init schema locations so by default we are going to look in Source main resources for some a file called schema.sql if you wanted to change that you could so we can come in here and set a bunch of different places where this could get populated from so I just wanted to point those out we're not actually going to set those because by default we're using an embedded database and we're going to use the default location here and this is going to be schema.sql all right so I'm going to paste in some SQL I don't think we need to watch me type this out this is basically the structure of the database so we have an ID that's going to be an auto incrementing ID we have a title description status content type date created date updated URL the primary key is going to be the ID so that is our table structure so all that we've done there is added that schema.sql we've added the structure for our table if we go ahead and run our main application now we don't see anything else here in the console so we're not quite sure if anything really happened right we don't know did anything like take place so for that I'm going to go over to my application.properties once again and I'm going to set logging level for a specific logger so I'm going to say org Dot springframework.jdbc and we're going to set this to debug so we haven't really talked about logging yet I'm not sure how far we're going to go into this but this property is just setting this specific logger to this specific log level there are different levels of logging and the default is not to Output this debug info so you have to be specific on what you want to Output here so we're just changing it for everything inside the jdbc package so if we go ahead and run this again we're going to see a little bit more in here and it's going to tell us some things that happened so we see we have a jdbc connection and we can see that it executed a SQL script from we see that schema.sql zero returned as the update so I went ahead and created that table and we see the uh executed SQL script from file and five milliseconds so now if we go back to the browser and refresh our H2 console here test and log in now we see our table so our table was created there were no actual rows in here so let's go ahead and do that so back in our schema file I can just do an insert so I'm basically going to say insert into and we are going to insert into and we're going to have title description oops sorry content title description status uh content type and date created and then I'm not going to insert anything into date updated or URL so what we're going to insert into there is values and this is um okay the status is going to be uh idea the content type is going to be article and then the date created is going to be current timestamp so let's see if that works let's go ahead and refresh this or restart our application look in our console um we did do an insert so let's go back to this console and connect and now if we look at content select all we see our Row in here so cool so that is one way that we can go ahead and manipulate the data in the database that we are connected to in this case we need some schema to be run so if it does not exist I'm creating a new table called content again the H2 is going to get wiped in memory database is going to get wiped out every time so every time I start this application up this is getting run and then this is getting run and then yeah it's not just for schema we can go ahead and insert some rows here as well or we could just do this here and then programmatically we could insert some data if we wanted to we're going to have to come back to the programmatic stuff though because we don't have a way to talk to the database we've we've looked at how to connect to the database but how how can we use some code to insert to read to delete how can we use some code some Java code in our in our spring application to manipulate the database and that's what we'll take a look at now all right so when we're at start.spring.io and we include this jdbc API and this HD database that we ultimately ended up putting into our application by copying those dependencies in what we get are Springs jdbc template and named parameter jdb Sid template these classes Auto configured for us so they're automatically in that application context we talked about which means we can ask for them as dependencies in our own beans so what are the jdbc template and named parameter jdbc template so if we look at here and we go down we have GDC so we have our jdbc template here this is the central class in the jdbc core package it simplifies the use of jdbc and helps you to avoid common errors so this is our first level of abstraction on top of the apis that we may be used to working with in say Java to get information in and out of the database right if you look through here there are a ton of methods and a ton of overloaded methods meaning they have different parameters but the same name because there are a ton of different things you may want to do with the jdbc template but this is essentially one class that you can use to say query a database and get a list of things back and so this makes it much easier to do all of the things that we need to do with the database now there is a difference if you looked there's a named parameter and I named parameter jdbc template this is the same thing but when you're using Dynamic parameters using the jdbc template you use these placeholders these question marks as placeholders as this says instead of using question marks as placeholders you get to use named parameters so you could say instead of question mark you could say like colon name and then provide a name later on so you can use either of them the API is identical again it's just when it comes to dealing with parameters whether you want to use a question mark or a named parameter so that's what we're working with today that's the first level of abstraction let's talk about that and create a new class in here so in my repository we have this content collection we're going to replace this with a new Java class and let's call this content gdbc repository um and actually let's be specific jdbc template repository it's a long name but again we're not going to be using these I'm just kind of using these as examples to show off kind of the different levels of abstraction if you're gonna go with the jdbcm template I would just call this content repository and be done with it so what I wanted to talk about before is because we have those things on the class path we're automatically getting that jdbc template so we don't need to like figure out how to construct one it's already been created for us we could say private final jdbc template jdbc template and now IntelliJ is going to say oh you want to construct a parameter for this so we now know after going through this ourselves that this is dependency injection this template repository is dependent on the jdbc template to work I need this I can't do my job without this so spring is going to automatically Auto wire one in for us so now we have a jdbc template that we can use to talk to the database okay so now we need a bunch of methods to kind of deal with all the things that we would need to do for our crud operations of you know being able to get things from the database and persist them I'm going to paste some things in here because I don't want to make this entire this we could talk through this code for probably 30 to 40 minutes and I don't want to make it about that so I just want to talk about what you can do here so we have this method called get all content so I create a SQL string that says hey select star from that content table from the jdbc template now we can now use a method called query and we could say go ahead and query the SQL I just gave you and then we're going to change this to content jdbc repository dot map row and is that right list of objects list of content this is a list of content so now we can just say here's the query this query method takes a string and then a um a row mapper of type T and the row mapper is really just how do I translate that particular row or rows that I'm going to get back for each row how do I translate that into an object that you care about in this case a Content object so this row mapper will go through and do kind of the same thing that we saw on the Java side when we're getting that result set and saying getting string here's the title description status and we do all the things that we need to do with all of our properties so this is going to be pretty much the same um you know for creating for updating for deleting for getting this is and this is we gotta change this one to content jdbc template Repository but again if you like to write SQL and you want full control over the SQL that's being written this is a great start this is the abstraction on top of the built-in Java SQL stuff so now what you can do is if you wanted to use this and I think we're still getting some errors in here um what is this one status string content type string oh yeah it's probably because those are enums uh get time stamp um okay but I'll go through and fix this for the the final source code this is the jdbc template so now what you want to do is if you wanted to use this you can go in your controller and say instead of using that in memory Repository I would change this to something like private final content jdbc template repository and call this Repository right and now you just have to adjust these methods to kind of match what your jdbc template code looks like again not going to do that here we're going to focus in on the spring data stuff I just wanted to show this as an option that hey when you pick that jdbc API you get a you get an instance of this jdbc template that you can work with and now if you just want to start off by writing SQL and kind of controlling everything and not having some of the things go on behind the scenes that that you don't have control over or that you don't understand I guess is a better way to put it this is a great start again this is kind of level one abstraction so I'll leave this code in here I'll fix it up but what I want to do is take a look at Spring data okay so the jdbc template was really nice it's a nice abstraction but there's still a lot of SQL that we got to write there so we're going to talk about spring data spring data's mission is to provide a familiar and consistent spring-based programming model for data access while still retaining the special traits of the underlying data store here we are on spring.io if we head over to projects and we go to Spring data you will see that same thing that I just read to you right here under overview and it lists out a lot of the powerful features things like a powerful repository and custom object mapping abstractions we'll see that in action you get some awesome Dynamic query derivation from repository method names being able to have the implementation for the domain-based classes providing basic properties things like auditing custom repository code and more so again we get some out of the box SQL and no SQL support So if you're using MySQL postgres Oracle SQL Server Etc you're good if you're using redis or mongodb or patchy Cassandra those will work as well so spring data is broken down into different modules so we have these main modules like the commons this is kind of core to every underlying spring data module there are things like spring data jdbc and spring data jpa which are two of my favorite which we'll talk about one of these today um there are things for working with like mongodb and redist or spring data rest and then there are a whole bunch of ones provided from the community so if you're working with say couch base or Azure Cosmos DB or um gigabyte DB so all of these are Community modules that are are really great as well so then you really have to ask yourself what you know what type of data store are you working with what are you trying to do and then kind of go from there so I think by far the most popular one is spring data GPA jpa is the Java persistence API and underneath the Hood by default we're using hibernate in this so this is an orm or an object relational mapper and this is really great if you have worked with orms before if you're new to RMS there's a little bit of an overhead here you got to kind of learn how to map entities to each other how hibernate Works underneath the hood because that's important when you're trying to debug those types of issues so jpa is great but there's a little bit of overhead another one I really love is spring data jdbc you get a lot of the benefits of using spring data without the overhead of say an orm um so I'm a big fan of that so I think we're going to use this today but just know that jpa is a really big and popular one out there so go ahead and check that out if you want if you're over at Spring initializer and you go to added dependencies we already saw the jdbc API but if you type spring data you'll see all the different spring data modules that are available so things like spring data.jpa r2dbc if you're working with reactive relational databases and then my favorite spring data gdbc so we're going to go ahead and choose that and then you're going to pick a database which is H2 again we're not going to generate a project here I'm just going to go ahead and look at explore and we're in Gradle again and if we dive into here we can see that the only dependency we need here is this spring boot starter data jdbc so I'm going to head back to my IntelliJ I'm going to open up um mypom.xml I'm going to keep my H2 database I'm going to get rid of this and now just add this new one and refresh my Maven palm and now I should get everything that I need so I talked about spring data jdbc being my favorite one well why is that what is it so if we dive into that you can learn more about the kind of overview of this project if you want you can go into the learn documentation to check out the reference docs or the API docs the reference docs do a really good job of kind of giving you an overview of the things we're going to go through here today also like a couple other things we talked about I could probably spend an hour or two just on this alone so I'm not going to I'm going to try and keep this concise I do have another video on getting started with just spring data jdbc and a little bit more in depth into some of the things we're going to talk about today so spring data jdbc aims at being conceptually easy in order to achieve this it doesn't do a lot of the things that something like jpa does like caching lazy loading right behind or many other features that you get with jpa this makes spring data jdbc simple limited and opinionated all right and it all starts with this idea of an aggregate root so I'm not going to go into this again watch the other video go through the docs learn a little bit more about that um and we should be we should be okay so back in our application I want to take a look at our model because it kind of all starts with the model uh this domain this idea of domain driven design before we jump in here I want to talk about a couple terms too you'll hear different terms like dto entity and pojo and what are these and I want to give a big shout out to Greg Turnquist uh who I think to describe these very well in his new book learning spring boot 3. so if you haven't had a chance to check that out go check that out I'll leave a link in the description for that as well a dto is really a class whose purpose it is to transfer data usually from the server to the client or vice versa an end to the other hand on the other hand is a class whose purpose is to store and retrieve data from a data store a pojo is a class that doesn't extend any of the framework code and doesn't have any restrictions baked into it so if we're looking at this content record here this whole purpose of this content record now is going to be to store and retrieve data from our database so this is an entity and as such there are some things we kind of need to tell uh This Record about we need to like say hey this is a this is an entity these are some things you may want to know about um what is it what's the difference between an entity and a dto well in the case of uh this particular thing not a whole lot because the same properties that we're working with here in the entity are something that we would kind of deal with on the client server handshake right like when I create a new piece of content I want all these things if I wanted to create a dto that just accepted a title and then if it was you know blank content was the type of dto that it was you know I could maybe make the assumption that I could fill in the rest of the data for that request so I'd create a new dto based on this to um kind of a subset of the data that I'm worried about I hope that makes sense if it doesn't please let me know in the comments below and I'll be sure to go ahead and answer that for you so this is an entity we need to tell spring data jdbc that this ID right here is an ID that we are going to be working with and the way that we do that and we say at ID this comes from springformerdata Dot annotation.id and if we look at the sources not much here this is an identifier right so that's all we need to do there now we could do some other things we could come up here and Mark this with at table and we could say that we wanted to specify the table name so um we could say that the value is my what if we had like a prefix called TBL and the table name was content right we could do that if we wanted to I'm not going to you can also come in here and say um this is a column and inside of column you could say that the particular column is called Str title I don't know whatever you want to customize this column to be right so that is the column annotation those are really the only three I'm working with here right now in this particular project but right now all I need is this ID saying this is something you're going to manage and I want you to go ahead and manage that manage this for me and this is the identifier of this so with that in place we can create some repositories now we've created these repositories before but we've also like these these were very um these were classes that we had to implement we had to make all of the code to create a collection of content and add to them and save and update and delete and list and find one we had to do that for all of those in this case we're not going to have to do that anymore thanks to Spring data so what I'm going to do is come in here I'm going to create a new Java class I'm going to call this one just content Repository but in this case it's going to be an interface say what an interface how are we going to get some code out of that well the way that we're going to do that is we're going to extend one of the spring data repositories so there are a few there's one called the Repository and if we look at repository there's actually nothing in here so this just says hey this is a repository then we can go ahead and add our own methods in here there is one called a crud repository this gives us a lot of the crud functionality out of the box in the latest version of spring data 2022 there's also a list cred repository and this is the one we're going to use once you have a list cred repository you need to give it a type what type am I managing this is content what is this type's ID that is an integer right so once you have this in place that's it that's all the code you need to write if we look at this list credit Repository it had it has methods for returning lists because the credit repository returns iterables and we're not used to working with iterables I want to work with a list so when I call find all give me a list of content right but the credit repository contains the rest of the operations for doing things like saving deleting delete by D find ID Etc so just by extending this what happens is we don't and also we don't add the at repository marker here because this is an interface and what happens is at runtime spring will see that you've extended one of the base repositories and basically turn this into an implementation so now you have an actual concrete class that you're working with called the content repository that has all of these methods in it right so how can we use this so let's go back to our content controller and instead of this content collection repository let's replace this with just the content repository and we'll keep this called Repository now we're going to have to change this up a little let's say content Repository and then that looks good this looks okay this looks okay this probably is gonna work and the only change we may have here is deletes by ID okay so now I did this because I specifically wanted my collection repository to look similar to this so that we can just flip over but again we have not written any methods in this content Repository so when you start you could just say hey repository find all that's going to get all of the methods right so this is is pretty fairly simple to go through and get your crud operations up running now let's see if this actually works let's restart our application and I'm going to go over to now we don't have any we're not going to have any um we're not going to have any content in there because remember when we added one we were doing this here in this content collection repository so let's back up a second let's go to our application I want to talk about programmatically inserting data oh no we should actually have one right we do have this schema it does have one let's scratch that and go over to our HTTP test and see if we can list out content and we do so that is in the database that's what we're born from the database and most of our content controller should work I do want to talk about programmatically inserting data now though let's go ahead and take this out actually I'll leave it in but just comment out in case you want to use it but now if we were to rerun this we'd have no rows in the database so how can we do that well we can come in here into our main application class or really any configuration class let's talk about this let's um let's do it the long way so it makes sense and then we'll do it the shorthand way so I'm going to create a new and actually this really isn't a config but that's okay let's create a new Java class and we'll call this a data loader right so there is a interface in Spring called the command line Runner and if we look at the command line Runner this is an interface used to indicate that a bean should be run when it's contained within a spring application you can have multiple command line Runners the important part to note is that this will run after dependency injection happens as the application has started up so this is a really good spot to do some type of you know bootstrapping or data loading so there's a single method in there so we're going to implement that and if you're paying attention there's a single abstract method also this is marked with that functional interface so we'll talk about that in a second I could create a class and hello and wave so that's all I'm going to do here I'm going to run my application rerun my application and actually this isn't going to work yet so this isn't going to work because we haven't marked this with ADD controller so spring doesn't know that this is a class that it should care about once you mark it with that controller now it's going to pick this up and then run the run method and there we go we see our hello outputted after everything is kind of warmed up started and ready to go so this is one way to do it um again I'll leave this in here I'll just kind of take that off so it won't get run another way to do it is it's a functional interface so it is a target for a Lambda so what we could do remember if you want to create something so instead of using at component on a class if you want to create an instance of a class using a method you can mark it with ADD Bean so I'm going to mark this as at Bean it's going to return a command line Runner the name of this method is called command line Runner and this is going to return a Lambda expression now this particular run method takes a vargs of string of strings called args so I can say return args and here's our Lambda expression or in this case I don't even need that if I just wanted to say hello Dan right so let's go ahead and run that and there's hello Dan so this is a great place to do some bootstrapping is what I am trying to get to so we can go ahead and insert some data into the database now what we need to insert some data into the database is our repository we need this content repository because this has all the methods to be able to do things like save a new piece of content so how can we get this here in our command line Runner well this is just an argument right so we can say content repository we'll call this repository and because spring is managing this as a kind of instance in the application context it will see that when we create an instance of this thing this is dependent on this and it will wire this in for us so now what we can do is let's go grab this code so we don't have to kind of replicate that we can say content is equal to that let's just write something else so we know it's something different I wrote a new thing on chat GPT earlier say all about chat T and maybe this was a video so now we can do is we can use that repository and we can save that entity that content and we could save it to the database so the only difference here is that we are not going to supply the ID so we are not supplying that ID this is actually going to be null right so with that let's go ahead and try and rerun our application and there we go so if we run back to this and say list all of our content we can see that we get that new piece of content so now we have the ability to programmatically insert data using one of the uh really nice interfaces that spring provides us with the command line Runner so again just a really nice way to kind of programmatically insert some data all right so there's one more thing I want to show you when it comes to data and then we'll kind of move on from this section but what we've looked at so far with the content repository is we get all these really great methods out of the box we get these list methods we get all these crud methods you can see in here we get a whole bunch of stuff out of the box which is great I don't like writing boilerplate dumb boring crud SQL so awesome don't have to do that anymore but what if we have something that we need specific so let's say that we had a request from the client hey I want you to write a method that will return to me a all of the pieces of content that contain some keyword in their title so find by title right and it's going to take in a keyword so how are we going to do this so first off this is going to be a git mapping right so we're going to respond to a get request so it's going to be at at sleep API slash content slash maybe filter and then whatever the keyword is so that's the keyword we're going to accept that as the path variable so how can we add something to the repository that will satisfy this requirement so if we go back to the content repository any methods that we add in here we can go ahead well let's back up there are kind of two ways that we can um add some store specific queries we could do it uh from the query name so we can do it by query derivation which is off the method name itself or about using a manually defined query so let's talk about query derivation first let's say that I wanted to get a list of content so what I want to do is I want to get all of the content by some column by some kind of criteria right I'm going to start typing here and as I start typing you can see that I get find all by find first by find content by find by find distinct by all of these really great query derivation helpers so what we're going to do is we're going to type out a query name here and then when this thing gets implemented at runtime it will turn what you're looking for into an actual query that will get sent to the database and we can get what we need back I want to find all by title and now we can start to like figure out what do we want to do with that title we could say like the title is this or contains that or starts with I want to say where find all where the title contains and then you can start to chain this so if I wanted to find all by title contains and date created was happened this year and the status was not an idea maybe it was published right you can start to chain all of these finders together I'm going to keep this simple and just say find all by title that contains whatever this keyword is so again this is not an actual implementation this is just an abstract method here we're defining the signature it will get turned into the bits that needs to be turned into for us to actually work at runtime so let's go ahead and go back to our content controller and say return repository dot find all by title contains and then our keyword so let's see if that works let's go to run our application and let's go to the browser and if we go to content and just list out all the content we have one in here we have a keyword of GPT so let's say filter by keyword let's say GPT and you can see that's found now let's find one by one that is not found so like data and as you can see we get an empty collection so this is a really great way to quickly add some new queries to your Repository now this is one way okay so I want to get a list of content and I will say that I want to list by status and so we'll take in an argument of status and we'll just call this status and instead of doing the query derivation and having that implemented for us I'm going to use the add query annotation because I'm on Java 17 I can now use this nice triple quotes text blocks and I'm going to say select select star from content where and then if we go back to our schema I just want to remember this where status so to that in a second swear status is equal to and then we need a way to say um the status that is being passed in so we can use a name parameter here and we say where status is equal to status and then we go ahead and use the app param annotation to bind to that so now we're actually writing out our own query right so let's go back to the content controller and let's write a new method we'll call this a git mapping I will say filter by status and then the status and then we will get a list of content pick we'll say find by status and then we'll use a path variable to pull out that status right and then what I want to do is use the repository to list by status and pass in the status right okay so we're passing that um let's go ahead and run this and see if that works so again I have just that one in the database it is a status of idea so I'm going to say filter by status and then idea and we see that we get that another status is in our completed and we see that we don't get any so just a couple of different ways you can start to write your own custom queries here in a repository you can use Query derivation there is a whole lot to learn about queer derivation and the different ways that you can construct these queries so check out the documentation for that and then you can use the at query annotation and you can write your own queries here if you want a little bit more control over the SQL that's getting sent to the database all right you've learned a lot so far I know this is a little bit overwhelming there's a lot to learn here but you've learned a lot and I'm very proud of you I'm glad you're sticking with me through this but the ultimate goal is not to have an application that we can run on our local laptop right we want to get this out to the great world of production we want to be able to show our moms and friends and say hey look at this thing that I built even though it's just returning Json so what we're going to do in this section is get prepared for the promised land of production and we're going to do that by covering a few more fundamental concepts so what are we waiting for let's do it spring boot lets you externalize your configuration so that you can work with the same application code in different environments you can use a variety of external configuration sources including Java properties files yaml files environment variables and command line arguments so we'll look at a list of all the property sources here in a second but I just want to talk through this so we've already kind of seen this in action if you open up Source I mean resources and application.properties you've seen that we've got a configured some things in here already right like we configured the H2 console the data source name and the logging level so this is where we can configure all the properties in our application uh these are all the things that are built into whatever components we're kind of using in our application so for web example there's a bunch of configuration that you can do to configure how the web application acts remember this is you know spring is configuring some sensible defaults for you but always giving you the ability to override those defaults if you need to so one of those that we've already seen is the port the default Port that's that spring boot starts on and that is a setting so if you go in here to server.port you can see that its default is 8080 we can always change that so if we want to change it to 8085 let's do that let's rerun our application and if we look in the console down here we'll see that now we have started on Port 8085 so now what I want to do is go over to the browser and if you look in the spring boot docs there is a section for externalized configuration and this is kind of the stuff that we just went through uh we're going to get into this properties can property values can be injected directly into your classes by using the at Value annotation so we'll talk about that or we can use structured objects using the at configuration properties annotation which we'll talk through as well but this is what I want you to pay attention to here spring boot uses a very particular property Source order that is designed to allow sensible overriding of values later properties in this list can override the values defined in earlier ones so this is something I never remember I always come back to the docs because there's so many different types of property sources one can override the other and so if you ever have a question always come back to the documents and take a look but what this is saying is anything later will override the one that is earlier so if we had a um config data such as application.properties files and then we go ahead and set an operating system environment variable that is going to override our application.properties and this becomes very important when you want to move to different environments so I may not want to um you know expose a secret key in a production environment that's where I can expose the secret key as maybe an environment variable in my production environment so there are a bunch of different ways again the application up properties whether it's dot Properties or dot yaml those those are are used in a specific order and then we also have variants of that we'll talk about this in a minute when we talk about profiles but you can have different property files for different profiles so we'll talk about that so just understand that there's a there's a pecking order to this right so here's our properties file we've set 8085. so what I'm going to do is just doing a little experiment here and go into um my run and go to edit configurations so we're going to go to edit configurations and in my application I am going to set a environment variable so let's say environment variable here and I'm going to set server dot Port equal to 8081 so this is different than the default 8080 this is different than the 8085 that is in our properties file so if we go ahead and run this now we can see that we are started on 80 81 because again that property Source overrides the dot properties file and therefore that takes precedent so that's just a little bit on on configuration and different property sources uh these again are important to note is you're moving through environments so I'm going to go ahead and remove this and we're going to talk about injecting values into your code using add value and configuration properties all right so to demonstrate this I'm going to create a new controller we're going to call this our home controller so let's say home controller this is a class we're going to mark this as a rest controller and we're going to have a single method in here that is going to return a string for now we'll call this home we'll return hello world and actually let's just return hello hand wave because any chance we get to use an emoji in some real code let's take it so this is going to be a git mapping for that so our root endpoint that should call This And if we go ahead and rerun our application and head back to the browser and we get localhost 8080 and we get our nice hello hand wave Emoji so so far so good now what if we wanted to get a value from the application.properties into this controller um well first off we might set up a variable here we can call this string we can call this welcome message and then we might want to return that here instead of this hard-coded Hello message so we'll say welcome message and great if we do this we have a null value right now so we're not going to display anything so what we can do is we can use the at Value annotation to say let's go ahead and grab something from that application.properties or really any configuration Source right now that we understand kind of property sources and how they're overwritten so we're going to use something called spell spring expression language to get that value so we're gonna we can name this value whatever we want so I'm going to start this with CC for Content calendar and we're going to say welcome message now we have not defined this yet so what do you think is going to happen if we try to run this application uh you're right it's going to blow up could not resolve placeholder CC welcome message so we could go to find that but we also want to be able to handle this case where maybe somebody didn't Define this in their app so we can actually set a default uh value here so I'm going to say default welcome message and now if we go ahead and restart this it doesn't blow up and if you went over here and refresh this we get our default welcome message so so far so good now what if I do want to Define this if I go back to application.properties and I say CC dot welcome oops welcome message is equal to um hello what are we um let's say welcome to Dan's content calendar okay so let's go ahead and use that and refresh and there is our new message so so far so good but what happens if we wanted to add some more data that we wanted to display so let's come back here and what if we had a an about like what is this what is this application all about or what is this API all about so maybe we had a string about we could do something similar here we could say um CC dot about and then we can pull that in how do we display two things here well at this point we're not displaying a string anymore maybe we want to display some Json data so what I could say is I'm going to display a map of string of string okay that's what I'm going to return so how do I do that I'm going to return map dot of and I'll say my first key is welcome message and that's welcome message and then my second key is about and that is about so that looks good we need an about in here so let's go ahead and do this okay so let's go ahead and refresh and if I go back over here now I'm getting my Json my welcome message and my about okay so this works but there's a couple problems with this one we you notice that when we start typing this here we don't really get any assistance CC dot why can't I see what those properties are I want I want to be able to help whatever user is using my feature here and to be able to get some uh intellisense here two if we come back to this we can kind of plug whatever we want in here so a welcome message I'm going to say 99 and what is this about I'm going to say that this is a list of things right um and it doesn't really care so it's going to or go ahead and run this and it's gonna go ahead and refresh and okay we have those things it didn't really do any kind of type checking right like uh these are strings I would want the user to input some strings so how can we get around this so let's go ahead and delete this let's go in here and um delete this we'll just say um let's say string for now and I'm going to remove these so anytime you have a single value this is great but when I start having a collection of values that are kind of related to each other and you maybe want some types around it this is a really good opportunity to use configuration properties so I'm going to go into config here I'm going to create a new Java class and I'm going to call this content calendar properties and this is just going to be a actually this is not going to be a class which probably make this a record just to simplify things let's say record and then the components of this record are simply going to be that welcome message string and the about so all we're going to do to turn this into some kind of properties that we can use is we're going to mark this with at configuration properties and we're going to give it a prefix so what is the prefix that someone types in for each of these so cc.welcome message CC dot about this is going to pop up in IntelliJ right away saying hey this spring boot configuration annotation processor is not configured what are you talking about so if you look at the documentation it'll tell you hey generating your own metadata used by The annotation processor all you need to do is include this dependency whether you're using Maven or Gradle so to do that I'm going to come back to my palm.xml I'm going to include that dependency reload Maven and then this should be okay but we have one more um thing that we need to worry about here and that is in our application we need to say we need to enable that so we need to say uh actually I'll put it up here we just need to say enable configuration properties which one which classes do you want to enable that for well I only have one so I'm going to point to it content calendar properties dot class okay so at this point we should be getting no more errors everything looks good now once you do this you got to run a build so I'm going to run a build let's go ahead and build our project and we're going to get this target folder and if we look under classes and under meta if we now see this spring configuration metadata and as you'll see in here we have some metadata for the CC so we have this is the kind of uh type where it's coming from these are the two properties the welcome message and the about so once this file is in place now I know if I go into my application.properties and I type CC I'm going to get some more help about this so you could see that this is a string this is a string so now if I go ahead and type and now I can say this is Dan's content or actually we said welcome to Dan's content calendar and then we say CC dot about this is a collection of my content okay so now we have that in place now we can come back over to the home controller and this is just a bean right now the spring application context is managing for this so as you can guess we are going to say private final content calendar properties we'll call this properties and IntelliJ is going to say Hey you probably want to construct our parameter for that I do I do we could change the type of this because in fact at home we just want to kind of send this info back so we can say that this is a configuration properties and let's go ahead and oops return properties right all right so now if we go ahead and restart application okay everything's working still let's go back to localhost 8080 and there we go we have our welcome message and our about but now we have them nicely packaged in this content calendared properties record and again if we think of other things that we want to add to this later we can just add that here and everything is going to be set up for us so that's a little bit about injecting values into your beans using both at Value annotation and the configuration properties all right so we've talked about configuration I want to move on to profiles spring profiles provide a way to segregate parts of your application configuration and make it available only in certain environments this is going to be really important again as we're moving to different environments like production so any component configuration or configuration properties can be marked with app profile to limit when it's loaded so let's take a look at an example of this and and to do so I want to first start our application and talk about something we we've may have seen in our console but haven't really understood what it is so here we get this nice ASCII art this first line up here says we are using Java 17. the second line says no active profile set falling back to one default profile default so by default if you don't set an active profile the active profile is something called default if you want to set an active profile you can come in here and say spring.profiles.active and then if you saw it real quick in the hint there you can provide a single active profile or a list of them so I can either say Dev or local or maybe this is local and Dev we're just going to start with say Dev so now if we restart this that is the active profile if we look up here we can see that our active profile is now Dev so we have this app profile annotation let's look at an example of where we might use this so I have this data loader class and again we made a mistake on this earlier we use that controller we should have used at component I just got excited so we have ADD component here and if we run this it will go ahead and run because we are telling it to run and there's our hello output but what if we only wanted this to run in I don't know say production right we didn't want let's say we didn't did not want this to run in Dev what we could do is add an app profile and we could say what profile we want this to run in we could do we could say hey I want this to run in production or I don't want this to run in Dev so you could do like matches or negative matches or against a list you can do a whole bunch of things when you're kind of trying to figure out what profile this should be used for so here I'm saying don't run this in Dev so now if I run this again we should not see this in the console and we don't so that's cool that allows us to kind of limit where this profile is being shown so that's one example I'm going to remove that and let's take this off so this doesn't get run anymore so we're still using profile as Dev the next thing I want to look at is profile specific configuration so we have this application.properties and this is going to be loaded no matter what environment we are in but what if we had environment or what if we had different settings based on the environment we're in this is very possible this is something that will happen a lot right so I'm going to create a new file here and I'm going to say application Dash and now you can use whatever profile you're going to be in so let's say we had a profile called production so I'm going to say application dash production dot properties now these will always get loaded into whatever environment you're in but then the profile specific properties will only get loaded when you are in that particular profile so let's take these two properties that we just looked at before and set these in the production and let's just say this is production and we'll say production about message all right so now we're still in Dev if we go ahead and run this we should be able to go to localhost 8080 and see our original ones so let's refresh and there we go but now let's go ahead and change this active profile and again we could do this here if we wanted to spring.profiles.active or let's override that in an environment variable because we know how these things work now so spring dot profiles DOT active is going to be equal to production so let's hit apply okay rerun this and if we go back over here we refresh this we see that we are now picking up properties from our production configuration so this is really cool I like the slot profiles allow us to do some some really cool things one of which I could see an example of you know that I've done before is we have this data source for for our local development right maybe when we go to production we are going to use that postgres that real database right so we could come into our application.production properties and Define our postgres jdbc Connection in here and so that'll only get loaded when we go to production and in fact that is what we are going to do today as we move to production I'm not going to do that yet because we're gonna have to set that production database up in that production environment get those properties and then we'll come back to here and load this so that is a little bit about properties um I also just want to point out that we've talked a lot about dot properties files they are interchangeable with something called yaml files so you can go ahead and create yaml files in here as well so let's say application.yaml and some people like yaml better because if you have like lots of different so so like spring.datasource.name.username.password right this can be a little bit more verbose in a properties file in a yaml file you can see we can start we can type spring.datasource.username and this could be Dan and now we can say password oops password and this could be password and then we can do uh driver class name whatever so you can see that we get a little bit cleaner we have some some kind of cleaner uh structure to our properties and a little bit less verbose because we're we're not repeating spring.data Source every single time so you could use yaml you could use properties if you use them both they'll actually get merged and there is an order to like which one wins but I just wanted to point that out in case you do see yaml files uh they are kind of the same thing as top properties files when we're talking about creating our configuring our application all right so we're getting ready to push our application into production I want to talk a little bit more about production ready features so spring boot includes a number of additional features to help you Monitor and manage your application when you push it to production it's not just enough to push your application into production cross your fingers and hope everything's working you don't want to rely on your users telling you something's wrong you need to be able to monitor this and see what's going on so you can choose to manage and monitor your application using HTTP endpoints or with jmx if you want you can auditing health and metrics Gathering that can also be automatically applied in your application so what we want to First do is enable these production ready features by using the spring boot actuator so like with a lot of things in Spring boot there is a spring boot starter actuator that we want to go ahead and add to our application so if we go ahead and do this I'm going to copy this dependency I'm going to go back to my palm and in here I'm going to add this dependency and let's tell Maven to reload and we should be okay so now when I go back to my application and start everything looks like it's working okay all right so the first uh production feature really the one that we're going to talk about today is endpoints so actuator endpoints let you Monitor and interact with your application spring boot includes a number of built-in endpoints and you can always Define your own for example the health endpoint provides basic health application information here's the important part you can enable or disable each individual endpoint or you could expose you know a whole bunch of them or all of them over HTTP HTTP or jmx the way that you get to them you most applications choose to expose over HTTP where the ID of the endpoint starts with Slash actuator and then the name of the endpoint and here's a list of all the different endpoints that you get out of the box and a description of what it gets so we know what beans are right there's actually an endpoint that displays a complete list of the spring beans in your application so this is really nice to be able to see what is uh happening in your live application as it's being used in production what are all the beans that are available there so let's go ahead and take a look at making these available so we can enable one we can enable all of them I'm going to enable all of them I'm going to say management dot endpoints dot web dot exposure exposure dot include and I want to include star I want to include all of them I also want to set one other property I'm going to say manage mint Dot and point so and point DOT health dot show details I'm just going to turn this on to always so I want to go ahead and restart this application and let's go back to the browser I'm going to go to localhost 8080 and actuator and now you can see I get a whole bunch of endpoints in here so we can see that we are basically given all the endpoints so like beans caches health and if we go ahead and dive into here we could see beans these are all the beans in the application context so we know that we created that content um was it content calendar properties so if we search for that we should see that here it is there's no aliases the scope is Singleton here's the type here's the dependencies so pretty cool stuff you can kind of see all of the different beans that are in your application another one that I really like is the uh config props so I'm going to config props and see uh where everything is and more importantly where it's come coming from so here's an example of that properties that about and that welcome message and we could see where it's coming from so if we look at the input it's coming from application.properties so if we had a bunch of different property sources and we weren't quite sure which one was overriding the other one hey this is going to tell us exactly where that particular configuration is coming from so I really like that as well we can go into the health and we get some details about this we can see that the status is up here's the components hey we do have a DB in this case it's an H2 that is up and ready to go what is our disk space and we can even configure this to show a little bit more information say in the info we can get some jvm info the operating system info Etc there's an environment that shows us all the environments that is happening we can get a list of loggers and these loggers are all the bloggers that are currently configured in our application and you can even make post requests to this if you're if it's enabled to change the logging level so if I wanted to change a logging level at runtime and I had the actuator enabled I could do that metrics are very important as we start to try to figure out what is going on in our system so if I want to see um let's see from a jvm standpoint let's just figure out what is the max memory of our jvm so I could say I can grab this key and then say from metrics what is this and here's some information about that particular metrics so just with the actuator on we are now collecting a bunch of metrics in our application let's take a look at some mappings so we have some mappings in our application these are all the mappings that are set up for our application so again just the just wanted to show the actuator uh it's important you get a lot of information out of it and this is the start you need to include this to do some other things so there's a big theme in Spring boot 3 around observability so if we include this we can now do some things uh with metrics so observability really is kind of uh the idea of logging metrics and distributed tracing just by including that actuator in Spring boot 3 and setting a couple properties we can start to collect a lot of metrics about what's going on in our application so that's pretty cool as well so that is the actuator again just by including this uh single little dependency starter in here so we have this spring boot starter actuator and then defining which uh endpoints we want to expose or how we want to expose them we get some more information there so that is the spring boot actuator all right and I want to just do one more thing as we wrap this up and get ready to move to production and I want to get rid of this Bean here but I do need a way to kind of load some sample data so that we have something to work with right uh whoops did I delete too much there nope let's go here and so I'm going to get rid of that and then we're going to revisit this data loader here which we're going to use to load some sample data so let's talk about that what I first want to do is you can grab this from the GitHub repository I'm going to create a data directory here under Source main resources and I'm going to create something called content dot Json and this is just a Json file of data it has three articles and three videos that I've worked on and this will allow us to load some data into the application I thought this would be a really fun little exercise just to say hey I have some Json data how could I use this command line Runner and load that data right so we're going to need a couple things we're going to need that content repository to persist it off to the database so I'm going to say Repository and we're going to need that through a Constructor injection I'm also going to need an object mapper so an object mapper is something that comes from Jackson Jackson is let's make this final Jackson is the way that we can kind of uh create uh objects out of Json and deserialize them to you know Json from an object so that is the just this has already been created in the application context so we're just asking for that instance now that we have the object mapper and the repository we have everything we need so let's go ahead and say in here I want to go ahead and read from that content.json this is going to be uh fairly easy to do so I want to do a try with resources because I'm going to read from something and I want to make sure that it's closed so what I'm reading from is an input stream so I'm going to say input stream is equal to and then I'm going to use something here called a type reference and then we're going to get a resource as a stream so what does get Resource as a stream do foreign it says Hey I want to find a resource with the given name so that seems pretty uh pretty useful here so what I'm going to do is say data content.json all right so now we are in here and this is not liking us try to resolve um I don't know why it's not finding type reference from we want it from core.type yes so okay resolved so now once we have that I can use the repository to save all so I'm going to save a bunch a list here and we're going to use that object mapper to read the values so it's basically reading the Json and for each one of those it's creating a type out of it what type is it for this one so actually we need to read the input stream what type is it in this case we're going to use this type reference to get a list of content so content and hmm that looks good let's go ahead and try that so I'm going to rerun this application again in application we've taken that out so the only data loading should come from there we should have six values looks like no errors let's go back to our localhost 8080 and go to our H2 console we'll go ahead and connect we'll go ahead and run select star from content and there's our six values so cool so we were able to just provide a little more kind of dummy data for this application that we're gonna spin up that way we can go ahead and make sure that this gets loaded when we move to production and we have some starting data all right in the repo for this particular project that we're working on there's a docs folder I'm going to include this production markdown folder because there's a lot of good info in here and I thought we'd just walk through this we're going to talk about how to build an artifact for production and then we're actually going to go in and publish this to a host so that we could see it live and out on the web so production it's the greatest place on the web we should all want to go there but it can be a very scary place so I picture I always use this picture because I always picture my friend Josh and my colleague Josh long as Buzz Lightyear saying production it's the greatest place on Earth so here's Josh just telling us reminding us that we need to get to production get there as soon and as often as possible so there are a few ways that you can build an artifact that is ready to go to production we're going to talk through just kind of really quickly uh all three of these and I'll actually build one or two of them but I wanted to leave this information here for you if you want to kind of explore all of your options so the first is an Uber jar so the spring boot loader modules let's spring boot support executable jar and War files we're using the maven plugins we can get this execute roll jar automatically generated to do so you can create an executable jar running the following command so remember you don't have to have Maven installed because we have this Maven wrapper so this means that we can go down to terminal and if we see the command here we can say Maven wrapper whoops and we want to type clean and package so clean deletes the target folder package will invoke maven's package phase which will cause the verify compile and test phases to be invoked in the correct order so let's go ahead and run that and you see it runs some tests it's doing some things build success so you see it built a jar in the Target folder called content calendar and then the version as defined in the Palms if we look under Target and we see this content calendar snapshot.jar so to run that you can use Java so now this is a executable jar that will run wherever there's a jvm so we could say Java Dash jar Target content calendar and if we go ahead and run that it starts up our application as normal cool so just seeing that as we're preparing to go to production we should probably fix one thing we have some logging in there that we probably don't want right so let's say application.properties let's just go ahead and remove that okay so that is an Uber jar this is a really what I love about the Uber driver is going to be run anywhere there's jvm so as we're moving to production a lot of hosts will be able to just take that jar and use it so that's really great so the other thing is um okay this is great in a neck in an environment where there is a jvm but what about an environment where there is no jdk right um this is where containers and specifically Docker containers in this instance can help us out you've already seen some examples of running things like Docker compose to generate uh that data that run that postgres database locally but what you can do is you can create a production version of your spring boot application using Docker files or by using Cloud native build packs so I would encourage you to go into the documentation read a little bit more about this uh we'll talk about some resources to kind of follow up this crash course with one of them is going to be spring office hours DeSean and I always talk you know one of our sayings is friends don't let friends write Docker files and you really shouldn't be writing these Docker files from scratch and that's why we're going to use this Cloud native build pack so to do so I want to make sure Docker is running let's make sure Docker is running on my machine I believe it is all right and we're started let's go back here and now what we can do is go back to the terminal let's clear this out and now we can run um let's get rid of that Maven wrapper spring boots and build image so if we run build image this is going to build us a container so we're gonna have a container file or a container that we can now run so this is really great so as we run this uh it's building this oci compatible image and it does some really interesting things in this image so we're using Poquito paquero build packs underneath the hood again read more about it in the documentation but it does this really nice way of building this out using different layers and again this is not something you want to build by yourself leave this up to the people who are doing some amazing things here with containers I don't do this every day so I don't want to have to manage this that's why I kind of lean on the cloud native build packs to create this for me so once this is done all we're going to do is say a Docker image ls-a we want to see that we have that particular Docker file created so we see saving Docker IO Library content calendar snapshot and the build was a success so if we say Docker image LS oops LS a we could see a bunch in there one of which is our did I miss it content calendar snapshot so now what I should be able to do is use Docker and run it we need to map port 8080 to 8080. uh that we're going to cause content calendar .1 dot or 0.0.1 snapshot snapshot Dan and as you can see it's starting up our spring boot application so this is really great for any host that doesn't have a jvm environment anywhere that can run a container image boom you're you're ready to go you can just pass this container to them and you are ready to go so I'm going to stop that that's our container image and then there's native images if you're using spring boot 3 there is a way to compile down to a native image so this is this works really great for different workloads uh some of the things that kind of stand out for me are like serverless functions or even serverless environments um you know building your own like clis I did a video lately on my Channel about building a CLI using um actually I've used one using Java and then built one using spring shell so then you could turn those types of applications into a native image and it just runs on your fast and the benefit to a native image is you get that smaller memory footprint and faster startup so that's really cool so we're not going to run that here this takes a little while to run so I'm not going to do that here but that's an option so all of this is leading up to how can I get my application into production so I've compiled a little bit of a list here here are some places that you can host your spring applications there are more but this is just a short list of of places that I really enjoy and actually on my channel I'm doing a bunch of uh different videos on deploying to these different environments we've done I think three of these so far and I'll continue to work on these uh throughout the year so there are some resources for this again we talk about this a lot on Spring Office hours and here are the three that I've already done for Azure spring apps Heroku and Railway and so what we're going to do today is focus on Railway and I like Railway because there's a free option so if you don't want to spend any money and you just want to kind of see how you can get this particular application into production I think Railway is a great way to do that so what are we doing let's take what we've learned today and get this application into production all right so before we head over to railway I want to talk a little bit about our project so we've been using the H2 database in our project and again this is great for prototyping and developing and the things that we were doing as we're getting ready to go to production we want to think about this because currently we're using H2 in our development and then we would be using something like postgres in production and typically you don't want to do this right you want to stay consistent with whatever database you are using in production should be in your Dev environment should be in your test environment if you haven't had a chance to check out something like test containers that will allow you to spin up a postgres container in your tests so that's really great so I think what we should do is make a change here and make sure that we're using postgres in our local environment and to do so we need to do a couple things first I'm going to go over to my palm I'm going to get rid of my H2 database driver and I'm going to include the postgres driver so I'm going to go ahead and grab that off screen it will look something like this we did this earlier so it should look pretty familiar so with that in place now in my application.properties I need to set some postgres properties right now what is the what are the properties so I have a Docker compose file that we used earlier so you will need Docker to do this locally if you haven't already set that up if not you can go ahead and set up postgres as a local instance I'm just not going to walk through that here take a little bit too much time so if you have a local postgres instance running no need for Doctor you can just input your parameters so I have this running on Port 5432 postgres is the username password is the password so spring.datasource.url is equal to jdbc posts SQL localhost 5432 and then the database name is postgres we need a username of postgres and a password of password and then we're also going to need that SQL init mode to be always cool so let's uh with that in place let's see if we can run this application and we have an error uh oh yeah so syntax near or at Auto increment so again this is kind of why you want to use the same database in Dev and production and test right the schema file is using something kind of specific to H2 right that's an auto increment in the world of postgres we're just going to say that this is a Serial and we'll say this is primary key so now with that in place let's go ahead and try and run our application and air syntax at our near descript oh I wonder if that is a keyword I think that is um so let's make a quick change real quick so I'm going to go over to content and I'm going to say that this column name should be description so now we don't have to change any of our code we're just changing where that gets stored so I'm going to change this to description and let's go ahead and rerun that and cool no errors so I think I think we're good there so again just being consistent there will help us kind of catch some of those errors on a local machine instead of as we deploy them to production so that now I think we can go over to railway you can find Railway at railway.app if you want to go over to pricing you can check out what pricing there is um I think I'm logged in that's why it's not allowing me to see the pricing let's go here so if you go to pricing trial you get a pretty generous free tier 512 megahertz of ram a gigabyte on disk five dollars or 500 hours of usage so again this is really great for your kind of side projects or something you want to just test out uh really awesome to use now there's a developer uh tier as well ditch the limit still free under five dollars so if you stay under free it's still five dollars but none of the limits as soon as you exceed these limits um you you know you'll have to pay a little bit more so pretty nice though and you get a lot if you head to like a team for twenty dollars a seat so I'm a big fan of Railway I'm going to go ahead and log in and what we need to do is create a new project so when you create a new project you can come in here and you can say you could deploy a project from GitHub from a template they have a ton of templates you can provision a database what I want to do is actually create an empty project because I'm going to create a couple services in here one is going to be that postgres database one is going to be my project from GitHub so let's create a new service I'm going to create a database I'm going to add postgres and it's going to come in here and provision it and once it's ready I can go in here so from the data tab I can go ahead and create some tables if I want to again we're going to kind of let um spring boot do that for us you can come in here query tables which is really nice there's some connection info so if you wanted to connect straight from say a terminal you could here's the URL connection we have logs in here these are variables so these are the different variables that we're going to use and I think this one yeah I'm going to go ahead and copy this one because we'll use this you have metrics and then settings for your database so once this is up now we can go ahead and create a our application so I'm going to go up here and say new from our GitHub repo if you don't see this in here you need to configure your GitHub app to allow either access to this specific GitHub repo or to all of your repos IO I only give it access to specific repos so it has access to these two I'm going to go ahead and select this one and then as this goes it's going to start trying to build but we don't want it to build yet we can just abort this if we want oh no we'll just leave it it's it's probably gonna not work so we need to set some environment variables but we need to figure out how we're going to connect to this postgres database that we just created before so I'm going to head back over and we're going to go to Source main resources we're going to create a new file we're going to call this application dash production dot properties right so in here I'm going to copy this thing that I copied from there and I want to copy these because these are going to be specific to production so what we need is we need the host so the host is PG host um so let's go ahead and do this PG host the port is going to be PG port and the database is going to be PG data base cool the username is going to be PG user and the password is going to be PG password so the reason we're doing this is you could go in there and get the actual values for this but this isn't something you want to stick in a plain text file and commit to git because then somebody can grab your PG username and your PG password and use your database so this is why we're using these property placeholders that will get replaced by an environment variable later so with that in place before I commit this I'm going to add a new variable here and so we want to set the active profile so we're going to say spring profiles active and we want to set this to production so that it uses our production settings so with that in place I'm going to go ahead and Commit This and say updating for Railway and let's commit push and then as we go back to our deployments here we should see updating for Railway so this one started this is the one we care about and it is going to go through and build so it's doing its first thing downloading everything from Maven it's actually going to use another way to build a container called NYX packs you as you'll see in the settings you can kind of change how it builds but I'm fine leaving it at the default so it's going to build a container and then deploy it for us foreign Docker RPG there's Railway build time 26.62 seconds now it's going to publish that image and then try and run our spring boot application all right so we have a success if you drill into there you could see the spring boot application starting to see people Tomcat start on 59.70 and our application started so if there was an issue and you didn't do something correctly you would have some output here that could kind of point you in the right direction you see that we are following the following profile is active production that's a good sign so if we go into here we can go over to settings we can actually generate a domain name so let's generate a domain name and this is going to give us this content calendar production so let's go ahead and click on this and it's going to open up in a new tab and here it says one moment your deployment should be live soon so let's go ahead and just wait a second for this to be live cool so it's live now uh we remember our home endpoint is displaying our configuration properties so if we want to go over to API slash content there is a list of all of our content in the database so this is point from the database and it looks like we may have run this twice so that's a good thing to note if this got deployed once and then deployed a second time we are running that command line Runner every single time because remember we we only ran this in development mode and in development mode we had the H2 and every time it restarted we had a fresh database to work with so now every time this starts up it's going to insert that data so you may just want to add a quick check in there so if we'll come back here I'm not going to run this again but in your config and data loader you could do something like if repository dot count is equal to zero then go ahead and do this if not we don't want to go ahead and insert this every single time okay cool so if I go to railway and we jump into postgres we can see that we have this table we can see all the um rows in there we can also query from here so we can say select star from content run our query and cool we got all our rows in here so really just that easy to get something up and running on Railway the biggest thing you have to worry about here is make sure you set the profile the active profile and then make sure you're using these particular environment variables that Railway has set up for the pros for the database if not you would have to set up new variables for that with specific values so cool again just a nice a really nice easy way to get an app out into production especially when you're you know just kind of playing around or tinkering there's that free tier there's also a generous developer tier big fan of Railway but um there are other options so make sure you look in the documentation for this repo under docs under production there is a bunch of hosts that I can recommend again some I've done videos on some I haven't but a big fan of all the ones on this list so go ahead and check those out Wow first off I just want to say thank you for sticking around through this entire crash course you made it through it I hope you learned a lot now this was a crash course this was not a full master class on how to learn everything there is to need to know in spring so I know I'm going to get a lot of comments like why didn't you cover this or why didn't you cover that we had to draw the line somewhere there are a lot more things that we could go into that we just couldn't do today so that's that this is a crash course I said this at the beginning please take what you've learned today and apply it to a different domain I think that's where a lot of the the real learning comes into play so kind of what's next first off bring office hours if you guys aren't aware of it it's this really great show that DeSean and I do over on tanzu TV go ahead and check that out I will leave a link in the description below as well as the resources in the docs folder for the GitHub repo for this project today there is a resources file this file contains a whole bunch of resources so all the documentation to a lot of the things that we covered today those links are in there there's links to books I suggest podcasts uh YouTube channels Yours Truly of course and then everything that you need to do to find me so again there is so much more to learn this is really just the beginning friends I hope you'll follow me on YouTube Twitter and Linkedin for more content I really really hope you got something out of this today this was a lot of fun to put together I hope you had fun going through it if you did help me out friends give me a thumbs up on this video subscribe to the Channel and as always happy coding [Music]
Info
Channel: Dan Vega
Views: 219,556
Rating: undefined out of 5
Keywords: dan vega, spring boot crash course, spring boot, spring boot tutorial, java, how to use spring boot, spring boot tutorial for beginners, spring boot full course, spring framework, spring mvc, java spring boot, spring boot project, spring boot initializr, spring mvc tutorial, learn spring boot, java tutorial, spring boot for beginners, spring boot tutorial for begineers, spring boot rest api, spring boot framework tutorial, spring boot 3.0, spring boot 3, spring boot java
Id: UgX5lgv4uVM
Channel Id: undefined
Length: 223min 51sec (13431 seconds)
Published: Fri Feb 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.