hello everyone and welcome back to our Channel today we'll have an exciting topic to discuss hexagon architecture with spring boot if you are a developer or maybe an architect you probably have heard of the term hexagon architecture you know hexagon architecture is a fantastic way of um building software that is more testable and maintainable we'll show you today how to implement it in a spring boot application but first let's talk about hexagon architecture what is it hexagona architecture is also known as the port and adapter architecture you know it is a software architectural pattern that
promotes a clear separation of um of concerns in your application it is called hexagona because it is often depicted as a hexagon with the core application in the center the key idea here is to is to isolate your business logic from external dependency such as databases external services and user interfaces now to make it even clearer let's dive into the core principles of the hexagonal architecture one of the core uh principle of the hexagonal architecture is the idea of ports so ports are the interfaces through which your application communicates with the outside world so these
are contracts that defines the methods or functions your application exposes to the external components in springboard for example we can use the Java interfaces to Define these ports adapters on the other hand are the implementations of these ports they are responsible for like Bridging the Gap between your core application and the external resources like for example your database or maybe your HTTP clients or maybe a messages system like Apachi uh Kafka or IBM mq Spring Book provid provides various ways to implement you know these adapters now we it kind of sounds a bit you know
theoretical and heavy to understand on first clance however I'm going to show you in a bit how to do it in practice so let let let me cook okay so we're going to kick off by you know bootstrap in our application for this we always come to our website here St spring.io and this website gave us this interface that allow us to quickly boost drop spring boot application so I'm just going to keep everything as it is the default I'm going to be using grle Java and this version of spring boot uh I'll make a
small change here I'm going to change this package uh group ID to this uh you can keep it as it is you can put whatever information you want to put there the application name or Alat ID I'll just call this one demo uh hexagona uh architecture okay something like this and yeah I'll just keep everything simple and leave it as it is and the Java version will be using today is Java version 17 which I think is okay and for the dependency section we add just the basic things that we need so we're going to
need spring web um spring web web I'm going to add us Alum book um I'm going to add the do compost support for spring boot uh I'll add POS so we're going to need some database and I will add the POS SK driver I think um yeah that's the POS uh we're going to add um spring data jdbc uh I think it's data you could use spring data GPA or spring data gdbc you know but I prefer using spring data gdbc because it allows me to have more control over my database uh interactions um let's
see if we have anything else that we don't um so have web Lum compos PBC I think this will do for now um yeah so I'll add one more let me add um uh what is it called Flyway um this is looking good so far if we need any other thing we'll come back later here and get it so for now I'm going to download this project by clicking this generate button and then I'll load it up inj so see you there okay so this is our um project here loaded in gter it's simple and
basic just as we configure it on the website here we have our source you know folder where we have our TR resources folder we have test folders here which is empty everything here is fresh and ready for us to start playing around with okay um I'm going to open up the resources folder in the resources folder we have um these folders already here generated for us this DB that migration is here because of the Flyway thing that we added in the glass P the Flyway dependency so I will just show you that right now I'm
open the Builder grer so here you can see all of our project configuration the dependencies that we added from the website and like I said if we need any other dependency we going to get it out there and bring it in and add it to this dependencies uh section so basically our application is just as we configure it I'm going to start um firstly by changing this application. properties to application. Yo which is convenient to work with so just change the extension there to yl and I reflect to it awesome that's the first change we've
done and we'll be adding in this uh db. migration uh directory this folder will add in it our database schemas so the thing that we create our database tables and you know other objects that we need in the database but we'll keep everything simple and just focus on the idea of uh designing an application using the hexagon architecture okay so basically here we have an empty um Java directory with our Ro package and then the main application which is the entry point and it's with this so now to to break down your application in uh
to to to suit your your your application to the hexagon architectural style you you have to understand like I did in the intro you have to understand the the entire uh concept of the pattern so the idea is you want to have your application separate from the um outside world like other external components like databases HTTP clients um messaging systems Etc so the way we do our folder structure is we're going to create one folder or package and this package I'm going to call it application so now in this application package I will put everything
that is core that is internal to my application that is business logic it has nothing to do with external systems like no database business there no HTTP connections just just the the the logic the business logic of the application that's what going to contain only those classes that related to the application logic is going to be placed in these uh in this uh application package then I'll make another package and this package is going to be infrastructure okay so this infrastructure package is where I would place all things related to infrastructure that is the framework
that we're using spring framework like all those support classes like configurations and other components that are related to the to our framework so in our case is spring boot so we're going to put our configuration classes there we're going to put exception handlings utility classes those things that we need to support our application okay so our application will have just the Core Business log the core components that are required to run the the the the logic the models and other things will be placing here and then the infrastructure will contain all the extra utilities the
configurations Etc and then I'll make another package um this package I'm going to call it adapters so now this adapters package will contain all the implementations okay of the the ports that will Define within this application they will contain the concrete implementation they will have the um the the how to do it okay I'll say how to do it so in the application we Define the what we want and then the adapts will get it for us will give us the implementation of that okay so this is where we put all of our implementations for
the ports or the interfaces that we Define within the application and in the infrastructure will place in just the configuration the utilities the support exception handlings and all those you know things that we need to make our application function properly so these three directories in some other implementations people may add extra but these three are the core basic directories that we need to have in your spring board application in order to implement to start implementing the hexagon architectural pattern so um now next I'm going to show you you know what are the things that we're
going to place in here and we're going to place and then the things we're going to put in this adapters and what we're going to put in the infrastructure okay so now that we have these packages here um I want to Define one more package that's the that I think is important to have also but you can also add that package in the applications folder here or you can put it outside but to be more explicit and clear I'll just put it outside here so that you understand so here I'm going to create that package
it's going to be the domain package so the domain is basically the the object that you going to represent okay like the representation of the physical object that you want to manage in your application so this here this is where you define uh things like maybe for example if you're doing a school management system you will say you want to define the student because you be managing students you be managing teachers you'll be managing uh subjects you'll be managing things like uh exams Etc so all these things you will have to put them here okay
so you can either place this package in here or you can put it outside here either way it's fine but the idea is that it should contain only the domain not the entities not documents like if you using M TV not the entities okay not a reference of your database table just the domain the raw domain okay so we will put those things in here and yeah so now I'm going to open up this package and first thing I want to create inside this um the the application package is going to be the um we're
going to create a use case so there's this idea of use case use case is it's a service okay so the use case is going to be like like the name suggest a use case like for example in our in this T application let's um pick a domain so let's say I want to create let me create one domain and this's domain I use record and let's say want to manage movies okay so it could be anything but let's pick movies for example want to be able to to to to store a movie in our
database want to be able to retrieve the list of movies retrieve a specific movie want to be able to um to delete a movie and maybe update a movie these know basic crowd operations so I'm going to call this um domain a movie and here I will Define few properties of the movie so uh our movie will have an ID so it's going to be along and then it will have a title and then we'll have maybe something like a description we have um release dates I use look at dat for this one something like
this I look at dat from java time uh release release it and then maybe I'll just add something like the director uh director name okay so let's keep it simple like this so This Is The Domain I want to manage in this uh project it's a movie okay so now that we have this domain we need to create use case use cases that will um that replic that would let's say uh uh use cases that want to do want to to perform on this movie so one use case could be they want to add um
a movie to our database that's a use case want to be able to to update a movie want to be able to retrieve a list of movie so in this application package we'll be creating our our use case packages because you know want to keep things organized so I create a package I call it use cases so in this use cases package we create we add um the package we add the classes that will you know uh manage our use cases okay that will help us to to to write these use cases and these use
cases they they have to um to talk to other services like they have to talk to other parts of our system so um I'm going to add another package called dto okay so this dto package will contain a representation of our domain that is unique to that to a specific use case Okay so let's say if we want to get um a movie and we just want to to have the title and the the description of the movie we don't want to have the release date or the director name we can create a dto that
represent that specific um that specific data and then we can have a use case that will return that will perform that operation for us okay so you don't need to have um The Domain actually per like you don't use your domain as a transfer object so you create a tto package where you place some some data transfer objects and next is we're going to create another package that will I just call this one Dao some people will call it Ido so it's like data assess object so this is the one that is going to define
the port of how data is going to be brought in um our application from our from external sources like databases not you know not uh you got it not from things like rest end points or something but it is from The Driven part okay the driven part so we have two parts in this hexagon architecture we have the driving part that is the one that brings in data like triggers action from external like a web interface or maybe a rest in point Etc and then we have the driven part that is our application going out
to get data okay so this Doo is going to represent that that Port that will will um that our application will need when it needs to go out to get data so for example going out to a database to get data now in this Dao we place those um those uh classes there those interfaces and yeah so with this I think we kind of set so we have to first start by defining our use cases okay we already have our movie um uh uh domain so we have to Define next our use case and then
after the use case we now come over to the adapters and then we'll start to work on other things so let's create our first use case which is movie use case since we have just movie domain in this uh this demo app so I'm going to call this movie um use case something like this and this going to be a service so that you can do you know dependency injection just spring both stuff now also add the Lum require a Constructor at the top you know you know you can add the SL 4G thing if
you want to do login I don't know if I'm going to do loging but yeah so now in this um movie use case I'm going to write the business l logic of how to perform the specific cases in this movie that we want to achieve these actions so let's say we want to be able to um save a movie in a database okay so I'll create a method which will be a public one um it's going to be public and let's I want to return the string when I save a movie uh just save movie
and to save a movie I need need to have a movie so that movie we already have a domain object of that movie but we don't want to receive all the fs in this domain this model okay so for that we have to create a data transfer object that represents only the fuse that we need when we want to save a movie so in that case I will come over to um our dto here and create a data transfer object that will contains only the fields that I need to save a movie all right so
let me just do this here and I'll just return all for now and inside here I want to have a an object called new movie dto so just call it new movie uh new movie D so this object I'm going to create it right now inside the dto package p uh it should be like this uh new Java class and I'll use D Record for that also and the new movie it should have just maybe this information I don't want the ID because the ID you know I'll generate it automatically all right cool so now
I just come back to this new movie that I uh dto that I have here and that's it I have the new movie right there so now if I come back to my thing I can import this class and now I have a new movie so to save this new movie the database um I could have up some conditions that I need to satisfy in order to um be able to successfully save the movie in the database so I could do things like maybe um check if the movie is already in in DB you know
or check if this movie is before this specific date so all the business conditions all these business requirement and logic that you need to perform you will do everything here against this movie okay this is where you will Define The Core Business logic of your application so in our case let's say we want to save a movie but we want to save a movie one time in a database we don't want to save it you know multiple times don't want to have multiple duplicates of movie so so the first thing we need to do we
need to check if the movie is in the database so to check if the movie is in the database we need to um make a call to uh we need to check we need to check with the the um the name or the title of the movie to see if we already have a movie in our database with this title so to do that we require our the the data access object okay so we will have to create um our dat access object here in this Doo folder and for that I'll just click like so
and I create an interface remember this data access object is a port it's a driving Port so it's going to go out and get data from the database and bring it back into the application okay so it is not the actual thing that is going out to get the data it is just going to describe you know how it wants the data and what it wants and then the adapters that will Define here later will be the one that will actually Implement you know how to go there get it from the database bring it back
and all of those so I'm going to Define that uh interface right now we just call it uh movie D AO like so and this interface here will Define the metal signatures okay so the first thing we want to have is we want to have a movie back okay whenever we go to to the to the to the database to get um whenever want we want to have a movie back if it exist in the database so we say want to find a movie by the way this movie to you can create a dto for
it so um I'll just keep it simple and use movie from the domain and I will say get movie so I can let me wrap this in optional such that if the movie is not pH we receive so want to have a option of movie like so it say find movie by title so here pass in the movie title simple as that let me fix this think and and this one okay why am I having this here expected oh yeah we need to close this so now this is just the signature of the method we
want to find a movie by the title but the query that will be executed where that movie is located we don't know we don't care okay see that's the beauty of the hexagon architecture Define the port and then the implementation will be taking care of you know by another thing so basically this is the first better we have here so let's you know add other ones so also also want to have a list of movies so find you know let's say all movies so in this one we don't care about title we want to get
all the movies that we have in our system and we want to have a method also to save a movie so this one maybe should return nothing or yeah nothing just say save MO movie and this one it should take uh a movie dto that we Define okay and let's say I want to update movie you know you can take in a movie and then update it something like this um but you get the idea so you can write all the actions that you want want to perform you know here this interface this interface and
then you have another class that will implement this interface and then get the actual uh concrete data that you need to return so now that we have this uh setup I can um I can inject this interface in my um in my um use case this move move your use case that we uh created here and use it okay so I can do private finer um movie Dao this data subject it's call it movie Dao like so so now that we have this we can you know use it to check if a movie exist and
if it does exist we will not save it in the database we show an exception now that exception that we show we have to Define it in the infrastructure package you see how things are getting in line but let keep going let's let's keep cooking let's keep cooking so first let's see whether a movie exist in database or not so to do to check to do that we have to go and call this movie uh D object and see if and try to find a movie by the ID so find movie by the title not
the ID and then this movie that we send in as um um as a payload we're going to get the title from there so we going to say new movie and then dot title like so so now this is going to grab this title and then call our Doo our Doo is going to be implemented by some class that will know how to go to database and get the data back and if it returns to us the data that's a good thing we can store it somewhere so let's say we can store it in here
movie or we could just say uh is present is present something like this okay so we will since this method is returning to us an optional we can do this check we can say is present so this will check if this respond the return value from this it is is it contains some data it's going to return to us true but if it is not it's going to return false so Bas on this is this condition you can now you know do some some other stuff so you can write your check if this is present
then you can maybe CH uh um new you know new exception so you can see movie already has this exception something like that this is a movie already as this reception which is not yet created I can create that no in a sec so let's create this exception um I'll just come over to infrastructure package and I'll create a new package I'll just call this exception some people call it errors other way is fine so I create a new class and I just call it movie already let me see if I copy that movie already
exist exception okay and I would like this to extend extend the run time exception class and I will create the Constructor for that we already accept uh exception and then I'll use the super Constructor and just passing the message so this should do um now I can use this exception here okay so here I can just pass in the message and this message too you can you know it could be any message movie already exist so now this should be fine and I think I need to troll this here okay awesome so if this condition
is present is true then it will show the exception and nothing will happen but if not it will go ahead then we can go ahead and save the movie so we can just say continue to save movie so this one we call the save method that we Define on our Dao to save the movie so for that we just say movie da do save movie and then we pass it this movie details the new movie object that we have right here so that is after our conditions is met properly the movie not the database Etc
and then if we have other conditions you know depending on the uh specificity of your application you can you know specify all those you know pre conditions that you need to save a movie and then after that save the movie so after saving the movie we just return return a string saying movie saved successfully okay um yeah like so and and we should be good why is this one like this anyways uh if okay I just put this in this thing awesome so we should be fine now put multiple lines to have better readability awesome
so now that we have this all set up we have defined the action save movie on the movie use case see how it work we did not implement the query that will you know do the saving in the database we just Define what we want the action that we want to perform and then another class we implement this interface and we'll you know give the details of how this find movie by title will be you know performed and how how this same movie will be performed how it will get the actual data and all these
other ones that we use later we'll see how it get performed so um let me come back to the use case here um I'll just close this for now for you to have more room see uh yeah so next we're going to define the next action which is the find movie by the movie ID the movie type so now let's um implement the other actions so um we already done the one to save movies let's do the one for getting the list of movies so for that we're going to have a public method that's going
to return to as a list of movies uh we just going to C it get uh all movies something like this and yeah that's it that's all it's going to do it's going to return from the movies Theo here we have a method that we Define there uh there's a method there called find all movies no not this one but find or movies this one and that's what I'm going to use here find or movies so it's going to return to me a list of movies so this one is pretty much simple there's do the
other ones to to update a movie so this one will do um let me see when you update a movie what do we see here okay returns nothing so uh I'm going to return this a string and then I'll say update movie and for this I'm going to take the movie as um as an argument the movie that I want to update and then I'm going to return the string that say movie successfully updated something like this okay so now to perform the rear update I will copy some code from this place we have to
make sure first that the movie is in the um it's in the database so I'll copy that piece of code and bring it right down here and this one I'll just replace it with this and now it's good so if the movie is present if um if it is not present so if it is not is present then we will CH a new exception so for that I will throw a new uh exception so I'll draw a new movie not found exception and I say movie does not exist okay this movie does not something like
this so I have to create this exception for that I'll come over to our infrastructure uh package here in the exceptions package and then I'll create a new class that will be this and I'll let extend uh extends the run time exception and then I'll make the Constructor it's going to be public movie I take a string as a message and then I'll just pass it onto the super like so so the exception is created fine I'll go where problem is here and I'm going to import this guy so it is okay now just throw
it here also chose this movies not found exception okay so now if the movie is you know found then this exception will not be thrown if the movie is not there this will be true so if we get past that we will then call on the U the movie the old that update movie method and pass it the movie okay so that's all we had to do there and basically this will update the movie so the the implementation of this method now will you know do the magic of how it's going to do it in
a database we don't care about that part we leave it to the adapters we just create a ports and leave it to the adapters to uh perform the actions so that's hexagon architecture okay so I think we got a few more methods to implement we have one to update want to get let me do the one to get uh movies by the title so this one uh public movie we return a movie get movie by title something like this and we're going to take the title of the movie as an argument it's going to be
a string uh movie type to okay like so and I will just copy this code here as well and make a small change in it and for this we what I'll do is I'll remove this spot and I just return it directly and then what I'll do is instead of passing in movie. title I just pass in the movie title here because it's a string and that's what we want to search by and I don't want to use this ispr so I'm going to remove it instead what I will do is I would do this.
true that is if the movie is not present it should true an Inception okay so now this exception I want to CH is it's going to be um this one so I'll just copy it and I'll create the the Lambda and I'll let it show this just paste this piece of code here uh I think it should return you not through just return it and this is not supposed to be here okay now it is looking good so what this code does is it's going to look in the database or call our um database or
whatever service that is providing the movies list and find the movie by the title if that movie is not found that is it it's not return it's going to do this exception that the movie it does not exist Okay so I think we have one more method that is to delete a movie I'm going to leave that for you as a challenge so when you're following this uh video you can you know use the same logic and Implement that we already have the uh method here in the do so you can write the the use
case action for that okay so back to the movie use case we have basically let's say completed the use case Okay the use case is good now when need to implement this movie Doo because this is the driving part of the hexagon architecture we need to implement how this um these actions that we have specified in here how are they going to be fulfilled so for that we'll move on to the adapters package here and create a few adapters so now for these adapters uh I'll create two packages Within These adapters to make things really
you know clear for us I create the first pack package I'll just call it in so basically this package it it's going to contain all the all the the adapters that are going to be bringing in uh uh data like that's going to be coming from from from sources like maybe rest end points uh a web interface Etc it's going to basically hold you know our controllers you know so this is going to be bringing in data so this is the driving I think yeah it's the driving part of the hexagon architecture it's going to
be driving in data and then I will create the second package in this uh adapter's package and that's going to be the out package So within the in package we place our you know things that will bring in data like that will cause that will trigger our application from outside and then the out package will be our application going out you know to get some external data so application going out to communicate with other services Services communicating with our application their interfaces will be implemented from here and then services our application will be talking to
will be implemented within this out package you know just to basically distinguish the two so that's so in the case of this movie Dao it is an out action so we're going to put the implementation or the adapter that will fulfill this uh contract inside of this uh out package so here I'll create a new package so we're going to start with that one first going to start with um the the out package I'm going to create a new package in it and I'll call this one um po just JBC um yeah just sport jdbc
jdbc um okay I I wanted to create a package not a class let me do it again new package I just call it postgress jdbc package something like this so now this out uh out out out area here we we could have multiple implementation of of this uh movies Theo object so uh we could be using a mongod DB as our backing as our database we will be using um Amazon uh some database from Amazon or we could be using um B like we are in this demo we could be using like any type of
database we could be using elastic search we could be using Oracle but the idea is that the implementation like the the core logic of our application always remain in type no matter what kind of data source we use so for each type of data source going to provide them as adapters so for the case of our application now our adapter will be a PO gdpc adapter since we are using post to fulfill this contract if we are using mongodb we create a new package here you know for clarity so I'll create a new package and
instead of having p and I'll just put DB something like this so all the implementation for this contract for for relating concerning post will be here so here we have things like entities we have things like repositories you know like gdbc repositories and then we also have um uh yeah we have the actual adapter implementation of this interface that adap implementation will be using all those things The Entity and then the the repository that will actually be communicating with the database similarly if we intend to use mongod DB we will be using uh we create
our documents our mongodb documents uh objects in this uh package we create our TV repositories in this package and and so forth and so forth so basically you can have multiple implementation of this thing and it will always be the same the the the only thing that needs to to uh satisfy is the contract of this interface so it needs to return for indic Cas of f movies by title it need to returns an opt an optional and it need takent or title okay similarly for this it need to return list of movie so wherever
it is getting that data from it don't care whether it's getting from mongodb or POS or Oro or AWS something it don't care we don't care our application don't care application is isolated from that enre process we just created the port which is this interface and then allowing the adapter to provide us the data so now you getting the idea slowly about um the hexagona architecture okay so let's Implement for this POS gdbc so for this uh we'll create um a few packages within it and I'll create one for entity so entities and uh I'll
create another package I'll just call this on repositories and I'll create the um the actual adapter you know implementation so I just create this uh class and I just call it um I just call it movies movies movies um adapter something like this okay so movies the adapter something like this awesome so as you know naming things can be a little bit crazy but however we're going to this movie Z adapter is going to implement guess what is going to implement our movies Dao okay so it's going to implement movies Dao so this is the
adapter that will provide the implementation or the Fulfillment of these you know methods that we Define in the Dao here so um I'll just close these exceptions we don't need them right now and I'll come back to my adapter and as you can see here because I'm implementing this uh interface I have to implement the methods that I defined within that interface so I'm going to just use intellig to do that and I want to implement all of them so I click on okay so now this is the actual implementation of these methods so now
we're going to write in here the the the how to get the data okay so how to get the data our data is store in which database is store in a post jdbc database so we will need to connect to that database using our repository so need to create the those repositories here and those repositories uh we need a representation of the data into tables in the form of an entity so we put those entity inside of this entity package so first of all we need to create the entity and then after creating the entity
we need to create the repository that is going to create a connection between the you know our app and and the the database and then after that we now you know bring the repository inside here and use it to get our data all right so let's go ahead and do that now to create our entity I will make uh a Java record so you could use a class or a record but I'll go ahead and use a record so I'm going to call this one movie entity like so and this record will be similar to
our model so I'll just come over to the uh domain here and copy these values um and I'll put it in the entity that I'm creating here so to make this um to make this uh uh record to be uh an entity a gdbc entity I need to um add an annotation so this is not jpa this is jdpc spring data jdpc so you don't have to write The annotation at into the above it okay all you need to do is to specify the ID so you just put at ID here so this is going
to be your ID and you can add other annotations that you know we use with GDP with JP like the the column annotation Etc but one thing I want to add here also is is the name of the table that this uh entity is going to map to in the database okay so if the entity name is the same as the table name you know it is not required that you add this annotation but sometimes The Entity name and the table name will not you know be the same there will be slight difference in it
so you need to put this annotation in that case to to um to clearly give the name of the table you want to map this entity to so for this I will just call it uh movies um like this I think movies is okay so this will be the name of our table we'll create that uh shortly in this directory in this db. migration directory we create an SQL schema there and then we add the create a table and then you know so basically this is our entity and I want to add one more thing
to this entity you know in Spring data jdbc there's a thing they called uh a version ID so the version ID allows you allows the framework to know whether this whether a record is new not the Java record by the way but a record in the database in the database table that is one rule whether that data is new or it's been there before so I will just add add that there I'll use integer for that and I'll just call the version so this will give us the version ID and we don't need to provide
this it will be provided automatically so we just need to add this annotation to it ad version so basically our our entity is ready so now base of this entity we can create our guess the right repositories so let's go ahead and create a repository another C link it should be new Java class and it's an interface so just like you make JP or spring dat JBC repositories okay so I'll just call this one movies uh repository like so and it's going to extend the the crow the crow repository and I will specify the type
which is going to be movies entity movie entity and the ID is going to be of typ long I think yeah it's going to be of type long so now that we have this set up um I just need to add The annotation of repository here I think yeah basically that's it and if you need to add any custom queries you know to get specific data Bas speciic condition you will do that here so we'll do that in in a in a in a in a second because we need to to write a specific query
to get a movie by the title so I'll just leave this for now and we'll come back to it shortly now I'll come back to my adapter now that we have our movie um our movie adapter I'm going to um import it here so here I will just add this annotation um what is it require ask Constructor from lumo so that I can do easy depend injection so inject that um repository here movies repository let's go a movies repository like so so I can make this final as well awesome so now that I have uh
I have this one here and I need to start implementing okay so to find a movie by the title will be the first method I we need to implement here so for this we firstly need to we need to get the movie so to get the movie we say movies repository do find movie by title okay and and I want this to return for me an optional so if um yeah it should just return from an optional so basically I can do this here I can just return this directly and I remove this one so
so now this method is not you know in our in in our repository yet so to create it I just use intellig ID to create this method for me so now you see we're returning um we're returning an optional and we going to find this movie by the title so this should work because similar to jpa you can you know do stuff like this find movie by title it will work but I just make it more explicit so add the query annotation here and this Square say SEL um or from movies so movies is going
to be our table name where um the title will be equal to um I think where the movie title will be equal to this okay where the movie title it will be equal to this condition that will put here so this will be um I think like so so this is going to be the query so now I need to add annotation here called Pam and it's going to be title uh basically I think this is the query that we need to execute to get that uh data so I'll leave this like this for now
and I'll come over to the adapter again and let's implement the next one so this the next method here is to get all the movies there's no query here no condition so I will just use def find all method from the crow repository that we extended initially this repository it contains a couple of methods so one of them is to um to find to find all the data so we don't need to implement this we already have have it okay the other thing is that this is returning an iterable and we need a list so
for that we just do tap gting and we we'll do that right away so basically all we need to do here is first of all do the typ casting one the list of movies and we going to call the find or method like so okay and I think I need to wrap all all of them in a parentheses so that we can have the on that I want move this repository that's fine all um what am I getting wrong okay let me do it slowly okay let me redo this thing I think I'm missing something
so I'll get this as it should work so I'm going to cast this response to a list of movies [Music] theong so what is the same inoma type uh find all oh yeah I just get it we we are returning here a list of movies and this is returning is bringing to us a list of movie entities so we need to do that um thing from there okay so there is a movies entity is what is returning to us yeah sometimes the brain freeze happen so forgive me okay so now I'm going to um take
this list of movies and map it to a list of movie entities so I can do something like like this I just wrap all of them in a parentheses okay so now you see we have list of moving entities so this list of movie entity I'm going to stream them and I will run a stream and then I'll map for each movie entity I want to return an equivalent movie Object okay so for this I will make um a new uh I need to return an equivalent movie Object let me see if I can do
this okay um yeah I need to return something so I need to return a movie new movie and this movie will have I'll just copy the data from this movie Object to this um this new movie so what I'll do is how the movie entity that um let me make this small m m entity do I want the um I want the ID and I want the title I want the description I want the um uh I think what was that uh movie entity that it should be released it and I think the last argument
we get there is it should be um the tit but I think director name yeah so why are we having problem here okay awesome so now we are basically copying the values from each movie entity into a movie Object okay that we are expected to receive so I can just return I just need to make this thing to be a list so I can do the to list method there so now we have a list of movies so we can return it directly awesome that was um a bit hanky but you get the idea so
basically what we did was okay again replace this with the Lambda for to be more clear awesome so now it's even more read so all we did here is that we went ahead and searched for all the movies in our in our database you the movie entities and movie repository we we received a list of movie entities that is a list of Records within the database table and then we map those record for each record we converted it to a movie Object a movie you know the domain object it could be a dto you know
but we just decided to use the domain you know itself so return a movie that was nice next we we need to save a movie okay so we need to create the implement mentation for saving a movie so to save a movie we um we already have um the movie here so the checks to make sure whether the movie is in the database or not that is business logic we don't we don't want to bring that part in in this um adapter so we did that part in the implementation in the use case in the
the the the port okay so in the use case we Define how all those happenings will happen all this logic all this criteria that need to be met to save a movie so here we have a movie that we need to save so only concerned about saving a movie to the database so to save a movie to the database we need to first of all create a movie entity so to create a movie entity we we um take the values that we have in this movie Object and then copy it into a new movie entity
so for that we firstly call the um what's say the the movies repository and then we call the save method there not this I can just save it like so and this takes an entity so I'll create a new movie entity and this new movie entity will copy the values from from this movie Object here okay okay so now uh this movie dto does not have an ID because our ID will be generated automatically by the database so for that I'll just put no here okay so the ID will be no but when it goes
in the database it will be uh generated by the database so an ID will be provided will be autogenerated so now uh I think the title description we need to add the um what is it called the I think release state so it's going to be movie. release date and then movie the direct name so I just need to remove this comma and put another semic on here so now what is the issue um I think one this no oh um what just happen here we need okay new moving entity oh the version so for
the version we we don't need to Prov it it will be autogenerated so just put no as well so now it's fine you know I added a version in this movie entity when I was creating it this thing you know when you creating using records you have to to provide the data at the time of the creation of the object so that it can be fully established all right um what was I here okay so now we now you know Define how to save a movie Next let's do the um the want to update a
movie so to update a movie we grab a movie so it's kind of similar to this um it's kind of similar to this we have a movie and and we basically be saving that movie so what will happen is that if the version number in the database is more than zero or is not know it means that movie is already in the database so when you call this save method it will perform an update operation but if the movie version number is not or is zero then it would it will assume that the framework will
assume that it is a new movie so it will save a new movie in will do an insert operation it won't perform an update operation so this is uh pretty intelligent so for here the ID will get this um new movie I don't know why I got a new movie but yeah so I'll just paste this here here here here and here and yeah the movie ID will be coming from this new movie that I so this version will also be um it should be know I think I should add a version to this uh
movie thing yeah it will make sense but anyways we just let's leave it like this for now let's see we just keep it as all and okay all right so let's uh do the one to oh yeah the one to delete the movie I said I'm going to leave it up with with you guys to to sort it out okay so you also do the implementation for that I will upload this just go to my GI up and share the link in the description of the video so that you can follow along and try to
implement this delete movie method so I just keep it as it is for now so basically we've implemented we provided the the implementation for the the ports the adapters for the ports that we we defined okay so now um the next thing I want to do is to work on the the in part that is the driving part okay so in this part we're going to put in here our controllers so I'll create a new package now call this one web and remember in this package uh in this in package you could have uh things
like uh graph C rest soap these are different ways you know um data can be uh information your application can be can be triggered Okay so in our case we'll be using um the rest end point so for that I'll just create this package called web and inside of it I'll create the class and I just call this movie controller so say movies [Music] controller and this is going to be it's going to be a rest controller with the request I think yeah request mapping I'll set it to for/ movies okay as the base and
and now add this require a Constructor to and here we will Define the methods that that is our endpoint methods okay so we Define them here the first endpoint method we want to Define is to to get all the mov for example so we are going to return the response entity of something and uh let me spell this right so it's going to return a response I think should be like this yeah a response entity uh entity of something we're going to call to the method name as get all movies Okay so to get all
movies we we need to call one of our use cases so the use case are responsible for managing actions on movies is the movies use case so I'm going to in Che that here uh for that I already have the require Constructor I'll do private funnel and I'll we call it movie use case if you can remember so this movie use case so basically this is your service so this is the one that you call to get the the the actions related to movies so here I'll just return now our response entity. okay fided everything
goes well and I'll pass in the movie use case object that we just injected and call one of the method that responsible for finding all the movies so the method there is get all movies and that's it now the next thing we need to do to this method to make it a rest end point is to add The annotation at uh uh get get mapping because we'll be using a get request to get this data and and I want it to be mapped to the to the request MPP to the RO so I want to
be SL movies this will give you all the movies okay so we're going to do the same thing for getting a specific movie as well so for this uh I'll just past the same thing here but this time I'm going to make a little change to the request uh path so instead of Slash movies it's going to be slov slash the title of the movie okay so here in this method so I'm going to change this method name to get movie by title and here we have a path variable that's going to be a tpe
string I'm going to inut this so you can also do this for more clarity so this is mapping to this and the actual data will be mapped to this variable here which is going to be a t string so here I will call another method that already prepared to get movie by title so this method and it requires an argument of string type which is this we already have here so pass it in so now this is done see how things I'm moving smoothly when you organize it so next I'm going to copy this one
also and I'm going to work on the one to save for movie so I'm save movie and I'm going to change this to a post mapping request because going to be using a post object with sending in some data and instead of U uh I want it to be on the path the the root element here that we have here so it's going to be SL movies post to SL movies you will be calling this ining this method so we don't need this instead what we need is a request body and this request body is
going to be mapped to um a new movies dto that we created okay and it's going to be new movie dto to request body is going to be like this I think or like this how this work so I'm now I'm going to call the meod responsible for that and I want to change something here so instead of returning okay for saving a movie I want to return the status code of 2011 which is the standard for object being created so HTTP status code created which is equivalent to http St code 2011 and then here
I just do that body yeah like so and instead of this I would change this to I think save movie yeah that's the name of the method that we created and then I'll pass into it this object okay let me close this so that you see properly all right so that's all you have to do to save a movie so now let's do the same thing for updating the movie for updating a movie we want to update a movie uh for that we need to we'll be expecting a movie so we'll be expecting an object
type movie and just call a movie and here we just change this method to update movie and we pass in the movie just like that so here instead of a post request because we performing an update operation we change this to put mapping so be put um HB variable be Port when you run your test and likewise for the delete I leave it for you to practice okay so the delete I'll leave it for you you should you can Implement and delete um endpoint okay so now this um this is looking good so far uh
now I want to to to focus on the infrastructure because we build our application all this thing but remember we did not specify how our application will connect to our database like the datab username type of database and all those things they not create the tables and all the things so this is going to be the next thing that we'll do so let's that okay so now let's come back to our application. Yu far here and as you can see it's pretty much empty so let's put some configuration in it um first thing I want
to do is to set our application Port so for that I will use this uh code and by default it's 8080 so I'll just keep it as 8080 and next we want to configure um the spring application so for that we say spring application and then we set the application name and you could pretty much put any no name here and what I would do here is I just put hexagona Arc demo something like this and then the next thing we need to configure for spring is the the the data source okay the data source
is basically our database connections so configure data source and for this we need to provide a few parameters we need to provide a database URL we we need to provide um we need to provide the the username and also we need to provide uh uh the password okay we need to provide the password so now where are we going to get the database from so if you can remember when we were bootstrapping our application we added a dependency in our dependency section which is this um spring framework this spring board do compos support So this
um this allows us to have do compos as part of our spring application you know it makes it very easy to work with containers in Spring BL so we're going to be running a container that is going to be uh bootstrap off of this based on the support of this spring boot do compos as you can see it's for development only okay so because we added this at the time of bopping application it automatically created for us our compost. yo file here going to open it and set up for us por because if it notice
that we have uh what is the PCH resting we have porch in our class path that is in our dependencies and it detected it and created for us a container a post database continue with these credentials okay it set the password it set I mean the DB name a set a password which is the secret a set a usern which is my user so you can modify these if if you want but I'm just going to leave it as it is and use the names just as the appear so the first thing I'll need is
this so I'll come back to my application Yambo I need to set the the connection string and because we are using a jdbc database so going to do jdbc and as you can see the tab n is is helping me with auto compete already so basically this auto complete is not really what I want so I'm going to remove it uh I will add the name of the database post I think it's post SQL and then for/ host okay now tab 9 is doing a great job and then the port so for the port how
do I know the port I'll come back to my do compos file here or the compos file and the port is 5432 which is the default by the way but you can modify it and do some Port mapping but I mean we just keep it as it is so it's 5432 uh and I'll put that 543 two and then the next thing is for Slash and then the database name the database that we want to connect to okay so this is also provided for us so the database is my database I'll just copy that and
I'll put it there so now we have our database connection string the next is the username I'll just copy that from here too is my user and I just paste it here the next one is the password secret and as you can see I did not you know create that theile it was created automatically for me you know because of the compos support which is pretty neat you know save you bunch of time when you work in your application so now I think we are set for um I think we are all set for testing
our application so let's go ahead and try to um to run it and then we might have some errors you know always have room for errors otherwise you always have heart attack so basically I'm going to um start the application and then let's see if it will boot up okay I just wait patiently and this is the first time we start the application since we started coding so all right the first exception is already here the verion for f with one so this issue is uh I think yeah I know why the my Docker is
not running so I need to start my uh my Docker right away let me just do that and run the application all right so I just start my Docker server my Docker server was down so that's why this did not work because you know it needs the the the dck compos F need to run onck so basically I'm just going to run this again and let's see how it goes again so this time we should not have that Ducker issue so things are going on and boom we have another error what is it this time
um we have um say what let's see what is the satation okay so this is the actual issue the said that there's no being of type movie do within my application so this issue is because spring B Bo or spring cannot find the the the B the implementation for this movie de within this context so I think I know where it is probably related to the adapter so I'm going to go to the adapter this one yeah exactly so we defined the implementation for this movie Doo but we did not um register it to the
spring you know with with the spring within the spring context so spring does not know where is it so spring now is looking for the implementation of this movie de and he cannot find it so it's confused like yo bro what's up so what we're going to do is we will add The annotation here one of the spring stereotype annotation we just add at component and with this annotation spring board will be able to find this uh implementation so let's try that again and it worked so now as you can see in our logs here
our application ran it ran pretty well it started it went Flyway tried to find the migration schema but it found nothing and there's nothing we have there so basically our app is starting up as expected and everything seems to be wired up together you know we don't have 100% uh shity yet that everything is going to work as as as we want but but after at least we know that our app is starting up so next we need to Now work on our database you know tables we need to create our table so that when
we try to make you know data input like we want to save a movie get a movie we should actually be able to to receive something okay but for now if you attempt to do any of those things you know you will be Sting with a huge problem like whoa whoa this table you want to map data to do so let's go ahead and create the the tables that we need and and move forward so um as you know we are using Flyway to manage our DB schema so we have this folder here db. migration
in the resources folder this is where we're going to create our database migration schemas or DB schemas so for this I'll create the first schema that we need uh probably the only one since our application is just a demo uh we call this movies uh by the way it's going to be version one so Flyway has a syntax that you need to follow that is you have the version of the thing of the schema Follow by two underscores and then you give it a description for example create um for me create movies table table that's
the purpose of this schema so if I have another version of the schema I will just put version two and then give it a description and and. SQL so basically fly will automatically Loop through those schemas and it will know which one is been has been applied and which one is outstading so that way you have a way to track your databases across your application you know uh development so I'm going to work with this for now and for this we need to create our table but before create our table we also need to create
a schema because if you know that our ID we want to automatically generate our idid and to keep track of our IDs you know we use sequences in database so I'll create a sequence first uh create sequence and I'm going to call this sequence uh movies I just put movies uh table add sequence something like this so this sequence is the one that we use for you know storing our IDs next I'll create a table so create a table called movies and this movies table has will contain a couple columns okay so the columns should
match the the ones we have within the entities so let me see what's our entity this movie entity I'll just close this and and try to create two columns here all right so now the name of our table is movies it should match so it's movies and then the names of the columns or the properties in the in the in the The Entity it should match as well so if you have different names in your columns in your table you should add at column annotation to you know specify that but since I'm going to keep
it on basically the same I just go ahead and write them so the first one is the ID do it underscore and it's Al long so I'll use big in and it's going to be our primary key and because I want to automatically generate the value from this I'll put the default thing and next from this movies uh movies uh table so movies table ID sequence like this okay I think that will do now what will happen here is I would just squeeze this up a little bit so that we can have more here what
happened here is that I'm saying that okay create an ID but the ID the default value for the ID if nor is provided it should be the next value within our sequence so it automatically pick the next value so first one be one two three you know get the idea now the next thing we have is uh um it's the title of our movie and it's going to be a far it's 225 but you can reduce it I'm just going to keep it as no whatever it is the next one is description oh sorry that
description and then we have a release date so for release date um I'm going to use date so so release date uh release date I'll just use date or date time no I think date will be okay and then director name is going to be a vouer and then the version I'm going to use uh integer for that okay so basically this is going to be our our schema that we'll be working with so let me try to uh restart our application and see if everything here is going to be good hopefully it is okay
so we were able to successfully um start the application and fly was able to apply one migration schema so technically we were able to um to create our database table and apply the sequence to the ID so let's see if we can verify that since our app is already running but what we'll do instead is that we'll try to call one of the end points that we have here and see if we can get the data all right so I'm going to open the uh Postman I open Postman and try to use it to to
query our application to see if we can get some even if it is not data but let's just see that it's working okay okay so here we are in Postman I already set up here an endpoint for us to test test endpoint is the endpoint that get the list of all the movies in the system in our application in know in our database so I'm going to send this request and we got an empty list because right now there's no data within our database so we got an empty list but the request went through successfully
so to 200 200 status now I will come to this other request that I also prepared in this one we will be posting that is we be making we'll be saving a new movie so to save a new movie we need to provide some information about the movie so I already copied something I'm just going to paste it here and this is a movie so this movie is called Lawrence of Arabia and the description is here the story of TE Lawrence English blah blah blah Etc and here we have the release date and also we
have the name of the director so what I'll do now I'll post this movie that is I'll save this movie to our database and I'll send the request and as you can see here the movie was saved successfully now let's see if we can get that movie amongst the list of movies that we want to get so send the request to get the list of movie and we have one movie within our database so as you can see clearly our application is working fine and there are a few things that I probably haven't taken care
of yet like maybe exception handling so in the case of saving this movie multiple times let's say I want to save the same movie again with the same near Lawrence of Arabia when I send it it will give me an error but this error message is not really really handled properly so I have a video on exception handling I might leave the link in the description for you to look at it and try to you know work around with this and also um I did not do any unit testing in this application so if you
are interested in unit testing you can um let me know in the comment SE and then probably we can expand this application to you know you know do some unit testing in this application so the other endpoints that are supposed to test uh they want to get the movie by the the title so let's see if we can we can do that I think it's similar to this I just copy this URL and I'll paste this one here and it should be slov slash the title of the movie so I think uh it hope it
works I hope it works let me send this and see and it did not work so okay let me remove this and see again awesome it works fine so you can see here we have the movie okay we have the movie somebody calling me I just close this we have the movie and that's it our application is working fine so I'll leave the link for it uh I'll put it on GitHub I'll leave the link for you to go and check it out and you know play around with it so that's it guys thank you
so much for watching this video I hope you enjoy it if you have any questions please leave them in the comment and I will try to respond to them as soon as I can and also I want you to take advantage of the small application that we build here expand on it try to complete the other endpoint that we did not delete endo and also and try also to check out my video on exception handling and try to implement that in this application as well so until next time thank you so much and happy Gooding