<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-ietf-regext-rdap-x-media-type-02" submissionType="IETF" category="std" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" updates="7480" indexInclude="true">

<front>
<title abbrev="rdap-x">An RDAP With Extensions Media Type</title><seriesInfo value="draft-ietf-regext-rdap-x-media-type-02" stream="IETF" status="standard" name="Internet-Draft"></seriesInfo>
<author initials="A." surname="Newton" fullname="Andy Newton"><organization>ICANN</organization><address><postal><street></street>
</postal><email>andy@hxr.us</email>
</address></author><author initials="J." surname="Singh" fullname="Jasdip Singh"><organization>ARIN</organization><address><postal><street></street>
</postal><email>jasdips@arin.net</email>
</address></author><date/>
<area>Applications and Real-Time Area (ART)</area>
<workgroup>Registration Protocols Extensions (regext)</workgroup>

<abstract>
<t>This document defines a media type for RDAP that can be used to describe RDAP content
with RDAP extensions. Additionally, this document describes the usage of this media
type with RDAP for the purposes of signalling RDAP extensions during content
negotiation.</t>
</abstract>

</front>

<middle>

<section anchor="background"><name>Background</name>
<t><xref target="RFC7480"></xref> defines the &quot;application/rdap+json&quot; media type to be used with RDAP. This
document defines a new media type to be used in conjunction with the current media type
when an RDAP extension needs to be described during HTTP content negotiation.</t>
<t>Though there maybe other purposes, the usage of this media type enables an RDAP
client to signal to an RDAP server the list of RDAP extensions supported by that client.
For example, an RDAP client that supports the &quot;foo&quot; extension may use this mechanism
as a signal to an RDAP server, thus allowing the server to serve data using the &quot;foo&quot;
extension only when it can be assured the client can understand it.</t>
<t>By using this method, there is no need for every RDAP extension to define their own unique
signaling mechanism. Additionally, this method is designed to be backwards-compatible
with the deployed RDAP ecosystem (see <xref target="design_considerations"></xref> for further information).</t>

<section anchor="document-terms"><name>Document Terms</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,
&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;,
&quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as
described in <xref target="BCP14"></xref> when, and only when, they
appear in all capitals, as shown here.</t>
</section>
</section>

<section anchor="rdap-x-the-rdap-with-extensions-media-type"><name>RDAP-X: The RDAP With Extensions Media Type</name>
<t>The media type defined by this document is &quot;application/rdap-x+json&quot;. This media
type has a parameter of &quot;extensions&quot; which is a whitespace-separated list of RDAP
extensions as defined in the IANA RDAP Extensions registry.</t>
<t>Here is an example:</t>

<artwork><![CDATA[application/rdap-x+json;extensions="rdap_level_0 fred"
]]></artwork>
<t>For readability, this document will refer to this media type, RDAP With Extensions,
as RDAP-X.</t>
</section>

<section anchor="using"><name>Using The RDAP-X Media Type</name>
<t><xref target="RFC7480"></xref> specifies the usage of &quot;application/json&quot;, &quot;application/rdap+json&quot; or
both with HTTP &quot;accept&quot; header. When using the media type defined by this document,
the &quot;application/rdap+json&quot; media type MUST also be used in the &quot;accept&quot; header.</t>
<t>An example:</t>

