Reactive REST API Calls in Spring Boot: How to Use the Reactive Web Client

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay so in this one we're going to be using the reactive web client to call a rest API from our spring boot application we have a server application and we have a client application so the domain model is super simple right we've got books and we've got authors now books the attributes we have here is ISBN to begin with which is unique identifier which identifies that particular book no two are going to be the same we're just using a bunch of made up ones fake data actually chat GPT generated that for me so thank you for that chat GPT we also have title on the book so just the name of the book the title of the book and then we have a link to the author from the book right and the author has a name and the author has an age and a numeric ID just to have a unique ID for it so the way that this is set up is that we have a book that book can have an author but an author can have many books so it's a many to one relationship between books and authors right so a book can have one author but an author can have many books that's our domain let's see it in action so we're going to use Postman for that so the server application is already running and it's running on Port 8181 which I've changed in the configuration there because it needs to be different from the default Port of 8080 because we're going to be having our client application run on Port 8080. so 8181 and it only has a single endpoint that we really care about and that's forward slash books so if we make a call to forward slash books which we can do like that we can see we have a list of results here what's worth pointing out before we dig into the individual results is the wrapper around them so we're using the pagination that's built into spring here and it gives all of this extra metadata so we can see we've got a pageable object it's got information on whether or not the results are sorted or not any offsets the page number the page size so we can hit this rest API with different page numbers and get different results we can actually hit it with different sizes and get different size Pages back you get all this for free when you use pagination inside of spring so you might be thinking Aaron why are you pointing this out to me the reason is that you'll see this represented in a domain main object on our client side a little bit later on and it's going to have this information like last total Pages size number so look out for that the real interesting bit is in the content right so this content is a list of books and we've got here an ISBN a title shadow in the attic and then author the author is nested so we've got here author but then we've got another Json object with the ID the name and the age and we can see we've got a whole bunch of these the last Ember by Adeline Rivers the forgotten key so on so fourth so this is all the information that's available on our server application we're going to take our client application now and implement it so it can call the server get this information and then display it on its own rest API so that's the server application let's not worry about that anymore we'll have it running in the background let's take a look at the client application code so let's take a quick look through the dependencies to make sure they match what we had in the initializer we can see here we've got spring boot starter web flux so all of our reactive stuff in Nettie comes along with that and there's lombok and then we just have the star Water Reactor test all of the basic stuff let's take a look at what we actually have going on here so I've put a bit of a an additional skeleton an additional skeleton sounds like a metal album so I've put together the Bare Bones what this application looks like right so a really vanilla application like this would have three layers so the top blade have presentation and that's where you'd present your data you've got the middle layer which is your service layer and that's where you do all your business logic and then you have at the bottom your persistence layer and that's where you deal with things like databases and nosql databases and we're not dealing with any databases or persistence layers in this one so we can just knock that off the bottom we are dealing with an external rest API so essentially we have two layers we have presentation where we deal with all our rest API bits and pieces and then we have our service layer where we deal with business logic and I'm including that call to the third party rest API as our business logic so let's just go through this so you can kind of make that make sense so at the top here we've got the books controller so the books controller as a single endpoint on it and it's just list all of the books that you have this will via the magic of the service layer do a call to the third party rest API I say third party it's like the other one that's running and then get all the books and then this will then look to display them it's not doing anything at the moment it's just going to blow up because it's got this unsupported operation exception but this is where we do our actual logic and we'll be calling our book service for this what's worth pointing out is a few things on this so obviously forward slash books with a git mapping so we'll do git forward slash books to get our books back and we can pass in a request parameter of the page so we can say page equals one or page equals two to get different sets of results back that page will simply just be passed on to the server application to get different pages back but this is something very very different here we've got a flux of book now I'm not going to pretend to be like the absolute expert on this stuff but here's what I know about a flux so a flux is different from a mono at least in this way of doing things right so if flux can return many and then a mono usually returns one neither of these things can return null but they can be empty so you might be thinking oh this is like fairly familiar to the whole like optional and stream stuff and yes they're fairly similar but they are different and hopefully this will shed some light on how so we're going to return a flux of books so think of it as like a stream of book but not really it's going to be many books right that's what we're going to be returning now you may be wondering like where's the response entity strictly speaking you don't need the response entity the response entity is there so you can change things like your HTTP status code in this case we just want to return it as okay which we'll do that if we return a flux of books let's keep it simple we haven't done the implementation here but we do know that we're going to be calling the book service because that's our middle layer that's our business logic so let's take a look and look at what a book service does has a single method on it which is get books we pass in the page which is just ninja and we get that flux of books back so let me just show you the implementation for book service quickly unsupported operation exception it will blow up if we call it we haven't implemented this yet we do know this is going to be cooling the book clients the book service is there to do all of the generic business logic around handling books whereas the book client is specifically there to call the server application it makes those HTTP calls so the books client interface looks a little bit like this get book passing in the page it's an integer but we can see here it returns a mono of page response book which seems super super complicated but let's break down what that means we know what the book is right so we know what that entity of the book looks like the page response was the thing that I was referring to earlier the main object on our client side a little bit later on so this is all of the metadata around pagination things like in fact let's look at the object so we can see it's got like total Pages total elements size number number of elements so all of this stuff is all of the metadata that was in Postman this stuff okay so we need some object to model them and we can see inside of content it takes a generic so the generic is where we can specify the type of what the content will be and if we take a look at the book we can see see that it's got the ISBN the title and the author there the author is an object in itself it just has the ID and the name the straightforward pojos plain old Java objects and we've used the longback annotations to make things a little bit easier on ourselves so we don't have to do all that boilerplate code hello quick Interruption so I'm trying to get as many people into software development as wants to so why not like And subscribe AI because it really helps out and why not share this with somebody you think could benefit maybe they want to have a career change maybe they're just wanting to learn how to code all the information's here and it's all for free and if you do have any ideas on stuff that you want to see that currently isn't on the channel comment below so what this means is Page response need to type for the list of objects that constitutes its contents it's going to be book and then the mono is one thing in the reactive way of doing things we are returning many books but as the object is the paged response we either have a page response with those many objects or we don't so it's a mono rather than a flux at this level at least that's how I think it's done seems to work so that's what we're going to do so this is the books client and as before it doesn't have any implementation so you can see here it just throws an unsupported exception so I think the best place to start is going to be the client and then we'll work our way up the various levels of abstraction until we can hit this rest API have it call the server and then we'll return the information and we'll do all of this with the web client so I'm going to go ahead and implement this now to say if you're waiting and I'll talk you through what this implementation looks like so here's our implementation let's start at the top so we've got here the web client reference and we are injecting this we're Auto wiring this by using the Constructor so the Constructor for books client import takes a web client and then we'll assign that web client to our private instance variable here we don't need our Auto wired on the top of this spring just knows that as this is the only Constructor that's explicit it will attempt to Auto wire on this one and then we've got our get books implementation here right so let's just skip over this and then I'll come back to this in a moment so we've got return so we're returning whatever's returned at the end of this we're referencing a web client and we're calling dot get on our web client so that refers to the HTTP verb get okay and then we've got the URI that we're specifying which is forward slash books so that's the same one that we were calling on Postman so the end point notice that we aren't specifying the host of the server that's done elsewhere again we'll talk talk about that in a moment and then we're calling dot retrieve which makes it happen makes that retrieve happen so it's actually going to do the action of sending the request and getting something back and then the response we're doing body to Mono so we're taking the body of the response that's been retrieved and then we are wrapping that in a mono making that a a mono that's returned and that is a page response books that's passed into that so let's go back to this a little bit so we need to specify what type is going to be returned from this so like the rest template this deals in objects we're going to say what type of objects are we dealing with well we're dealing with a pretty complicated one because we're using generics and we're using a page response of books so rather than just passing that in that that wouldn't compile there's not a way of doing that easily because you can't do pageresponsebook dot class doesn't work like that so we need to have this parameterized type reference and then pass that in it's probably not worth doing a whole lot more thinking on this one because I mean getting things like typer Asia and I'll do a separate video on that one but just know for the moment the purpose of this is to say what type of objects are we dealing with we are returning a mono page response book from this method so that's our client implemented let's take a look at our service implementation so the purpose of what we're doing here is we're going to call the books client get those books and then we want to return a flux of book right because we don't really care too much about that page metadata we only really care about our books and there's going to be many books so it's a flux and not a mono at this point so let me implement this and I'll talk you through it three line implementation but it's going to take some explaining so the first one we're just calling the books client get books passing in the page that's going to get us back our mono page response of books by calling dot map on that which essentially goes inside of the mono this is the way I think about it right it kind of like Dives inside of the mono to get access to what's inside which in this case is going to be that page response object now we've mentioned before that we don't really care too much about all of that total page business or size for pay age or what page we're on all that metadata we don't really care about that at least in this method so we just want to get the content from that right which is going to be our list of books so that's exactly what we're doing with this method so we're going inside of the mono and then on the page response give me the content which I list of books and then there's this line we need to return a flux from this method because it has multiple books and the way that we do that is by calling flat map to mini so flat map is a functional concept which basically when you call flatmap on something you can do something on what it wraps but it has to return the same type so when you flat map something so if you flat map object of Type X it will still return object of x if you flat map an optional it will still need to return an optional this one works in a little bit of a different way because you are doing a flat map on many many referring to the flux it's all a little bit confusing but tldr is we can call flat matte mini on a mono and we can get a flux back and that's why we're using that line I'm not really happy with that definition so I'm going to link to of the dock so you can read it through it's probably more than a video's Worth to explore all of those different concepts I'll link to it so there's our flat map to many so we now have our flocks of books returned from this method we've gone from the client level to the service level we can now call get books and get a flux of books back let's now deal with the controller level which is our presentation layer so there's our reference to book service and let me implement this for you and then we'll talk through it this one's a little bit simpler than the service layer so this should be it should be good we're returning that flux of books right so we need to get hold of the flux of books oh how do we do that or simply we just call book service which is what we've done here bookservice.getbooks but we know get books needs a page number right we've got up here our request param for page which isn't required so we can actually pass in a page number we can choose not to on our rest API when it's not provided we're going to default to zero in this case and that's what this line is about so we're doing an optional with nullable on the page if the page is null then this becomes zero if it's provided then it becomes whatever number been provided on the rest API and that gets passed into get books so quite simply get the page number from the rest API if it exists if not default to page zero and then pass that to our service layer book service.give books with that page number and that's going to return us our flocks of books and we get to display that that's most what we need to do but we haven't made our web client available to our application remembering that in the client the books client import here we're Auto wiring the web client but it has to be in our spring context to begin with and we also saw here that we're not specifying the host of the web client we do that in our configuration let's go up to our configuration let's create a new file up here and I'm going to call this one webclient config.java okay and we need to put configuration on this class to tell spring that this is where it should look for configuration beans and the bean that we want to make available remembering a bean is an object that can be placed into the spring context so we use the bean annotation for that and the type that we want to make available is the web client and we create one super easily so we do web client dot create and then this is where we specify our host which in this case is HTTP localhost and it's running on Port 8181 so that is the address or the the host hosting Port I suppose for the server application that's currently running what we've got here is create a web client using the base host Port of localhost 8181 so whatever we call endpoint wise it's always going to hit that server and return that web client where it needs to be injected that should be everything that we need to do to this client application to use the web client to call the server application so what we'll do is start up this application which we can do from the terminal here we'll call the maven wrapper which is this one over here and we're going to say spring boot run so you'll notice that this is a little bit different from what we've seen in previous tutorials because we aren't using Tomcat we're using Nettie still running a port 8080 but it is a different application container entirely this is the non-blocking one whereas Tomcat is the blocking one so it's running let's try it out let's go over to postman so this is our server application let's just hit this endpoint to make sure it's still running looking good let's now call our client application so change the port to 8080 we still have forward slash books as our endpoint but we're expecting to get back is a HTTP 200 but it will just be a list of books there will be none of this extra pagination metadata it'll just be a list of books the first one being the shadow in the Attic by Abigail Rose so let's send this and see what we get back fantastic that was quick here's our list of books the shadow in the Attic Abigail Rose Beyond the Horizon it's all looking good let's just take a look at the server logs to see what they look like because our server lovers are set up to show every request so these are logs for the server here and we can see that we've got a HTTP 200 we are just getting a single request of forward slash books page number zero size 20. so all of the default stuff let's make a call to our client with a different page number which we can do by doing page equals tools too we're getting the same books back reason for that is we haven't passed in the query parameters to our web client let's fix that so back in the web client we've changed the four slash books which is a straightforward string inside of your eye two this nice little Builder pattern here so we're able to get hold of the Builder and then call Path on it which is still forward slash books but this time around we can actually pass in the query parameter which is Page using the page integer that is passed in to the method that should allow us to do our page pagination a pagination so let's restart the application and see it working hopefully super quick restart back to postman okay here we go we've got here the shadow in the Attic we know that to be the book from page one even though we specified page two in the URL so we can hit this again and hopefully this should give us a different set of books those for page two and we'll double check that in the logs this time so let's click Send the Dragon's Lair the secret society The Vanishing Village looking good let's do page three just to make triply sure the seventh hour The Missing Link because Wood's looking good let's look at the logs for our server over there we go page request number zero page request number two page request number three so the pages are now being passed through to the server from the client looking good so I'm not for one moment gonna pretend to be the expert on the spring reactive way doing things it's all right there's definitely some Concepts in there which uh new and perhaps a little bit different from what you might be used to so the concept of a flux a concept of a mono yet they kind of have parallels with the stream and the optional but they're its own thing entirely the magic behind this of course is if you're dealing with loads of streaming data you're just in a world where it needs to be just like the quickest it possibly could be then this could be a really really good solution for you and it's certainly the most modern I would argue that actually the more traditional way of doing things is simpler but I just wonder if that will change over time as this sort of stuff just becomes more of the norm so as per usual I'm just going to commit this pushes them up to GitHub so you can get hold of this code and you can play with it yourself and there we go we've managed you use the reactive web client to call a rest API from a spring boot application is it the most optimal implementation probably not so if you have some suggestions on how to improve it I'd love to hear them please leave those in the comments below now if you want to kind of contrast this to the more traditional way of doing things and I totally recommend that you do check out this tutorial where we build a rest API completely from scratch in Spring boot but this one using spring web spring MVC the traditional stack I'll see you over there
Info
Channel: Devtiro
Views: 5,302
Rating: undefined out of 5
Keywords:
Id: SN2ApMA-CGk
Channel Id: undefined
Length: 18min 48sec (1128 seconds)
Published: Sun Apr 02 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.