A simple way to iterate over paginated reponse Http4s

486 views Asked by At

I'm trying to handle pagination without using string interpolation and also take advantage of http4s features. I have came across the OptionalQueryParamDecoderMatcherand I don't know if it is a good match in my use case. So the response contain header that has information about the number of pages in the Link attribute It has rel set to prev, next, first, or last. as follows :

<https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="prev", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="next", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=1&per_page=3>; rel="first", <https://gitlab.example.com/api/v4/projects/8/issues/8/notes?page=3&per_page=3>; rel="last"

My idea is to get the number of pages specified as last (which is the total number of pages) and then increment by one to get all the results. The first way I thought about is string interpolation, but I believe that there would be a much simpler way to do it especially taking advantage of http4s.

Can someone enlighten me ? I'm open to your suggestions.

note: the httpRoute is specified as this example :

 val routes   = HttpRoutes.of[IO] {
      case GET -> Root /"projects"/project_name/"Details"
}
1

There are 1 answers

1
Mateusz Kubuszok On BEST ANSWER

As described in documentation you can use query matchers to extract data from query.

object Page extends OptionalQueryParamDecoderMatcher[Int]("page")
object PerPage extends OptionalQueryParamDecoderMatcher[Int]("per_page")

val routes = HttpRoutes.of[IO] {
  case GET -> Root / "projects" / project_name / "Details" :? Page(page) :? PerPage(perPage) =>
    ...
}

OptionalQueryParamDecoderMatcherand is indeed the right usage here.

(Personally, I prefer to define API using something like Tapir or Endpoint4s (I find it saner for many reasons) and then interpret it into HTTP4s. It's a very simple way of avoiding many idiosyncrasies of HTTP4s or Akka HTTP).