<artwork><![CDATA[accept: application/rdap+json;q=0.9, 
    application/rdap-x+json;extensions="rdap_level_0 rdapx fred";q=1
]]></artwork>
<t>When a server is programmed to understand the RDAP-X media type,
it SHOULD respond with this media type in the &quot;content-type&quot; header. By doing so,
clients will be able to detect if the server recognizes the media type. Otherwise,
the server will use the &quot;application/rdap+json&quot; media type signalling to the client
that the RDAP-X media type is not recognized by the server.
This updates the usage of the &quot;content-type&quot; header with RDAP defined in <xref target="RFC7480"></xref>,
but this usage is backwards-compatible.</t>
<t>If both a client and server support the RDAP-X media type, and the client requests
an extension that is unimplemented by the server, the server SHOULD respond with
the RDAP-X media type using only extensions implemented by the server. This behavior
is backwards-compatible as RDAP clients must ignore unknown extensions as specified by
<xref target="RFC9083"></xref>. Responding with an HTTP 406 Not Acceptable status code is NOT RECOMMENDED.</t>
<t>Likewise, if a server is required to use an extension in a response that was not
requested by the client, the server SHOULD respond as if the client had requested
the extension. This behavior is backwards-compatible as RDAP clients must ignore unknown
extensions as specified by <xref target="RFC9083"></xref>. Responding with an HTTP 406 Not Acceptable status
code is NOT RECOMMENDED.</t>
<t>When the RDAP-X media type is used in the &quot;content-type&quot; header, the
values in the media type's &quot;extensions&quot; parameter SHOULD match the values in the &quot;rdapConformance&quot;
array in the returned JSON. When there is a mismatch between the &quot;extensions&quot; parameter and
the &quot;rdapConformance&quot; array, clients SHOULD give preference to the &quot;rdapConformance&quot;
array.</t>
<t>Just as servers should not put extensions into the &quot;rdapConformance&quot; array for which
they do not support, servers SHOULD NOT list extensions in the RDAP-X media type for
which they do not support.</t>
<t>The contents of the &quot;extensions&quot; parameter mirrors the content of the
&quot;rdapConformance&quot; array in server responses. This includes the identifier &quot;rdap_level_0&quot;, which is not
an extension identifier by an identifier for the base RDAP specifications. Servers MUST
follow the same rules for placing &quot;rdap_level_0&quot; in the content of the &quot;extensions&quot;
parameter and the &quot;rdapConformance&quot; array. Clients SHOULD interpret an &quot;extensions&quot;
parameter without &quot;rdap_level_0&quot; or one of its successor identifiers (e.g. &quot;rdap_level_1&quot;)
in the same manner as the interpretation of the &quot;rdapConformance&quot; array without
&quot;rdap_level_0&quot; or one of its successors.</t>
<t>Nothing in this specification sidesteps or obviates the HTTP content negotiation defined
in <xref target="RFC9110"></xref> for RDAP. Specifically, if a client gives RDAP-X a lower q value than
any other media type, that is a signal not to use RDAP-X.</t>
<t>Likewise, nothing in this specification sidesteps or obviates the HTTP caching mechanisms
defined in <xref target="RFC9110"></xref>. Further advice on the &quot;vary&quot; header can be found in <xref target="vary_header"></xref>.</t>
<t>Some RDAP extensions, such as <xref target="RFC9560"></xref>, have other protocol elements
passed from the client to the server, and the presence of these protocol elements may be
used by servers to determine a client's capability to handle the RDAP extension. This specification
does not require the usage of those extension identifiers in the &quot;extensions&quot; parameter,
though clients SHOULD list the extension identifier in the &quot;extensions&quot; parameter when using
other protocol elements of those extensions. Servers SHOULD NOT require the usage of extension
identifiers in the &quot;extensions&quot; parameter when other extension protocol elements are used.</t>

<section anchor="examples"><name>Examples</name>
<t>The following examples use the HTTP/1.1 message exchange syntax as seen in <xref target="RFC9110"></xref>.</t>

<section anchor="classic-negotiation"><name>Classic Negotiation</name>
<t>This example demonstrates the negotiation of the &quot;applicaton/rdap+json&quot; media type
as defined in <xref target="RFC7480"></xref> using an RDAP &quot;/help&quot; query. This example also demonstrates
the negotiation in which a client does not support RDAP-X but a server does support
RDAP-X.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /help HTTP/1.1
accept: application/rdap+json
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap+json

{ "rdapConformance" : [ "rdap_level_0", "rdapx" ],
  "notices" : [
    { "description" : [ "my content includes a trailing CRLF" ] } ] }
]]></artwork>
</section>

<section anchor="rdap-x-negotiation"><name>RDAP-X Negotiation</name>
<t>In this example, both the client and server support RDAP-X and a fictional
extension of &quot;foo&quot;.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /help HTTP/1.1
accept: application/rdap+json, application/rdap-x+json;extensions="rdap_level_0 rdapx foo"
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap-x+json;extensions="rdap_level_0 rdapx foo"

{ "rdapConformance" : [ "rdap_level_0", "rdapx", "foo" ],
  "notices" : [
    { "description" : [ "my content includes a trailing CRLF" ] } ] }
]]></artwork>
</section>

<section anchor="no-server-support-negotiation"><name>No Server Support Negotiation</name>
<t>In this example, only the client supports RDAP-X, along with a fictional
extension of &quot;foo&quot;.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /help HTTP/1.1
accept: application/rdap+json, application/rdap-x+json;extensions="rdap_level_0 rdapx foo"
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap+json

