Liking cljdoc? Tell your friends :D

wagoe.platform.shell.pagination.link-headers

Shell layer RFC 5988 Link header generation for pagination.

RFC 5988: Web Linking https://datatracker.ietf.org/doc/html/rfc5988

SIDE EFFECTS:

  • String building and URL encoding
  • Logging

Link headers provide hypermedia controls for pagination navigation. They allow clients to discover next, prev, first, and last pages without parsing response bodies.

Format: Link: </api/v1/users?limit=20&offset=20>; rel="next", </api/v1/users?limit=20&offset=0>; rel="first", </api/v1/users?limit=20&offset=980>; rel="last"

Supported Relations:

  • first: First page of results
  • last: Last page of results (offset pagination only)
  • prev: Previous page
  • next: Next page
  • self: Current page
Shell layer RFC 5988 Link header generation for pagination.

RFC 5988: Web Linking
https://datatracker.ietf.org/doc/html/rfc5988

SIDE EFFECTS:
- String building and URL encoding
- Logging

Link headers provide hypermedia controls for pagination navigation.
They allow clients to discover next, prev, first, and last pages without
parsing response bodies.

Format:
Link: </api/v1/users?limit=20&offset=20>; rel="next",
      </api/v1/users?limit=20&offset=0>; rel="first",
      </api/v1/users?limit=20&offset=980>; rel="last"

Supported Relations:
- first: First page of results
- last: Last page of results (offset pagination only)
- prev: Previous page
- next: Next page
- self: Current page
raw docstring

(build-cursor-links base-path params pagination-meta)

Build link data for cursor-based pagination.

Generates URLs for prev, next, and self relations based on cursor pagination metadata. Note: first and last are not available with cursor pagination (would require scanning entire dataset).

Args: base-path - Base URL path (e.g., "/api/v1/users") params - Current query parameters (map) pagination-meta - Cursor pagination metadata with keys: :limit - Items per page :has-next - Boolean indicating if next page exists :has-prev - Boolean indicating if previous page exists :next-cursor - Cursor for next page (if has-next) :prev-cursor - Cursor for previous page (if has-prev)

Returns: Vector of link data maps [{:url ... :rel ...} ...]

Side Effects:

  • URL building
  • Logging

Example: (build-cursor-links "/api/v1/users" {:limit 20 :cursor "eyJ..." :sort "name"} {:limit 20 :has-next true :has-prev true :next-cursor "eyJpZCI6IjEyMyI..." :prev-cursor "eyJpZCI6IjQ1NiI..."}) ;;=> [{:url "/api/v1/users?limit=20&cursor=eyJpZCI6IjQ1NiI...&sort=name" :rel :prev} ;; {:url "/api/v1/users?limit=20&cursor=eyJ...&sort=name" :rel :self} ;; {:url "/api/v1/users?limit=20&cursor=eyJpZCI6IjEyMyI...&sort=name" :rel :next}]

Build link data for cursor-based pagination.

Generates URLs for prev, next, and self relations based on cursor pagination
metadata. Note: first and last are not available with cursor pagination
(would require scanning entire dataset).

Args:
  base-path - Base URL path (e.g., "/api/v1/users")
  params - Current query parameters (map)
  pagination-meta - Cursor pagination metadata with keys:
    :limit - Items per page
    :has-next - Boolean indicating if next page exists
    :has-prev - Boolean indicating if previous page exists
    :next-cursor - Cursor for next page (if has-next)
    :prev-cursor - Cursor for previous page (if has-prev)
    
Returns:
  Vector of link data maps [{:url ... :rel ...} ...]
  
Side Effects:
  - URL building
  - Logging
  
Example:
  (build-cursor-links
    "/api/v1/users"
    {:limit 20 :cursor "eyJ..." :sort "name"}
    {:limit 20
     :has-next true
     :has-prev true
     :next-cursor "eyJpZCI6IjEyMyI..."
     :prev-cursor "eyJpZCI6IjQ1NiI..."})
  ;;=> [{:url "/api/v1/users?limit=20&cursor=eyJpZCI6IjQ1NiI...&sort=name" :rel :prev}
  ;;    {:url "/api/v1/users?limit=20&cursor=eyJ...&sort=name" :rel :self}
  ;;    {:url "/api/v1/users?limit=20&cursor=eyJpZCI6IjEyMyI...&sort=name" :rel :next}]
sourceraw docstring

(build-link-header links)

Build RFC 5988 Link header string from link data.

