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/