{ "rdapConformance" : [ "rdap_level_0", "foo" ],
  "notices" : [
    { "description" : [ "my content includes a trailing CRLF" ] } ] }
]]></artwork>
</section>

<section anchor="differing-extension-negotiation"><name>Differing Extension Negotiation</name>
<t>In this example, both the client and server support RDAP-X. The client
supports the extensions &quot;foo&quot; and &quot;bar&quot; while the server only support &quot;foo&quot;.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /help HTTP/1.1
accept: application/rdap+json, application/rdap-x+json;extensions="rdap_level_0 rdapx foo bar"
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap-x+json;extensions="rdap_level_0 rdapx foo"

{ "rdapConformance" : [ "rdap_level_0", "rdapx", "foo" ],
  "notices" : [
    { "description" : [ "my content includes a trailing CRLF" ] } ] }
]]></artwork>
</section>

<section anchor="versioning"><name>Extension Versioning and Meta-data</name>
<t>For scenarios where the &quot;versioning&quot; extension, as defined by <xref target="I-D.ietf-regext-rdap-versioning"></xref>,
is used, the extension identifiers in the client request may not be exact or case-insensitive matches for the
extension identifiers in the server response (unlike scenarios where the &quot;versioning&quot; extension is not used).
That is, the extension identifiers used by the client have prepended versioning information, but the
extension identifiers returned by the server do not have prepended versioning information (such information
is in the &quot;versioning&quot; JSON).</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /domain/example.com HTTP/1.1
accept: application/rdap+json, application/rdap-x+json;extensions="rdap_level_0 rdapx versioning_0_2"
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap-x+json;extensions="rdap_level_0 rdapx versioning"

{ "rdapConformance" : [ "rdap_level_0", "rdapx", "versioning" ],
  "objectClassName": "domain",
  "ldhName": "example.com",
  "versioning": [ {
    "extension": "versioning",
    "type": "semantic",
    "version": "versioning_0_2" } ]
}
]]></artwork>
<t>Servers might also use the &quot;versioning&quot; extension to describe meta-data about
supported extensions even if the servers do not explicitly support extension versioning.</t>
</section>
</section>
</section>

<section anchor="links"><name>Usage in RDAP Links</name>
<t><xref target="RFC9083" sectionFormat="of" section="4.2"></xref> defines a link structure used in RDAP.</t>

<artwork><![CDATA[{
  "value": "https://example.com/context_uri",
  "rel": "self",
  "href": "https://example.com/target_uri",
  "hreflang": [ "en", "ch" ],
  "title": "title",
  "media": "screen",
  "type": "application/json"
}
]]></artwork>
<t>The type attribute signals to a client the expected media type of the resource
referenced in the href attribute, and some clients use this information to determine
if the URI in the href attribute should be de-referenced.</t>
<t>Servers MAY use the RDAP-X media type in the type attribute if a client
has negotiated content with the server using the RDAP-X media type,
the resource referenced by the URI matches the RDAP-X media type, and
the resource referenced by the URI is served by a server compliant with this specification.
Otherwise, use of the &quot;application/rdap+json&quot; media type is RECOMMENDED when the URI
references RDAP resources.</t>

<section anchor="example-with-rdap-x-negotiation"><name>Example With RDAP-X Negotiation</name>
<t>In this example, both the client and server support RDAP-X and the server has opted
to return links with the RDAP-X media type in a domain query.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /domain/example.com HTTP/1.1
accept: application/rdap+json, application/rdap-x+json;extensions="rdap_level_0 rdapx"
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap-x+json;extensions="rdap_level_0 rdapx"

{ "rdapConformance" : [ "rdap_level_0", "rdapx" ],
  "objectClassName": "domain",
  "ldhName" : "example.com",
  "links": [ {
    "value": "https://regy.example.net/domain/example.com",
    "rel": "self",
    "href": "https://regy.example.net/domain/example.com",
    "type": "application/rdap-x+json;extensions=\"rdap_level_0 rdapx\"" } ]
}
]]></artwork>
</section>

<section anchor="example-without-rdap-x-negotiation"><name>Example Without RDAP-X Negotiation</name>
<t>In this example, the client does not support RDAP-X. Though the server may support
RDAP-X, it will not signal RDAP-X because the client does not request it.</t>
<t>Client Request:</t>

<artwork><![CDATA[GET /domain/example.com HTTP/1.1
accept: application/rdap+json
]]></artwork>
<t>Server Response:</t>

