Implementing pagination | ASP.NET Core 5 REST API Tutorial 26

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody I'm Anika I'm gonna show you how you can start using pagination your REST API in a speedloader color the approach we're gonna go with is very simple the many ways to go about it but I'm gonna go with a simplest and it's usable as much as any other method well one explain is why do we need pagination the reason is quite simple we don't want to return everything in a single response when it comes to response with multiple items in the response because the response can be huge and if you have like thousands tens of thousands of requests in a single response that's a lot of data going over the wire and you might not want to allow the users to do that so instead of returning everything in the single response you might want to return them in essentially pages so what you see in any website that has any sort of pagination REST API work very much in the same way the first thing I need to do in this approach is to create two classes and these will go in the contracts the first one in the create is called a response or it could be called API responsible I'm gonna go with response because this is an API so it's implied and the way I wanted to look like is I want to have a generic type T parameter and then I want you to have a parameterless constructor and one that accepts this T data or in fact the best name is T response and we are going to have this property here called data so data equals response and with this response we are going to wrap all the things where we turn in our API so instead of returning the object itself so in this scenario if I go to the post controller instead of returning a list of response or post response or any of that I'm going to turn a response that contains that and let me just quickly do that and show you what I mean so we're going to say new response and the type is this type here and here we go and we need to do the same for all the other things returning except the errors this is only valid for the good responses so here we go in fact I can actually copy that here and I think it's the same across the other things that return a response so yeah and also how this is created so I don't copy the whole thing I'll just copy this bit so now everything in our API is returned into this object let me run this and show you how this looks like so here I have our API and I'm already of indicated so if I just return now all the posts you will see that they returned into a top-level data object and that is the same with any other response in this controller and I will do the same for the tax controller as well now why did we do that we did that because now let's say I want to add some other metadata stuff in the response I can do this in this very top level without actually affecting the response contract itself so people that need to use this will just pass this data object as our response object and then they can get other things from the top level and this will become more clear and why we're gonna do this now that I'm going to actually add that paged response so we need to create another class as well again in the contracts and this will be called page response I've seen people inheriting in the contracts I think that's a very bad idea let me just stop running this because you're coupling your contracts with each other and if you change the one like the base one you might accidentally have a knock-on effect on the rest so I recommend not doing that again we're gonna have a parameterless constructor because our SDK will need to use this and it won't be able to use the constructor to deserialize automatically and then I'm going to create this constructor but I'm gonna use an ienumerable here of T because a page results implies that we have many items in the response not a single one so we have the data here and again I'm going to make the same eye a numerable of T here and I'm gonna call it theta again I'm gonna say theta equals theta here but on top of that I'm going to add a few other properties and these will be an int which is nullable called page number another intern a label called page size a string called next page and now the string called previous page now we have this class we can actually take it and use it in this one case where we return many responses so many posts and this would look something like this page response of post response so now we have this base response which also has all these other values in the response so if I run this again and I execute this again you can see scrolling down that we have this null of vidas here and there null because we're not actually setting them what we need to do at this point is add to query string parameters page number and paid signs this will indicate which page we're retrieving and when we do that we will get the page number of the page size and the response and we're also gonna get the pointer to the next page and to the previous page so the SDK the client that's using this can actually do pagination in the front-end so let's see how we can do that the first thing I need to do is I'm going to create a page nation query so I'm gonna go to the request and I'm gonna create a new folder and I'm going to call that query and in there I'm gonna create a query clause and that will be called pagination query and it's gonna have a constructor and we'll see what will go in here in fact we will actually have two constructors we will need two properties we will need an integer named page number and we're gonna need another integer called page size and in here one of them will just set those values so page number and page size but the other one we will just default it to some values and these will be page number equals one so we always by default when I get this first page and page size and here you need to default to a value that you deem acceptable I'm gonna go with a hundred this is specific to you your case if you can handle it more you might want to default it to more and you might also want to limit them to here so say something like if this is more than a hundred then return a hundred because you don't want them to just say give me a million results back that's up to you but here's how you can just default it so with this pagination of query now in here I can actually go to the controller and they get all end point and dew from query and use this class pagination query and then just call pagination query and if I import it now don't let go is smart enough to actually recognize these two values by name page number and page size and allow me to specify them in here at this point since this is a contract I actually need to create an equivalent domain object to actually map this contract too so we'll go to domain I will create a new class and I will name this class pagination filter and this class will have two properties and page number and ain't page signs so we've created I'm going to go ahead and create a mapping profile and this mapping profile will be from request domain so I'm going to create a new class because that doesn't exist so request to domain profile and this will need to extend the profile class and in the constructor I'll need to say create map and we are mapping from the pagination query to the page nation filter and that's what we need to do so in the post controller now I'm going to split this up a little bit to make it a bit more readable we have our posts response which is mapped to that object and then here we will have our vegetation response equals this and I'm gonna copy that mapped value from this to this and return it here so roughly this is what this should look like but at this point we will need to pass our filter to this get post sizing method the way to do that is we're gonna do a pagination filter cloth and we're gonna say map or map and we're gonna map this fella here to the pagination filter we just mapped in the profile and we are going to pass that down to this method now currently does not accept it but we're gonna make it accept it so pagination filter now that it's a domain object and we are going to add this in the implementation of this class as well this goes here and the way to implement this with anteye framework is very very simple the first thing I want to do is I want to say if pagination filter equals null because it could be null and in fact let's just make it nullable by default and I'm gonna add that in the interface as well that we just gonna return everything this will never be the case because we already said the value higher up but let's just do it like this so if it's not just return everything what we need to calculate is how much in the future to skip based on the pagination configuration so I'm going to say pagination filter dot page number minus one x pagination filter dot paid science this is a formula to calculate how far we need to skip how many documents we need to skip how many files we need to keep in the database and all we need to do is just say dot skip this keep amount and then just take the paid sighs so pagination filter trade size and this is all the database that we need to do for our pagination so being done with this service and closing all these others it would be a fairly straightforward just at this point just return so in here I have a paginated response I have the posts I could set all the page number of page whatever in here and that'll be all fine but we also want to set the euro riotous so the URLs to the next and the previous page and this is just a nice feature to have when you design a REST API because you make it very easy for the consumer to use so what I'm gonna do here is I'm gonna create a new service and this service will be called a URI service the responsibility of this service let me just turn this into an interface there's possibility of this service is solely to just generate you arise from our API for different purposes I'm going to create two of them I'm gonna create one for the get post by ID endpoint and one for they get all posts endpoint and I'll show you why I'm gonna create both of them so the first one will be a URI get post URI and here we accept outsid and the other one is your I get all costs you right and in here we accept the pagination of query which defaults to null because you might not have it at this point I'm going to create the implementation of this interface so we're gonna say i uri service and we're gonna implement the missing members i'm gonna add a constructor here because what we do need is to have a private reading lee string which we represent the base URI of our API cuz remember our API URI differs based on where we run it it can be localhost and can be on a different domain name it can be on so many names you want this to be dynamic you don't want to hard code it so I'm gonna inject it and I'm gonna set it during the I so I'm gonna say base you're right here and I'm just gonna set it to base your I equals base you're right and let me show show you what we're doing in this post controller we have this created location if you're writing now this is too much for the controller to know to generate it like ideally you wouldn't want to have this here and in fact that's what we're actually gonna replace first we're gonna say read-only I your I service and we're just gonna inject through the constructor and I'm gonna get that and I'm going to say but the location you're right I'm going to comment these two things out and I'm gonna say that the location you're our equals your I serve I still get positive you're right and then we just gonna say post dot ID dot to string and then this service will do all this for us we don't need to have it here I can just delete it how will this method look like it's just implemented I'll show you it's simply one line we're just gonna say return new uri base your i + api routes dot costs dot get dot replace and we're gonna replace the token in here so i'm gonna replace the post ID which is part of the uri with the cost ideal and that's it and now we have a thing that can generate this uri for that endpoint you can make one method parent point here for simplicity and for minimization and just gonna create what i need but you could create one for each now the pagination one is a bit more complicated because we have this pagination query thing but it's still fairly simply first we need a URI which is the base URI and then we're going to check if pagination equals null then at this point just return the yeren because there's no query string if not we're gonna modify it and we're gonna say modified your I equals and we're gonna use the query help us class which is part of dotted course so query help us dot add query string and we need to add it to the base you write the name is page number and the values pagination dot page number two string and then I also need to modify it again and I'm gonna say again query helpers add query string we're adding it to the modified here I this time let me just scroll this up so you can see and it's paid size and then pagination dot paid signs dot to string so here we go and we're just gonna say return new uri modified you're right I'm sure they're cleaner ways to do this but just let's do it like this for now so we have something that can generate this you're right based on the pagination filter which is awesome because we are actually going to use it now to generate the next in previous your eyes the way to do this is very very easy so let's see what we got here we had we have the pagination filter we have the posts and what we want to do now is we're gonna say if pagination filter equals null or pagination filter dot page number is less than one or pagination filter dot page size is less than one so if any of these values essentially is invalid because there's no - page and there's no - size then at this point we're just gonna say return and let me just move those a little bit up at this point we can just say return ok new page response of post response of post response I know that sounds weird but we're just returning these this list of post responses in a single page response but if that's not the case then we're gonna do some magic here we first want to calculate the next page so the next page equals pagination filter in fact we just rename this pagination filter to simply pagination because it's too long to show in this video so pagination dot page number is equal or more than one then the UI service dot get all cost you writing and then the query we're going to use is pagination dot paid number plus one because we want to get the next bite so we're gonna say what we have now plus one and then the page size is the equal size we already have Alice just not so this is the next page and we are going to do the same for the previous page but we're gonna subtract one so can just copy this I can just say previous page if page number minus one is more than one because you don't want to go negative or zero then page number combined someone paid sighs and we also need to just to string this because the metal will accept string and now we have our previous and our next and we can use that to create a new page response with all those values so what we'll do is we can say create a new page response just scroll up we can say data equals the object is the post response the page number is the page nation number which is it equal or more than one if it is then use it else return none but because this is an integer inaudible integer and specify that same for the page size repeat size is pagination dot page size is it more or equal to 1 then pagination the page size adds another int then we have the next page and we can say does the post response have any objects in it because if it doesn't then there is no other page in the future else just next byte so let's see how this reads do we have any objects in here if we do give me the next page if not return null because there's no next page and the previous page is just the previous page now you can actually tell that this is a bit of like too much code for this what I'm going to do is I'm going to create a new folder named help and we're gonna add a new class in here and I'm gonna call it pagination first and I'm gonna move all this logic in there pagination building and all that can actually all go here so we just copy this I would expect it to look something like this pagination response equals pagination helpers dot create paginated to response I'm hoping this is valid English and then this accepts the Euro service the pagination itself and the first response and let's just create this method automatically and we have our a service or filter and this now this I can actually be generic so let me just taste what we copied here and replace as much as we can I don't want to make this specific to they the post response come before any type of object so for that reason I'm gonna change this to a generic T parameter and I'm gonna add the generic T parameter here so we can just say any type of response can go here and rename this to response and now we have our method here of course we need to actually return as well so return I can just put in here I don't need to allocate the object here we go so we have our object and this object is in fact a paginated response of t this looks way way much cleaner so that is a small thing I need to do and that is in the startup in the configuration I'm gonna go to the MVC installer and I'm gonna add the initializer for the US service so add singleton your i in fact i euro service and I'm gonna instantiate this and don't get intimidated it's actually fairly simple what we're gonna do here first we need the HDP context accessor to get the car request so this equals provider dot get required service I ate the DP context accessor then we need the request itself and this is coming from the accessor dot X deep context dot request then from the request when you to get the absolute you arrived and we're gonna concatenate a few strings here now we're gonna say request the scheme and then we're gonna add the these characters which is part like this is saying HTTP or HTTPS and then these characters and then the rest of it is a request dot host dot to you write component and we just gonna add the folks last at the end and we're gonna return a new uri service with this absolute URI as the base you're right and this will guarantee that the URL that the user used to call us is what we get in their response whenever the URI service is actually used so let's just see how all these hangs together let me just run this and show you what we did so I'm now CENTAC eight this year so if I rather try to get all the post you'll see that we have two parameters if I ignore them and I just say execute I'm getting by default everything but it looks like everything it's really first page a hundred items but if I go now and say give me page one and page eight every five objects then I can execute this and I can get exactly one two three four five and then it tells me that here's the first page first sighs here's a URL you need to call to get the next one so if I do that as you can see we skip the first posts and now we're here again second page number five page size and there's another one and there's a previous one and so on and so forth you can configure this even more if you want but now we have this data object that has all these values and then we also have all our pagination data of course I will change the SDK to reflect those changes you find the code down below for that I won't show this in the video because it's long enough already this is all the has for this video for you you never liked if you liked this video subscribe for more content like this and i'll see you in the next video keep coding you
Info
Channel: Nick Chapsas
Views: 38,759
Rating: undefined out of 5
Keywords: Elfocrash, elfo, coding, asp.net, .netcore, dot net, core, C#, how to code, tutorial, asp.net core, javascript, js, 2.2, csharp, rest, rest api, development, lesson, software engineering, dev, microsoft, microsoft mvp, .net core, nick chapsas, chapsas, asp.net core 3, pagination, asp.net pagination, rest api pagination, dotnet, .net
Id: cKj6U4qDmgQ
Channel Id: undefined
Length: 26min 10sec (1570 seconds)
Published: Tue Sep 03 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.