Reputation: 822
I need to create HATEOAS pagination links for first, last, next, and previous and add them to the Link
header of the response.
A PagedResultDTO
is returned from the application layer to the controller in the API layer. Besids the records it holds information about TotalCount
, PageNumber
, PageSize
, and PageCount
.
I'm confused with the options provided by the framework. Many posts use UriHelper
, but it seems that LinkGenerator
is the newer and the current helper class. Looking at the documentation I don't understand the difference of the various methods that LinkGenerator
provides. Is there any good post that explains the use cases for the various methods?
Since a request can have various other query parameters e.g. for sorting, filtering, searching, embedding they need to be kept and returned when the links get created. E.g. a controller declaration can look like:
public ActionResult<PagedResultDTO<GetCountriesDTO>> GetCountries(
[FromHeader(Name = "If-None-Match")] string? eTags,
[CommaSeparated] IEnumerable<string> languages,
string? sort,
string? search,
int? pageNumber,
int? pageSize)
([CommaSeperated]
is an extension that accepts multiple values separated by comma and creates a List without having to repeat the query parameter. If pageNumber and pageCount are not set and don't have default values set in a specific controller method my use case handlers will set default values.)
For a request like:
GET https://example.com/api/countries?languages=de-DE,en-US&sort=name
I need to generate:
<https://example.com/api/countries?languages=de-DE,en-US&sort=name&pageNumber=2&pageSize=20>; rel="next",
<https://example.com/api/countries?languages=de-DE,en-US&sort=name&pageNumber=1&pageSize=20>; rel="first",
<https://example.com/api/countries?languages=de-DE,en-US&sort=name&pageNumber=10&pageSize=20>; rel="last"
All query parameters not related to paging need to be kept in the generated links. Does LinkGenerator
support a straightforward way to generate those pagination links? Is there any structure that supports the Link
header format already? I wonder if should just create the links manually using the Request
object?
Upvotes: 0
Views: 903
Reputation: 822
I created now my own code using a dictionary that holds the passed query parameters.
Dictionary<string, string> query = new();
foreach (KeyValuePair<string, StringValues> item in httpContext.Request.Query)
{
query.Add(item.Key, string.Join(",", item.Value));
}
I then update pageNumber
and pageSize
for each link. If it was not set before and defaults are used the parameters are added, e.g.:
query["pageNumber"] = "1";
query["pageSize"] = pageSize.ToString();
I then use LinkGenerator
to create the link:
linkGenerator.GetUriByAction(httpContext, values: query)
Upvotes: 1