<artwork><![CDATA[HTTP/1.1 200 OK
content-type: application/rdap+json

{ "rdapConformance" : [ "rdap_level_0", "rdapx" ],
  "ldhName" : "example.com",
  "links": [ {
    "value": "https://regy.example.net/domain/example.com",
    "rel": "self",
    "href": "https://regy.example.net/domain/example.com",
    "type": "application/rdap+json" } ]
}
]]></artwork>
</section>
</section>

<section anchor="rdap-x-extension"><name>RDAP-X Extension</name>
<t>This document defines an RDAP &quot;profile&quot; extension using the identifier &quot;rdapx&quot; (hyphen
characters are not allowed in RDAP extension identifiers). This RDAP extension defines
no additional RDAP queries or response structures.</t>
<t>The purpose of this RDAP extension is to allow servers to signal support for RDAP-X in
&quot;rdapConformance&quot; arrays of responses to &quot;/help&quot; (aka &quot;service discovery&quot;).</t>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>As stated in <xref target="using"></xref>, this specification does not override the protocol elements of
RDAP security extensions, such as <xref target="RFC9560"></xref>, nor does it override
the protocol elements of other security features of HTTP.</t>
<t>This specification does contrast with solutions using query parameters in that those
solutions require servers to blindly copy query parameters into redirect URLs in
situations where such copying could cause harm, such as copying an API key intended
for one server into the redirect URL of another server.</t>
</section>

