Skip to main content

Registration Data Access Protocol (RDAP) Query Parameters for Result Sorting and Paging
RFC 8977

Document Type RFC - Proposed Standard (January 2021)
Authors Mario Loffredo , Maurizio Martinelli , Scott Hollenbeck
Last updated 2021-01-22
RFC stream Internet Engineering Task Force (IETF)
Formats
Additional resources Mailing list discussion
IESG Responsible AD Barry Leiba
Send notices to (None)
RFC 8977
quot;seconds";
           description
             "The minimum time allowed between sending unsolicited
              multicast Router Advertisements from the interface.";
         }
         leaf managed-flag {
           type boolean;
           description
             "The value that is placed in the 'Managed address
              configuration' flag field in the Router Advertisement.";
         }
         leaf other-config-flag {
           type boolean;
           description
             "The value that is placed in the 'Other configuration' flag
              field in the Router Advertisement.";
         }
         leaf link-mtu {
           type uint32;
           description
             "The value that is placed in MTU options sent by the
              router. A value of zero indicates that no MTU options are
              sent.";
         }
         leaf reachable-time {
           type uint32 {
             range "0..3600000";
           }
           units "milliseconds";
           description
             "The value that is placed in the Reachable Time field in
              the Router Advertisement messages sent by the router. A
              value of zero means unspecified (by this router).";
         }
         leaf retrans-timer {
           type uint32;
           units "milliseconds";
           description
             "The value that is placed in the Retrans Timer field in the

Lhotka & Lindem         Expires November 26, 2015              [Page 36]
Internet-Draft           YANG Routing Management                May 2015

              Router Advertisement messages sent by the router. A value
              of zero means unspecified (by this router).";
         }
         leaf cur-hop-limit {
           type uint8;
           description
             "The value that is placed in the Cur Hop Limit field in the
              Router Advertisement messages sent by the router. A value
              of zero means unspecified (by this router).";
         }
         leaf default-lifetime {
           type uint16 {
             range "0..9000";
           }
           units "seconds";
           description
             "The value that is placed in the Router Lifetime field of
              Router Advertisements sent from the interface, in seconds.
              A value of zero indicates that the router is not to be
              used as a default router.";
         }
         container prefix-list {
           description
             "A list of prefixes that are placed in Prefix Information
              options in Router Advertisement messages sent from the
              interface.

              By default, these are all prefixes that the router
              advertises via routing protocols as being on-link for the
              interface from which the advertisement is sent.";
           list prefix {
             key "prefix-spec";
             description
               "Advertised prefix entry and its parameters.";
             leaf prefix-spec {
               type inet:ipv6-prefix;
               description
                 "IPv6 address prefix.";
             }
             leaf valid-lifetime {
               type uint32;
               units "seconds";
               description
                 "The value that is placed in the Valid Lifetime in the
                  Prefix Information option. The designated value of all
                  1's (0xffffffff) represents infinity.

                  An implementation SHOULD keep this value constant in

Lhotka & Lindem         Expires November 26, 2015              [Page 37]
Internet-Draft           YANG Routing Management                May 2015

                  consecutive advertisements except when it is
                  explicitly changed in configuration.";
             }
             leaf on-link-flag {
               type boolean;
               description
                 "The value that is placed in the on-link flag ('L-bit')
                  field in the Prefix Information option.";
             }
             leaf preferred-lifetime {
               type uint32;
               units "seconds";
               description
                 "The value that is placed in the Preferred Lifetime in
                  the Prefix Information option, in seconds. The
                  designated value of all 1's (0xffffffff) represents
                  infinity.

                  An implementation SHOULD keep this value constant in
                  consecutive advertisements except when it is
                  explicitly changed in configuration.";
             }
             leaf autonomous-flag {
               type boolean;
               description
                 "The value that is placed in the Autonomous Flag field
                  in the Prefix Information option.";
             }
           }
         }
       }
     }

     augment "/rt:routing-state/rt:routing-instance/rt:ribs/rt:rib/"
           + "rt:routes/rt:route" {
       when "../../rt:address-family = 'v6ur:ipv6-unicast'" {
         description
           "This augment is valid only for IPv6 unicast.";
       }
       description
         "This leaf augments an IPv6 unicast route.";
       leaf destination-prefix {
         type inet:ipv6-prefix;
         description
           "IPv6 destination prefix.";
       }
     }