Takes a collection of link entries and produces a single Link header value with multiple relations.

Args: links - Collection of maps with :url and :rel keys :url - Full URL for the link :rel - Relation type (:first, :last, :prev, :next, :self)

Returns: RFC 5988 Link header string

Side Effects:

  • String building
  • Logging

Example: (build-link-header [{:url "/api/v1/users?offset=0&limit=20" :rel :first} {:url "/api/v1/users?offset=20&limit=20" :rel :next} {:url "/api/v1/users?offset=980&limit=20" :rel :last}]) ;;=> "</api/v1/users?offset=0&limit=20>; rel="first", </api/v1/users?offset=20&limit=20>; rel="next", </api/v1/users?offset=980&limit=20>; rel="last""

Returns: nil if links collection is empty

Build RFC 5988 Link header string from link data.

Takes a collection of link entries and produces a single Link header value
with multiple relations.

Args:
  links - Collection of maps with :url and :rel keys
    :url - Full URL for the link
    :rel - Relation type (:first, :last, :prev, :next, :self)
    
Returns:
  RFC 5988 Link header string
  
Side Effects:
  - String building
  - Logging
  
Example:
  (build-link-header
    [{:url "/api/v1/users?offset=0&limit=20" :rel :first}
     {:url "/api/v1/users?offset=20&limit=20" :rel :next}
     {:url "/api/v1/users?offset=980&limit=20" :rel :last}])
  ;;=> "</api/v1/users?offset=0&limit=20>; rel=\"first\", </api/v1/users?offset=20&limit=20>; rel=\"next\", </api/v1/users?offset=980&limit=20>; rel=\"last\""
  
Returns:
  nil if links collection is empty
sourceraw docstring

(build-offset-links base-path params pagination-meta)

Build link data for offset-based pagination.

Generates URLs for first, last, prev, next, and self relations based on offset pagination metadata.

Args: base-path - Base URL path (e.g., "/api/v1/users") params - Current query parameters (map) pagination-meta - Offset pagination metadata with keys: :total - Total number of items :offset - Current offset :limit - Items per page :has-next - Boolean indicating if next page exists :has-prev - Boolean indicating if previous page exists :next-offset - Offset for next page (if has-next) :prev-offset - Offset for previous page (if has-prev)

Returns: Vector of link data maps [{:url ... :rel ...} ...]

Side Effects:

  • URL building
  • Logging

Example: (build-offset-links "/api/v1/users" {:limit 20 :offset 40 :sort "name"} {:total 100 :offset 40 :limit 20 :has-next true :has-prev true :next-offset 60 :prev-offset 20 :total-pages 5 :current-page 3}) ;;=> [{:url "/api/v1/users?limit=20&offset=0&sort=name" :rel :first} ;; {:url "/api/v1/users?limit=20&offset=20&sort=name" :rel :prev} ;; {:url "/api/v1/users?limit=20&offset=40&sort=name" :rel :self} ;; {:url "/api/v1/users?limit=20&offset=60&sort=name" :rel :next} ;; {:url "/api/v1/users?limit=20&offset=80&sort=name" :rel :last}]

Build link data for offset-based pagination.

Generates URLs for first, last, prev, next, and self relations based on
offset pagination metadata.

Args:
  base-path - Base URL path (e.g., "/api/v1/users")
  params - Current query parameters (map)
  pagination-meta - Offset pagination metadata with keys:
    :total - Total number of items
    :offset - Current offset
    :limit - Items per page
    :has-next - Boolean indicating if next page exists
    :has-prev - Boolean indicating if previous page exists
    :next-offset - Offset for next page (if has-next)
    :prev-offset - Offset for previous page (if has-prev)
    
Returns:
  Vector of link data maps [{:url ... :rel ...} ...]
  
Side Effects:
  - URL building
  - Logging
  
Example:
  (build-offset-links
    "/api/v1/users"
    {:limit 20 :offset 40 :sort "name"}
    {:total 100
     :offset 40
     :limit 20
     :has-next true
     :has-prev true
     :next-offset 60
     :prev-offset 20
     :total-pages 5
     :current-page 3})
  ;;=> [{:url "/api/v1/users?limit=20&offset=0&sort=name" :rel :first}
  ;;    {:url "/api/v1/users?limit=20&offset=20&sort=name" :rel :prev}
  ;;    {:url "/api/v1/users?limit=20&offset=40&sort=name" :rel :self}
  ;;    {:url "/api/v1/users?limit=20&offset=60&sort=name" :rel :next}
  ;;    {:url "/api/v1/users?limit=20&offset=80&sort=name" :rel :last}]