<section anchor="iana-considerations"><name>IANA Considerations</name>
<t>IANA is requested to register the following value in the Media Types Registry at
<eref target="https://www.iana.org/assignments/media-types/:">https://www.iana.org/assignments/media-types/:</eref></t>
<t>Type name: application</t>
<t>Subtype name: rdap-x+json</t>
<t>Required parameters: This media type has a parameter of &quot;extensions&quot; which is a whitespace-separated list of RDAP extensions as defined in the IANA RDAP Extensions registry (<eref target="https://www.iana.org/assignments/rdap-extensions/rdap-extensions.xhtml">https://www.iana.org/assignments/rdap-extensions/rdap-extensions.xhtml</eref>).</t>
<t>Optional parameters:  N/A</t>
<t>Encoding considerations: See Section 3.1 of <xref target="RFC6839"></xref>.</t>
<t>Security considerations: The media represented by this identifier does not have security considerations beyond that found in Section 12 of <xref target="RFC8259"></xref>.</t>
<t>Interoperability considerations: There are no known interoperability problems regarding this media format.</t>
<t>Published specification: This document.</t>
<t>Applications that use this media type: Implementations of the Registration Data Access Protocol (RDAP) with Extensions.</t>
<t>Additional information: This media type is a product of the IETF REGEXT Working Group. The REGEXT charter, information on the REGEXT mailing list, and other documents produced by the REGEXT Working Group can be found at <eref target="https://datatracker.ietf.org/wg/regext/">https://datatracker.ietf.org/wg/regext/</eref>.</t>
<t>Person &amp; email address to contact for further information: IESG &lt;iesg&amp;ietf.org&gt;</t>
<t>Intended usage: COMMON</t>
<t>Restrictions on usage: None</t>
<t>Author: Andy Newton</t>
<t>Change controller: IETF</t>
<t>Provisional Registration: No</t>
</section>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>Pawel Kowalik and James Mitchell have provided ideas and feedbacks that have contributed to
the content of this document.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml9/reference.BCP.14.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6839.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7480.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8259.xml"/>
</references>
<references><name>Informative References</name>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-regext-rdap-extensions.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml3/reference.I-D.ietf-regext-rdap-versioning.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3986.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6838.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9083.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9110.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9560.xml"/>
</references>
</references>

<section anchor="vary_header"><name>Using the Vary Header</name>
<t>Server implementers may want to consider using the &quot;vary&quot; header depending on the caching
behavior desired of shared caches (i.e. middleboxes, not client caches).</t>
<t>Consider the following scenario where user Bob and user Alice send queries to the same
RDAP server that is routed through a middlebox network element implementing a shared HTTP cache.</t>
<t>User Bob sends a query for the domain &quot;example.com&quot;
(<eref target="http://regy.example/domain/example.com">http://regy.example/domain/example.com</eref>) without RDAP-X. The &quot;accept&quot; header sent
for Bob's query would be &quot;accept: application/rdap+json&quot; or &quot;accept: application/json&quot;.</t>
<t>User Alice later sends a query for the same domain, however her client uses RDAP-X. The &quot;accept&quot;
header sent for Alice's query might be &quot;accept: application/rdap-x+json, application/rdap+json&quot;.</t>
<t>If no &quot;vary&quot; header is set in the response for these queries, the shared cache will compare only
the URL of the query when processing cache items and therefore user Bob and user Alice would receive
the same answer. In other words, since both queried &quot;<eref target="http://regy.example/domain/example.com&quot;">http://regy.example/domain/example.com"</eref> the shared
cache would return the answer of the first query to the second query and all other subsequent queries
until the item expired out of the cache.</t>
<t>If server implementers do not desire this behavior and would signal that caches consider each query
separately, servers should also return a &quot;vary: accept&quot; header to inform the cache that the &quot;accept&quot;
header should also be considered when processing cache items. Server implementers should also
consult <xref target="RFC9110"></xref> regarding caching and other uses of the &quot;vary&quot; header.</t>
</section>

<section anchor="design_considerations"><name>Design Considerations</name>

<section anchor="not-reusing-the-existing-media-type"><name>Not Reusing the Existing Media Type</name>
<t><xref target="RFC6838" sectionFormat="of" section="4.3"></xref> strongly discourages the creation of new parameters on existing
media types to enable new features. As RDAP has always had extensions, it could be argued
that adding an &quot;extensions&quot; parameter to the existing &quot;application/rdap+json&quot; media type
is not adding a new feature to RDAP. However, the opposite could be argued that adding
the capability for clients to signal desired RDAP extensions is a new feature.</t>
<t>More practically, there is concern that adding a new parameter to the existing media
type would not be backwards-compatible with some server software. That is, servers
examining media types as exact string matches may incorrectly conclude that the existing
media type with an unknown, new parameter may not be the same as the existing media
type without parameters. A similar, though less likely, concern exists for clients.</t>
<t>As servers are required to handle multiple media types according to <xref target="RFC7480"></xref> and <xref target="RFC9110"></xref>,
it therefore seems reasonable to conclude that defining a new media type for use with
the existing media type is best to preserve backward compatibility.</t>
</section>

<section anchor="inappropriate-use-of-query-parameters"><name>Inappropriate Use of Query Parameters</name>
<t>Another design approach to communicating RDAP extensions from the client to the
server would be the use of URI query parameters:</t>

<artwork><![CDATA[https://rdap.example/domain/foo.example?extensions=fizzbuzz  
]]></artwork>
<t>However, there are a few problems with using query parameters for this scenario.
Some of these problems are specific to RDAP and are also documented in
<xref target="I-D.ietf-regext-rdap-extensions"></xref>. The following sections also describe the
problems.</t>

<section anchor="copy-and-paste"><name>Copy and Paste</name>
<t>Consider two RDAP users, Alice and Bob. Alice has an RDAP client that supports
the extensions &quot;fizzbuzz&quot;, and Bob has an RDAP client that does not support this
extension.</t>
<t>Now consider the scenario where Alice copies and pastes the RDAP URL from above into an email
and sends it to Bob. When Bob uses that URL with his RDAP client, it will be communicating
to the server that the extension &quot;fizzbuzz&quot; is understood by Bob's client when it is not.</t>
<t>In this scenario, Bob's client will be unable to render the RDAP extension regardless
of the usage or not of the query parameter. However, if the server is using the query
parameter for secondary purposes, such as gathering metrics and statistics, then the
capabilities of Bob's client will have been incorrectly signalled to the server.</t>
</section>

<section anchor="redirects"><name>Redirects</name>
<t>The RDAP ecosystem uses redirects in many situations. <xref target="RFC7480"></xref> discusses &quot;aggregators&quot;, which
are RDAP servers used to help clients find authoritative RDAP servers using the RDAP bootstrap
registries. Redirects are also heavily used by the RIRs when IP addresses or autonomous
system numbers are transferred from one RIR to another.</t>
<t>Within HTTP, URI query parameters are not explicitly preserved during a redirect (probably
due to architecture considerations, see the section below). Specific to RDAP, <xref target="RFC7480"></xref>
instructs RDAP servers to ignore unknown query parameters and instructs clients not to
transform the URL of a redirect.</t>
<t>Therefore, query parameters denoting RDAP extensions will not survive redirects. This can
be readily observed in currently deployed RDAP servers:</t>

<artwork><![CDATA[curl -v https://rdap-bootstrap.arin.net/bootstrap/autnum/2830?extension=fizzbuzz    
]]></artwork>
<t>To further demonstrate that query parameters do not automatically survive redirects but that media types
do, consider the code found <eref target="https://github.com/anewton1998/draft-regext-ext-json-media-type">here</eref>.
This code consists of a simple client and a simple server. The client sets both a new
media type and query parameters. The servers listen on two ports, redirecting the client
from a URL on the first port to a URL on the second port.</t>
<t>Here is the output of the client. It shows that the query parameters are not automatically
preserved but that the media type is automatically preserved.</t>

<artwork><![CDATA[2024-01-05T11:15:34.380989Z  INFO client: sending reqwest to http://127.0.0.1:3000/ex1/domain/foo.example?foo&bar
2024-01-05T11:15:34.431386Z  INFO client: returned content type: "application/rdap-x;extensions=\"foo bar\""
2024-01-05T11:15:34.431413Z  INFO client: status code is 418 I'm a teapot
2024-01-05T11:15:34.431476Z  INFO client: response is {"errorCode":418,"title": "Your Beverage Choice is Not Available"}
]]></artwork>
<t>Here is the output of the server. It shows that the client, upon redirect, automatically sends the media type
but does not automatically preserve the query parameters.</t>

<artwork><![CDATA[2024-01-05T11:15:31.071936Z  INFO servers: starting server on port 3000
2024-01-05T11:15:31.071961Z  INFO servers: starting server on port 4000
2024-01-05T11:15:34.429595Z  INFO servers: [redirecting server] Serving request from 127.0.0.1:60260
2024-01-05T11:15:34.429648Z  INFO servers: [redirecting server] received query parameters: 'bar', 'foo'
2024-01-05T11:15:34.429682Z  INFO servers: [redirecting server] client signaled RDAP extension 'foo'
2024-01-05T11:15:34.429693Z  INFO servers: [redirecting server] client signaled RDAP extension 'bar'
2024-01-05T11:15:34.429704Z  INFO servers: [redirecting server] redirecting to http://127.0.0.1:4000/ex2/domain/foo.example
2024-01-05T11:15:34.430940Z  INFO servers: [authoritative server] Serving request from 127.0.0.1:40840
2024-01-05T11:15:34.430967Z  INFO servers: [authoritative server] received query parameters:
2024-01-05T11:15:34.430983Z  INFO servers: [authoritative server] client signaled RDAP extension 'foo'
2024-01-05T11:15:34.430989Z  INFO servers: [authoritative server] client signaled RDAP extension 'bar'
2024-01-05T11:15:34.430995Z  INFO servers: [authoritative server] responding with an unuseful error
]]></artwork>
<t>Preservation of query parameters is not a guaranteed feature of HTTP client and server libraries,
whereas preservation of media types is.</t>
</section>

<section anchor="referral-compatibility"><name>Referral Compatibility</name>
<t>It is common in the RDAP ecosystem to link from one RDAP resource to another. These are typically
conveyed in the link structure defined in <xref target="RFC9083" sectionFormat="of" section="4.2"></xref> and use the &quot;application/rdap+json&quot;
media type. One common usage is to link to a domain registration in a domain registrar from
a domain registration in a domain registry.</t>

<artwork><![CDATA[{
  "value" : "https://regy.example/domain/foo.example",
  "rel" : "related",
  "href" : "https://regr.example/domain/foo.example",
  "type" : "application/rdap+json"
}
]]></artwork>
<t>Usage of the RDAP-X media type does not require clients to conduct further processing of these
referrals, whereas a query parameter approach would require clients to process and de-conflict
any other query parameters if present.</t>
</section>

<section anchor="architectural-violations"><name>Architectural Violations</name>
<t>As noted in <xref target="RFC3986"></xref>, URI query parameters are meant to be part of the identity of the resource
being identified by a URI and pointed to by the location of a URL. RDAP extensions change
the portions of JSON returned by the server but are not intended to change the resource
being identified. That is, a domain registration is the same domain registration regardless
of whether the postal address in that domain registration is communicated via JCard or
a new RDAP extension for JSContact.</t>
<t>Changing how the content of a resource is conveyed is called content negotiation and
is discussed in detail in <xref target="RFC9110"></xref> using media types.</t>
<t>Readers should note that protocol design is not a &quot;priestly affair&quot; in which architectural
violations are strictly forbidden. Every design decision is a trade-off. However, following
the architecture of an ecosystem generally makes re-use of software and systems easier,
and often eases the adoption of newer features in the future. When given the choice between
two designs, the design that does not violate architecture should be preferred when all
other considerations are equal.</t>
</section>
</section>
</section>

</back>

</rfc>