Lhotka & Lindem         Expires November 26, 2015              [Page 38]
Internet-Draft           YANG Routing Management                May 2015

     augment "/rt:routing-state/rt:routing-instance/rt:ribs/rt:rib/"
           + "rt:routes/rt:route/rt:next-hop/rt:next-hop-options/"
           + "rt:simple-next-hop" {
       when "../../../rt:address-family = 'v6ur:ipv6-unicast'" {
         description
           "This augment is valid only for IPv6 unicast.";
       }
       description
         "This leaf augments the 'simple-next-hop' case of IPv6 unicast
          routes.";
       leaf next-hop-address {
         type inet:ipv6-address;
         description
           "IPv6 address of the next-hop.";
       }
     }

     /* Configuration data */

     augment "/if:interfaces/if:interface/ip:ipv6" {
       description
         "Augment interface configuration with IPv6-specific parameters
          of router interfaces.";
       container ipv6-router-advertisements {
         description
           "Configuration of IPv6 Router Advertisements.";
         leaf send-advertisements {
           type boolean;
           default "false";
           description
             "A flag indicating whether or not the router sends periodic
              Router Advertisements and responds to Router
              Solicitations.";
           reference
             "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) -
              AdvSendAdvertisements.";
         }
         leaf max-rtr-adv-interval {
           type uint16 {
             range "4..1800";
           }
           units "seconds";
           default "600";
           description
             "The maximum time allowed between sending unsolicited
              multicast Router Advertisements from the interface.";
           reference
             "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) -

Lhotka & Lindem         Expires November 26, 2015              [Page 39]
Internet-Draft           YANG Routing Management                May 2015

              MaxRtrAdvInterval.";
         }
         leaf min-rtr-adv-interval {
           type uint16 {
             range "3..1350";
           }
           units "seconds";
           must ". <= 0.75 * ../max-rtr-adv-interval" {
             description
               "The value MUST NOT be greater than 75 % of
                'max-rtr-adv-interval'.";
           }
           description
             "The minimum time allowed between sending unsolicited
              multicast Router Advertisements from the interface.

              The default value to be used operationally if this leaf is
              not configured is determined as follows:

              - if max-rtr-adv-interval >= 9 seconds, the default value
                is 0.33 * max-rtr-adv-interval;

              - otherwise it is 0.75 * max-rtr-adv-interval.";
           reference
             "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) -
              MinRtrAdvInterval.";
         }
         leaf managed-flag {
           type boolean;
           default "false";
           description
             "The value to be placed in the 'Managed address
              configuration' flag field in the Router Advertisement.";
           reference
             "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) -
              AdvManagedFlag.";
         }
         leaf other-config-flag {
           type boolean;
           default "false";
           description
             "The value to be placed in the 'Other configuration' flag
              field in the Router Advertisement.";
           reference
             "RFC 4861: Neighbor Discovery for IP version 6 (IPv6) -
              AdvOtherConfigFlag.";
         }
         leaf link-mtu {

Lhotka & Lindem         Expires November 26, 2015              [Page 40]lt;https://www.e4developer.com/2018/02/16/
              hateoas-simple-explanation/>.

   [JSONPATH-COMPARISON]
              "JSONPath Comparison",
              <https://cburgmer.github.io/json-path-comparison/>.

   [JSONPATH-WG]
              IETF, "JSON Path (jsonpath)",
              <https://datatracker.ietf.org/wg/jsonpath/about/>.

   [ODATA-PART1]
              Pizzo, M., Handl, R., and M. Zurmuehl, "OData Version 4.0.
              Part 1: Protocol Plus Errata 03", June 2016,
              <https://docs.oasis-
              open.org/odata/odata/v4.0/errata03/os/complete/part1-
              protocol/odata-v4.0-errata03-os-part1-protocol-
              complete.pdf>.

   [REST]     Fielding, R., "Architectural Styles and the Design of
              Network-based Software Architectures", 2000,
              <https://www.ics.uci.edu/~fielding/pubs/dissertation/
              fielding_dissertation.pdf>.

   [RFC6901]  Bryan, P., Ed., Zyp, K., and M. Nottingham, Ed.,
              "JavaScript Object Notation (JSON) Pointer", RFC 6901,
              DOI 10.17487/RFC6901, April 2013,
              <https://www.rfc-editor.org/info/rfc6901>.

   [SEEK]     EverSQL, "Faster Pagination in Mysql - Why Order By With
              Limit and Offset is Slow?", July 2017,
              <https://www.eversql.com/faster-pagination-in-mysql-why-
              order-by-with-limit-and-offset-is-slow/>.

   [W3C.CR-xpath-31-20170321]
              Robie, J., Dyck, M., and J. Spiegel, "XML Path Language
              (XPath) 3.1", World Wide Web Consortium Recommendation
              REC-xpath-31-20170321, March 2017,
              <https://www.w3.org/TR/2017/REC-xpath-31-20170321/>.

Appendix A.  JSONPath Operators

   The jsonpaths used in this document are provided according to the
   Goessner proposal [GOESSNER-JSON-PATH].

   Such specification requires that implementations support a set of
   "basic operators".  These operators are used to access the elements
   of a JSON structure like objects and arrays, as well as their
   subelements (object members and array items, respectively).  No
   operations are defined for retrieving parent or sibling elements of a
   given element.  The root element is always referred to as $
   regardless of it being an object or array.

   Additionally, the specification permits implementations to support
   arbitrary script expressions.  These can be used to index into an
   object or array, or to filter elements from an array.  While script
   expression behavior is implementation-defined, most implementations
   support the basic relational and logical operators as well as both
   object member and array item access, sufficiently similar for the
   purpose of this document.  Commonly supported operators/functions
   divided into "top-level operators" and "filter operators" are
   documented in Tables 2 and 3, respectively.

   For more information on implementation interoperability issues, see
   [JSONPATH-COMPARISON].  At the time of writing, work is beginning on
   a standardization effort too (see [JSONPATH-WG]).

      +===================+=========================================+
      | Operator          | Description                             |
      +===================+=========================================+
      | $                 | Root element                            |
      +-------------------+-----------------------------------------+
      | .<name>           | Object member access (dot-notation)     |
      +-------------------+-----------------------------------------+
      | ['<name>']        | Object member access (bracket-notation) |
      +-------------------+-----------------------------------------+
      | [<number>]        | Array item access                       |
      +-------------------+-----------------------------------------+
      | *                 | All elements within the specified scope |
      +-------------------+-----------------------------------------+
      | [?(<expression>)] | Filter expression                       |
      +-------------------+-----------------------------------------+

                   Table 2: JSONPath Top-Level Operators

      +====================+========================================+
      | Operator           | Description                            |
      +====================+========================================+
      | @                  | Current element being processed        |
      +--------------------+----------------------------------------+
      | .<name>            | Object member access                   |
      +--------------------+----------------------------------------+
      | .[<name1>,<name2>] | Union of object members                |
      +--------------------+----------------------------------------+
      | [<number>]         | Array item access                      |
      +--------------------+----------------------------------------+
      | ==                 | Left is equal to right                 |
      +--------------------+----------------------------------------+
      | !=                 | Left is not equal to right             |
      +--------------------+----------------------------------------+
      | <                  | Left is less than right                |
      +--------------------+----------------------------------------+
      | <=                 | Left is less than or equal to right    |
      +--------------------+----------------------------------------+
      | >                  | Left is greater than right             |
      +--------------------+----------------------------------------+
      | >=                 | Left is greater than or equal to right |
      +--------------------+----------------------------------------+
      | &&                 | Logical conjunction                    |
      +--------------------+----------------------------------------+
      | ||                 | Logical disjunction                    |
      +--------------------+----------------------------------------+

                     Table 3: JSONPath Filter Operators

Appendix B.  Approaches to Result Pagination

   An RDAP query could return a response with hundreds, even thousands,
   of objects, especially when partial matching is used.  For this
   reason, the "cursor" parameter addressing result pagination is
   defined to make responses easier to handle.

   Presently, the most popular methods to implement pagination in a REST
   API include offset pagination and keyset pagination.  Neither
   pagination method requires the server to handle the result set in a
   storage area across multiple requests since a new result set is
   generated each time a request is submitted.  Therefore, they are
   preferred to any other method requiring the management of a REST
   session.

   Using limit and offset operators represents the traditionally used
   method to implement result pagination.  Both of them can be used
   individually:

   "limit=N":  means that the server returns the first N objects of the
      result set

   "offset=N":  means that the server skips the first N objects and
      returns objects starting from position N+1

   When limit and offset are used together, they provide the ability to
   identify a specific portion of the result set.  For example, the pair
   "offset=100,limit=50" returns the first 50 objects starting from
   position 101 of the result set.

   Though easy to implement, offset pagination also includes drawbacks:

   *  When offset has a very high value, scrolling the result set could
      take some time.

   *  It always requires fetching all rows before dropping as many rows
      as specified by offset.

   *  It may return inconsistent pages when data are frequently updated
      (i.e., real-time data).

   Keyset pagination [SEEK] adds a query condition that enables the
   selection of the only data not yet returned.  This method has been
   taken as the basis for the implementation of a "cursor" parameter
   [CURSOR] by some REST API providers [CURSOR-API1] [CURSOR-API2].  The
   cursor is a URL-safe string opaque to the client and representing a
   logical pointer to the first result of the next page.

   Nevertheless, even keyset pagination can be troublesome:

   *  It needs at least one key field.

   *  It does not allow sorting simply by any field because the sorting
      criterion must contain a key.

   *  It works best with full composite values supported by database
      management systems (i.e., [x,y]>[a,b]); emulation is possible but
      inelegant and less efficient.

   *  It does not allow direct navigation to arbitrary pages because the
      result set must be scrolled in sequential order starting from the
      initial page.

   *  Implementing bidirectional navigation is tedious because all
      comparison and sort operations have to be reversed.

B.1.  Specific Issues Raised by RDAP

   Some additional considerations can be made in the RDAP context:

   *  An RDAP object is a conceptual aggregation of information
      generally collected from more than one data structure (e.g.,
      table), and this makes it even harder to implement keyset
      pagination, a task that is already quite difficult.  For example,
      the entity object can include information from different data
      structures (registrars, registrants, contacts, resellers), each
      one with its key field mapping the RDAP entity handle.

   *  Depending on the number of page results as well as the number and
      the complexity of the properties of each RDAP object in the
      response, the time required by offset pagination to skip the
      previous pages could be much faster than the processing time
      needed to build the current page.  In fact, RDAP objects are
      usually formed by information belonging to multiple data
      structures and containing multivalued properties (i.e., arrays);
      therefore, data selection might be a time-consuming process.  This
      situation occurs even though the selection is supported by
      indexes.

   *  Depending on the access levels defined by each RDAP operator, the
      increase in complexity and the decrease in flexibility of keyset
      pagination in comparison to offset pagination could be considered
      impractical.

   Ultimately, both pagination methods have benefits and drawbacks.

Appendix C.  Implementation Notes

   This section contains an overview of the main choices made during the
   implementation of the capabilities defined in this document in the
   RDAP public test server of Registro.it at the Institute of
   Informatics and Telematics of the National Research Council (IIT-
   CNR).  The content of this section can represent guidance for
   implementers who plan to provide RDAP users with those capabilities.
   The RDAP public test server can be accessed at
   <https://rdap.pubtest.nic.it/>.  Further documentation about the
   server features is available at <https://rdap.pubtest.nic.it/doc/
   README.html>.

C.1.  Sorting

   If no sort criterion is specified in the query string, the results
   are sorted by a default property: "name" for domains and nameservers,
   and "handle" for entities.  The server supports multiple property
   sorting but the "sorting_metadata" object includes only the links to
   alternative result set views sorted by a single property just to show
   the list of sorting properties allowed for each searchable object.
   The server supports all the object-specific sorting properties
   described in the specification except for nameserver sorting based on
   unicodeName, that is, the "name" sorting property is mapped onto the
   "ldhName" response field.  Regarding the object-common properties,
   sorting by registrationDate, expirationDate, lastChangedDate, and
   transferDate is supported.

C.2.  Counting

   The counting operation is implemented through a separate query.  Some
   relational database management systems support custom operators to
   get the total count together with the rows, but the resulting query
   can be considerably more expensive than that performed without the
   total count.  Therefore, as "totalCount" is an optional response
   information, always fetching the total number of rows has been
   considered an inefficient solution.  Furthermore, to avoid the
   processing of unnecessary queries, when the "count" parameter is
   included in the submitted query, it is not also repeated in the query
   strings of the "links" array provided in both "paging_metadata" and
   "sorting_metadata" objects.

C.3.  Paging

   The server implements the cursor pagination through the keyset
   pagination when sorting by a unique property is requested or the
   default sort is applied.  Otherwise, it implements the cursor
   pagination through the offset pagination.  As most relational
   database management systems don't support the comparison of full
   composite values natively, the implementation of full keyset
   pagination seem to be troublesome so, at least initially, a selective
   applicability of keyset pagination is advisable.  Moreover, the
   "cursor" value encodes not only information about pagination but also
   about the search pattern and the other query parameters in order to
   check the consistency of the entire query string.  If the "cursor"
   value is inconsistent with the rest of the query string, the server
   returns an error response.

Acknowledgements

   The authors would like to acknowledge Brian Mountford, Tom Harrison,
   Karl Heinz Wolf, Jasdip Singh, Erik Kline, Éric Vyncke, Benjamin
   Kaduk, and Roman Danyliw for their contributions to the development
   of this document.

Authors' Addresses

   Mario Loffredo
   IIT-CNR/Registro.it
   Via Moruzzi,1
   56124 Pisa
   Italy

   Email: mario.loffredo@iit.cnr.it
   URI:   https://www.iit.cnr.it

   Maurizio Martinelli
   IIT-CNR/Registro.it
   Via Moruzzi,1
   56124 Pisa
   Italy

   Email: maurizio.martinelli@iit.cnr.it
   URI:   https://www.iit.cnr.it

   Scott Hollenbeck
   Verisign Labs
   12061 Bluemont Way
   Reston, VA 20190
   United States of America

   Email: shollenbeck@verisign.com
   URI:   https://www.verisignlabs.com/