sourceraw docstring

build-query-stringclj

(build-query-string params)

Build URL query string from parameters map.

Filters out nil values and URL-encodes parameter values.

Args: params - Map of query parameters

Returns: Query string (without leading '?')

Side Effects:

  • URL encoding
  • String building

Example: (build-query-string {:limit 20 :offset 40 :sort "name"}) ;;=> "limit=20&offset=40&sort=name"

(build-query-string {:limit 20 :offset nil}) ;;=> "limit=20"

Build URL query string from parameters map.

Filters out nil values and URL-encodes parameter values.

Args:
  params - Map of query parameters
  
Returns:
  Query string (without leading '?')
  
Side Effects:
  - URL encoding
  - String building
  
Example:
  (build-query-string {:limit 20 :offset 40 :sort "name"})
  ;;=> "limit=20&offset=40&sort=name"
  
  (build-query-string {:limit 20 :offset nil})
  ;;=> "limit=20"
sourceraw docstring

build-urlclj

(build-url base-path params)

Build full URL from base path and query parameters.

Args: base-path - Base URL path (e.g., "/api/v1/users") params - Map of query parameters

Returns: Full URL with query string

Side Effects:

  • URL encoding (via build-query-string)
  • String building

Example: (build-url "/api/v1/users" {:limit 20 :offset 40}) ;;=> "/api/v1/users?limit=20&offset=40"

(build-url "/api/v1/users" {}) ;;=> "/api/v1/users"

Build full URL from base path and query parameters.

Args:
  base-path - Base URL path (e.g., "/api/v1/users")
  params - Map of query parameters
  
Returns:
  Full URL with query string
  
Side Effects:
  - URL encoding (via build-query-string)
  - String building
  
Example:
  (build-url "/api/v1/users" {:limit 20 :offset 40})
  ;;=> "/api/v1/users?limit=20&offset=40"
  
  (build-url "/api/v1/users" {})
  ;;=> "/api/v1/users"
sourceraw docstring

(generate-link-header base-path params pagination-meta)

Generate RFC 5988 Link header for pagination response.

Automatically detects pagination type (offset or cursor) and generates appropriate links.

Args: base-path - Base URL path (e.g., "/api/v1/users") params - Current query parameters (map) pagination-meta - Pagination metadata (either offset or cursor type) Must have :type key with value "offset" or "cursor"

Returns: RFC 5988 Link header string, or nil if links are empty

Side Effects:

  • Link building (URL construction, string building)
  • Logging

Example (offset): (generate-link-header "/api/v1/users" {:limit 20 :offset 40} {:type "offset" :total 100 :offset 40 :limit 20 :has-next true :has-prev true :next-offset 60 :prev-offset 20}) ;;=> "</api/v1/users?limit=20&offset=0>; rel="first", ..."

Example (cursor): (generate-link-header "/api/v1/users" {:limit 20 :cursor "eyJ..."} {:type "cursor" :limit 20 :has-next true :next-cursor "eyJpZCI..."}) ;;=> "</api/v1/users?limit=20&cursor=eyJpZCI...>; rel="next", ..."

Generate RFC 5988 Link header for pagination response.

Automatically detects pagination type (offset or cursor) and generates
appropriate links.

Args:
  base-path - Base URL path (e.g., "/api/v1/users")
  params - Current query parameters (map)
  pagination-meta - Pagination metadata (either offset or cursor type)
    Must have :type key with value "offset" or "cursor"
    
Returns:
  RFC 5988 Link header string, or nil if links are empty
  
Side Effects:
  - Link building (URL construction, string building)
  - Logging
  
Example (offset):
  (generate-link-header
    "/api/v1/users"
    {:limit 20 :offset 40}
    {:type "offset"
     :total 100
     :offset 40
     :limit 20
     :has-next true
     :has-prev true
     :next-offset 60
     :prev-offset 20})
  ;;=> "</api/v1/users?limit=20&offset=0>; rel=\"first\", ..."
  
Example (cursor):
  (generate-link-header
    "/api/v1/users"
    {:limit 20 :cursor "eyJ..."}
    {:type "cursor"
     :limit 20
     :has-next true
     :next-cursor "eyJpZCI..."})
  ;;=> "</api/v1/users?limit=20&cursor=eyJpZCI...>; rel=\"next\", ..."
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close