Re: [regext] RDAP Extensions Approach Analysis v2

Jasdip Singh <jasdips@arin.net> Fri, 10 June 2022 20:07 UTC

Return-Path: <jasdips@arin.net>
X-Original-To: regext@ietfa.amsl.com
Delivered-To: regext@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id EB123C15791C for <regext@ietfa.amsl.com>; Fri, 10 Jun 2022 13:07:19 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.809
X-Spam-Level:
X-Spam-Status: No, score=-1.809 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, HTML_TAG_BALANCE_BODY=0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3028SzqwrpR8 for <regext@ietfa.amsl.com>; Fri, 10 Jun 2022 13:07:17 -0700 (PDT)
Received: from smtp4.arin.net (smtp4.arin.net [199.43.0.54]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 307B5C13A2C3 for <regext@ietf.org>; Fri, 10 Jun 2022 13:07:09 -0700 (PDT)
Received: from CAS01CHA.corp.arin.net (cas01cha.corp.arin.net [10.1.30.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by smtp4.arin.net (Postfix) with ESMTPS id AC3ED1075764 for <regext@ietf.org>; Fri, 10 Jun 2022 16:07:07 -0400 (EDT)
Received: from CAS01CHA.corp.arin.net (10.1.30.62) by CAS01CHA.corp.arin.net (10.1.30.62) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 10 Jun 2022 16:07:06 -0400
Received: from CAS01CHA.corp.arin.net ([fe80::99af:898b:219f:401]) by CAS01CHA.corp.arin.net ([fe80::99af:898b:219f:401%17]) with mapi id 15.00.1497.000; Fri, 10 Jun 2022 16:07:06 -0400
From: Jasdip Singh <jasdips@arin.net>
To: "regext@ietf.org" <regext@ietf.org>
Thread-Topic: RDAP Extensions Approach Analysis v2
Thread-Index: AQHYehMOb+39gncj606qQP5zBqNDnq1JFymA
Date: Fri, 10 Jun 2022 20:07:05 +0000
Message-ID: <9D0DC567-0CD9-4B49-8E98-54166C8BDE56@arin.net>
References: <9DFC631E-8AD7-4CE2-8D13-9ABC342F4234@arin.net>
In-Reply-To: <9DFC631E-8AD7-4CE2-8D13-9ABC342F4234@arin.net>
Accept-Language: en-US
Content-Language: en-US
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
x-ms-exchange-messagesentrepresentingtype: 1
x-ms-exchange-transport-fromentityheader: Hosted
x-originating-ip: [192.136.136.37]
Content-Type: multipart/alternative; boundary="_000_9D0DC5670CD94B498E9854166C8BDE56arinnet_"
MIME-Version: 1.0
Archived-At: <https://mailarchive.ietf.org/arch/msg/regext/ZF8UNZQpa2lrJKU0fcTplQGOKVQ>
Subject: Re: [regext] RDAP Extensions Approach Analysis v2
X-BeenThere: regext@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: Registration Protocols Extensions <regext.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/regext>, <mailto:regext-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/regext/>
List-Post: <mailto:regext@ietf.org>
List-Help: <mailto:regext-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/regext>, <mailto:regext-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 10 Jun 2022 20:07:20 -0000

Hi.



Based on some direct feedback from Mario (thanks Mario for the careful review), further revised this analysis [1].



TL;DR -- Approach B (Lack of tight coupling between extension identifier and rdapConformance) could also afford an upgrade path for quite a few of the listed scenarios, thereby raising its grade. :)



Further, beside updating various aspects in the Aspect Analysis section for Approach B, added one more aspect: “On-the-wire efficiency”.



Thanks,

Jasdip



[1] https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit?usp=sharing



---



RDAP Extensions Analysis v2


Approaches<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.x3za3x81059e>

Change Scenario Analysis<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.zi62z1sce607>

Aspect Analysis<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.ogk4tkhrldq5>

Approaches


Approach A: Tight coupling between extension identifier and rdapConformance


Extension identifier = <opaque identifier>

  No version semantics

  Registered in the IANA RDAP Extensions registry

  A new spec provided for each new iteration of the extension

rdapConformance = <extension identifier>


Extension identifier used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)


Note: The phrase “new iteration” here simply connotes a new opaque identifier for an extension when it evolves.


Approach B: Lack of tight coupling between extension identifier and rdapConformance


Extension identifier = <prefix>

  Registered in the IANA RDAP Extensions registry

rdapConformance = <prefix>[<version (suffix)>]   [ ] means optional

  Needs version (suffix) semantics

  Registered in the IANA RDAP Extensions registry (or perhaps another registry for rdapConformance)

  A new spec provided for each new version of rdapConformance


Extension identifier used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)


Approach C: Decouple extension identifier from prefix(es) used for naming


Extension identifier = <opaque identifier>

  Registered in the IANA RDAP Extensions registry

  A new spec provided for each new iteration of the extension; lists prefix(es) used for naming

    Version semantics not needed for listed prefix(es)

rdapConformance = <extension identifier>


Listed prefix(es) used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)

Change Scenario Analysis

Legend:

ei - extension identifier

rc - rdapConformance value

p - prefix

u - URI

q - query parameter

s - segment

sp - segment parameter

d - data member


#


Change Scenario


Approach A - Tight coupling between extension identifier and rdapConformance


Approach B - Lack of tight coupling between extension identifier and rdapConformance


Approach C - Decouple extension identifier from prefix(es) used for naming


1


Add a URI path (no parameters yet)


ei = ext0 (registered)

rc = ext0

p = ext0 (new)


u0 = …/ext0/…


ei = ext (registered)

rc = ext0 (registered)

p = ext (new)


u0 = …/ext/…


ei = ext0 (registered)

rc = ext0

p = p0 (new)


u0 = …/p0/…


2


Add a path segment (s1)


ei = ext1 (registered)

rc = ext1

p = ext1 (new)


u1 = …/ext1/s1/…


Old URI u0 continues to exist during transition


ei = ext

rc = ext1 (registered)

p = ext


u1 = …/ext/s1/…


Old URI u0 continues to exist during transition


ei = ext1 (registered)

rc = ext1

p = p1 (new)


u1 = …/p1/s1/…


Old URI u0 continues to exist during transition


3


Add a segment parameter (sp2)


ei = ext2 (registered)

rc = ext2

p = ext2 (new)


u2 = …/ext2/s1;sp2=.../…


Old URI u1 continues to exist during transition


ei = ext

rc = ext2 (registered)

p = ext


u2 = …/ext/s1;sp2=.../…


Clients still on rc ext1 when calling u1 break if sp2 is required; otherwise not


ei = ext2 (registered)

rc = ext2

p = p1


u2 = …/p1/s1;sp2=.../…


Clients still on rc ext1 when calling u1 break if sp2 is required; otherwise not


The breakage scenario could be avoided by registering a new prefix for ext2


4


Rename a segment parameter (sp2 -> sp3)


ei = ext3 (registered)

rc = ext3

p = ext3 (new)


u3 = …/ext3/s1;sp3=.../…


Old URI u2 continues to exist during transition


ei = ext

rc = ext3 (registered)

p = ext


u3 = …/ext/s1;sp3=.../…


Old URI u2 continues to exist during transition


ei = ext3 (registered)

rc = ext3

p = p3 (new)


u3 = …/p3/s1;sp3=.../…


Old URI u2 continues to exist during transition


5


Remove a path segment (s1)


ei = ext4 (registered)

rc = ext4

p = ext4 (new)


u4 = …/ext4/…


Old URI u3 continues to exist during transition


ei = ext

rc = ext4 (registered)

p = ext


u4 = …/ext/…


Old URI u3 continues to exist during transition


ei = ext4 (registered)

rc = ext4

p = p4 (new)


u4 = …/p4/…


Old URI u3 continues to exist during transition


6


Add a required query parameter (q5)


ei = ext5 (registered)

rc = ext5

p = ext5 (new)


u5 = …/ext5/…?q5=...


Old URI u4 continues to exist during transition


Note: The query parameters (e.g. q5) for a URI path containing the extension identifier need not be prefixed with that identifier, just like the sub-data (e.g. d0 in ext9_d object, row 10) need not for a data member prefixed with the extension identifier


ei = ext

rc = ext5 (registered)

p = ext


u5 = …/ext/…?q5=...


Clients still on rc ext4 when calling u4 break


ei = ext5 (registered)

rc = ext5

p = p5 (new)


u5 = …/p5/…?q5=...


Old URI u4 continues to exist during transition


7


Add an optional query parameter (q6)


ei = ext6 (registered)

rc = ext6

p = ext6 (new)


u6 = …/ext6/…?q5=...&q6=...


Old URI u5 continues to exist during transition


ei = ext

rc = ext6 (registered)

p = ext


u6 = …/ext/…?q5=...&q6=...


Clients still on rc ext5 when calling u5 do not break


ei = ext6 (registered)

rc = ext6

p = p5


u6 = …/p5/…?q5=...&q6=...


Clients still on rc ext5 when calling u5 do not break


8


Rename a required query parameter (q5 -> q7)


ei = ext7 (registered)

rc = ext7

p = ext7 (new)


u7 = …/ext7/…?q7=...&q6=...


Old URI u6 continues to exist during transition


ei = ext

rc = ext7 (registered)

p = ext


u7 = …/ext/…?q7=...&q6=...


Old URI u6 continues to exist during transition


ei = ext7 (registered)

rc = ext7

p = p7 (new)


u7 = …/p7/…?q7=...&q6=...


Old URI u6 continues to exist during transition


9


Rename an optional query parameter (q6 -> q8)


ei = ext8 (registered)

rc = ext8

p = ext8 (new)


u8 = …/ext8/…?q7=...&q8=...


Old URI u7 continues to exist during transition


ei = ext

rc = ext8 (registered)

p = ext


u8 = …/ext/…?q7=...&q8=...


Old URI u7 continues to exist during transition


ei = ext8 (registered)

rc = ext8

p = p8 (new)


u8 = …/p8/…?q7=...&q8=...


Old URI u7 continues to exist during transition


10


Add a new data member (object class, array, number, string, and/or literal) (d object) for a new response


ei = ext9 (registered)

rc = ext9

p = ext9 (new)


u9 = …/ext9/…?q7=...&q8=...


Old URI u8 continues to exist during transition


u9_d = …/ext9_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “ext9_d” : {

    “d0” : “a”

  }

}


ei = ext

rc = ext9 (registered)

p = ext


u8 = …/ext/…?q7=...&q8=...


u9_d = …/ext_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “ext_d” : {

    “d0” : “a”

  }

}


ei = ext9 (registered)

rc = ext9

p = p8


u8 = …/p8/…?q7=...&q8=...


u9_d = …/p8_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “p8_d” : {

    “d0” : “a”

  }

}


11


Add a required data member (d1) to an existing response


ei = ext10 (registered)

rc = ext10

p = ext10 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “ext10_d1” : 8

}


ei = ext

rc = ext10 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “ext_d1” : 8

}


ei = ext10 (registered)

rc = ext10

p = p10 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “p10_d1” : 8

}


12


Add an optional data member (d2) to an existing response


ei = ext11 (registered)

rc = ext11

p = ext11 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”,

    “ext11”

  ],

  …,

  “ext10_d1” : 8,

  “ext11_d1” : 8,

  “ext11_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break, at the expense of sending duplicate data for ext10


ei = ext

rc = ext11 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”

  ],

  …,

  “ext_d1” : 8,

  “ext_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break


ei = ext11 (registered)

rc = ext11

p = p10


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”

  ],

  …,

  “p10_d1” : 8,

  “p10_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break


13


Rename a required data member (d1 -> d3)


ei = ext12 (registered)

rc = ext12

p = ext12 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”,

    “ext12”

  ],

  …,

  “ext11_d1” : 8,

  “ext11_d2” : “abc”,

  “ext12_d3” : 8,

  “ext12_d2” : “abc”

}


Clients still on rc ext11 when calling u10 do not break, at the expense of sending duplicate data for ext11


ei = ext

rc = ext12 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”,

    “ext12”

  ],

  …,

  “ext_d1” : 8,

  “ext_d3” : 8,

  “ext_d2” : “abc”

}


Clients still on rc ext11 when calling u10 do not break, at the expense of sending duplicate data for ext11; albeit lesser cumulative data than other approaches


ei = ext12 (registered)

rc = ext12

p = p12 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”,

    “ext12”

  ],

  …,

  “p10_d1” : 8,

  “p10_d2” : “abc”,

  “p12_d3” : 8,

  “p12_d2” : “abc”

}


Clients still on rc ext11 when calling u10 do not break, at the expense of sending duplicate data for ext11


14


Modify a required data member’s type (d3 number -> string)


ei = ext13 (registered)

rc = ext13

p = ext13 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext12”,

    “ext13”

  ],

  …,

  “ext12_d3” : 8,

  “ext12_d2” : “abc”,

  “ext13_d3” : “def”,

  “ext13_d2” : “abc”

}


Clients still on rc ext12 when calling u10 do not break, at the expense of sending duplicate data for ext12


ei = ext

rc = ext13 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d2” : “abc”

}


Clients still on rc ext12 when calling u10 break


ei = ext13 (registered)

rc = ext13

p = p13 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext12”,

    “ext13”

  ],

  …,

  “p12_d3” : 8,

  “p12_d2” : “abc”,

  “p13_d3” : “def”,

  “p13_d2” : “abc”

}


Clients still on rc ext12 when calling u10 do not break, at the expense of sending duplicate data for ext12


15


Rename an optional data member (d2 -> d4)


ei = ext14 (registered)

rc = ext14

p = ext14 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”,

    “ext14”

  ],

  …,

  “ext13_d3” : “def”,

  “ext13_d2” : “abc”,

  “ext14_d3” : “def”,

  “ext14_d4” : “abc”

}


Clients still on rc ext13 when calling u10 do not break, at the expense of sending duplicate data for ext13


ei = ext

rc = ext14 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”,

    “ext14”

  ],

  …,

  “ext_d2” : “abc”

  “ext_d3” : “def”,

  “ext_d4” : “abc”

}


Clients still on rc ext13 when calling u10 do not break, at the expense of sending duplicate data for ext13; albeit lesser cumulative data than other approaches


ei = ext14 (registered)

rc = ext14

p = p14 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”,

    “ext14”

  ],

  …,

  “p13_d3” : “def”,

  “p13_d2” : “abc”,

  “p14_d3” : “def”,

  “p14_d4” : “abc”

}


Clients still on rc ext13 when calling u10 do not break, at the expense of sending duplicate data for ext13


16


Modify an optional data member’s type (d4 string -> number)


ei = ext15 (registered)

rc = ext15

p = ext15 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext14”,

    “ext15”

  ],

  …,

  “ext14_d3” : “def”,

  “ext14_d4” : “abc”,

  “ext15_d3” : “def”,

  “ext15_d4” : 16

}


Clients still on rc ext14 when calling u10 do not break, at the expense of sending duplicate data for ext14


ei = ext

rc = ext15 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d4” : 16

}


Clients still on rc ext14 when calling u10 break if they were processing the optional data member


ei = ext15 (registered)

rc = ext15

p = p15 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext14”,

    “ext15”

  ],

  …,

  “p14_d3” : “def”,

  “p14_d4” : “abc”,

  “p15_d3” : “def”,

  “p15_d4” : 16

}


Clients still on rc ext14 when calling u10 do not break, at the expense of sending duplicate data for ext14


17


Remove a required data member (d3)


ei = ext16 (registered)

rc = ext16

p = ext16 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”,

    “ext16”

  ],

  …,

  “ext15_d3” : “def”,

  “ext15_d4” : 16,

  “ext16_d4” : 16,

}


Clients still on rc ext15 when calling u10 do not break, at the expense of sending duplicate data for ext15


ei = ext

rc = ext16 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”,

    “ext16”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d4” : 16

}


Clients still on rc ext15 when calling u10 do not break, at the expense of sending duplicate data for ext15; albeit lesser cumulative data than other approaches


ei = ext16 (registered)

rc = ext16

p = p16 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”,

    “ext16”

  ],

  …,

  “p15_d3” : “def”,

  “p15_d4” : 16,

  “p16_d4” : 16,

}


Clients still on rc ext15 when calling u10 do not break, at the expense of sending duplicate data for ext15


18


Remove an optional data member (d4)


ei = ext17 (registered)

rc = ext17

p = ext16


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”,

    “ext17”

  ],

  …,

  “ext16_d4” : 16

}


Clients still on rc ext16 when calling u10 do not break, at the expense of sending data for ext16


Note: This would be the case when phasing out jcard


ei = ext

rc = ext17 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”,

    “ext17”

  ],

  …,

  “ext_d4” : 16

}


Clients still on rc ext16 when calling u10 do not break, at the expense of sending data for ext16


ei = ext17 (registered)

rc = ext17

p = p16


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”,

    “ext17”

  ],

  …,

  “p16_d4” : 16

}


Clients still on rc ext16 when calling u10 do not break, at the expense of sending data for ext16


19


Remove a required query parameter (q7)


ei = ext18 (registered)

rc = ext18

p = ext18 (new)


u18 = …/ext18/…?q8=...


Old URI u9 (row 10) continues to exist during transition


ei = ext

rc = ext18 (registered)

p = ext


u18 = …/ext/…?q8=...


Old URI u8 (row 10) continues to exist during transition


ei = ext18 (registered)

rc = ext18

p = p18 (new)


u18 = …/p18/…?q8=...


Old URI u8 (row 10) continues to exist during transition


20


Remove an optional query parameter (q8)


ei = ext19 (registered)

rc = ext19

p = ext19 (new)


u19 = …/ext19/…


Old URI u18 continues to exist during transition


ei = ext

rc = ext19 (registered)

p = ext


u19 = …/ext/…


Old URI u18 continues to exist during transition


ei = ext19 (registered)

rc = ext19

p = p19 (new)


u19 = …/p19/…


Old URI u18 continues to exist during transition


21


Remove a URI path (u19)


ei = ext20 (registered)

rc = ext20

p = ext19


u19 = …/ext19/…


Old URI u19 continues to exist during transition, and not beyond


ei = ext

rc = ext20 (registered)

p = ext


u19 = …/ext/…


Old URI u19 continues to exist during transition, and not beyond


ei = ext20 (registered)

rc = ext20

p = p19


u19 = …/p19/…


Old URI u19 continues to exist during transition, and not beyond


22


Add a query parameter (q9) to an existing, non-extension URI


ei = ext21 (registered)

rc = ext21

p = ext21 (new)


u21 = …?ext21_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


ei = ext

rc = ext21 (registered)

p = ext


u21 = …?ext_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


ei = ext21 (registered)

rc = ext21

p = p21 (new)


u21 = …?p21_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


23


Remove a query parameter (q9) from an existing, non-extension URI, as well as add a query parameter (q10) to it


ei = ext22 (registered)

rc = ext22

p = ext22 (new)


u22 = …?ext21_q9=...&ext22_q10=...


{

  “rdapConformance” : [

    …,

    “ext21”,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 do not break


ei = ext

rc = ext22 (registered)

p = ext


u22 = …?ext_q10=...


{

  “rdapConformance” : [

    …,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 break


ei = ext22 (registered)

rc = ext22

p = p22 (new)


u22 = …?p21_q9=...&p22_q10=...


{

  “rdapConformance” : [

    …,

    “ext21”,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 do not break


Aspect Analysis


#


Aspect


Approach A - Tight coupling between extension identifier and rdapConformance


Approach B - Lack of tight coupling between extension identifier and rdapConformance


Approach C - Decouple extension identifier from prefix(es) used for naming


1


Providing a new spec to IANA for a new iteration of an extension


Registry stays as-is


Few non-compliant registrations need to be remedied


Registry needs to evolve for:


  Versioned rdapConformance


  Tying spec to versioned rdapConformance


Registry stays as-is


Prefix(es) listed in the spec


2


Risk of breaking changes for RDAP clients


Minimal since it would always be a controlled upgrade to the next iteration of an extension with sufficient transition time


More risky since there is no controlled way to upgrade for few of the change scenarios<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.zi62z1sce607>


Risk is minimal, like for approach A


However, requires carefully identifying the need for a new prefix on scenario-by-scenario basis; otherwise inadvertent mistakes possible


3


Cost of reprogramming clients for the next iteration of an extension


There is cost but not as high as it seems — replacing extension identifier in multiple places, and accounting for primarily query parameter and data member changes


Longer grace period for clients to reprogram if the server supports multiple iterations of an extension during transition


For few change scenarios, reprogramming could become exigent for clients when the server switches to the new iteration without a way to support the previous iteration


For other change scenarios, longer grace period for clients to reprogram if the server supports multiple iterations of an extension during transition


Cost slightly lower than that for Approach A — replacing prefixes for a majority (but not all) of the scenarios


4


Cost of reprogramming servers for the next iteration of an extension


Highest cost — to simultaneously support multiple iterations during transition period, replicating code from the previous iteration and replacing extension identifier in multiple places, and accounting for primarily query parameter and data member changes


Eventually retiring code for the previous iteration


Cost is lower than that for other approaches but not that low — for a majority (but not all) of the scenarios, to simultaneously support multiple iterations during transition period, replicating code from the previous iteration, and accounting for primarily query parameter and data member changes


Eventually retiring code for the previous iteration


Cost is lower than for that for Approach A but not too low — for a majority (but not all) of the scenarios, to simultaneously support multiple iterations during transition period, replicating code from the previous iteration and replacing prefixes in multiple places, and accounting for primarily query parameter and data member changes


Eventually retiring code for the previous iteration


5


Server-side signaling of the next iteration of an extension


Add the new value of the rdapConformance in the help response and related responses


Make the new URIs available, without affecting the old ones


Add the new value of the rdapConformance in the help response and related responses


Mostly the current URIs change for the new value of the rdapConformance, resulting in client breakages for few of the scenarios


Add the new value of the rdapConformance in the help response and related responses


To a lower extent than Approach A, make the new URIs available, without affecting the old ones


6


Collisions risk


Zero since the new extension identifier is explicitly marked in data members and URIs


Zero since the constant extension identifier is explicitly marked in data members and URIs


However, client breakage possible for few change scenarios


Zero since the new prefix is explicitly marked in data members and URIs, just like the new extension identifier in Approach A


7


On-the-wire efficiency


Lower than Approach B since more duplicated data is sent back when supporting multiple iterations during transition period


Highest since lesser duplicated data is sent back when supporting multiple iterations during transition period


Lower than Approach B since more duplicated data is sent back when supporting multiple iterations during transition period




From: Jasdip Singh <jasdips@arin.net>
Date: Monday, June 6, 2022 at 10:05 PM
To: "regext@ietf.org" <regext@ietf.org>
Subject: RDAP Extensions Approach Analysis v2

Hi.

Please find below the revised analysis of the current approach (A) and the 2 newly proposed approaches (B and C) for RDAP extensions [1]. Hopefully, the considered change scenarios are now granular enough ( @Mario :) ).

My high-level observations:

  1.  Approach C is much better than Approach B.
  2.  That said, would still go with Approach A since it consistently prevents naming collisions for all change scenarios and affords sufficient transition time for clients to “upgrade” to the next iteration of an extension. The latter -- graceful upgrade -- could be quite important to most, if not all, customers of the RDAP service at an RIR or a DNR, to the point of being an operational requirement. The former – consistently preventing naming collisions – helps keep the model simple, albeit at the expense of occasionally sending more data in responses.
  3.  Approach C is closer to Approach A than to Approach B but requires a careful scenario-by-scenario analysis to determine the need for a new prefix(es), and that could be problematic at times. I think it’d come down to (sunk) cost versus benefit when choosing between sticking with Approach A or moving to Approach C.

Please feel free to rectify this analysis. :) Hopefully, the discussion could converge for the considered change scenarios.

Thanks,
Jasdip

[1] https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit?usp=sharing

---


RDAP Extensions Analysis v2


Approaches<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.x3za3x81059e>

Change Scenario Analysis<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.zi62z1sce607>

Aspect Analysis<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.ogk4tkhrldq5>

Approaches


Approach A: Tight coupling between extension identifier and rdapConformance


Extension identifier = <opaque identifier>

  No version semantics

  Registered in the IANA RDAP Extensions registry

  A new spec provided for each new iteration of the extension

rdapConformance = <extension identifier>


Extension identifier used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)


Note: The phrase “new iteration” here simply connotes a new opaque identifier for an extension when it evolves.


Approach B: Lack of tight coupling between extension identifier and rdapConformance


Extension identifier = <prefix>

  Registered in the IANA RDAP Extensions registry

rdapConformance = <prefix>[<version (suffix)>]   [ ] means optional

  Needs version (suffix) semantics

  Registered in the IANA RDAP Extensions registry (or perhaps another registry for rdapConformance)

  A new spec provided for each new version of rdapConformance


Extension identifier used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)


Approach C: Decouple extension identifier from prefix(es) used for naming


Extension identifier = <opaque identifier>

  Registered in the IANA RDAP Extensions registry

  A new spec provided for each new iteration of the extension; lists prefix(es) used for naming

    Version semantics not needed for listed prefix(es)

rdapConformance = <extension identifier>


Listed prefix(es) used to prefix data member names, and in URIs (path segment, segment parameter, and/or query parameters)

Change Scenario Analysis

Legend:

ei - extension identifier

rc - rdapConformance value

p - prefix

u - URI

q - query parameter

s - segment

sp - segment parameter

d - data member


#


Change Scenario


Approach A - Tight coupling between extension identifier and rdapConformance


Approach B - Lack of tight coupling between extension identifier and rdapConformance


Approach C - Decouple extension identifier from prefix(es) used for naming


1


Add a URI path (no parameters yet)


ei = ext0 (registered)

rc = ext0

p = ext0 (new)


u0 = …/ext0/…


ei = ext (registered)

rc = ext0 (registered)

p = ext (new)


u0 = …/ext/…


ei = ext0 (registered)

rc = ext0

p = p0 (new)


u0 = …/p0/…


2


Add a path segment (s1)


ei = ext1 (registered)

rc = ext1

p = ext1 (new)


u1 = …/ext1/s1/…


Old URI u0 continues to exist during transition


ei = ext

rc = ext1 (registered)

p = ext


u1 = …/ext/s1/…


Clients still on rc ext0 when calling u0 break


ei = ext1 (registered)

rc = ext1

p = p1 (new)


u1 = …/p1/s1/…


Old URI u0 continues to exist during transition


3


Add a segment parameter (sp2)


ei = ext2 (registered)

rc = ext2

p = ext2 (new)


u2 = …/ext2/s1;sp2=.../…


ei = ext

rc = ext2 (registered)

p = ext


u2 = …/ext/s1;sp2=.../…


ei = ext2 (registered)

rc = ext2

p = p1


u2 = …/p1/s1;sp2=.../…


4


Rename a segment parameter (sp2 -> sp3)


ei = ext3 (registered)

rc = ext3

p = ext3 (new)


u3 = …/ext3/s1;sp3=.../…


Old URI u2 continues to exist during transition


ei = ext

rc = ext3 (registered)

p = ext


u3 = …/ext/s1;sp3=.../…


Clients still on rc ext2 when calling u2 break


ei = ext3 (registered)

rc = ext3

p = p3 (new)


u3 = …/p3/s1;sp3=.../…


Old URI u2 continues to exist during transition


5


Remove a path segment (s1)


ei = ext4 (registered)

rc = ext4

p = ext4 (new)


u4 = …/ext4/…


Old URI u3 continues to exist during transition


ei = ext

rc = ext4 (registered)

p = ext


u4 = …/ext/…


Clients still on rc ext3 when calling u3 break


ei = ext4 (registered)

rc = ext4

p = p4 (new)


u4 = …/p4/…


Old URI u3 continues to exist during transition


6


Add a required query parameter (q5)


ei = ext5 (registered)

rc = ext5

p = ext5 (new)


u5 = …/ext5/…?q5=...


Old URI u4 continues to exist during transition


ei = ext

rc = ext5 (registered)

p = ext


u5 = …/ext/…?q5=...


Clients still on rc ext4 when calling u4 break


ei = ext5 (registered)

rc = ext5

p = p5 (new)


u5 = …/p5/…?q5=...


Old URI u4 continues to exist during transition


7


Add an optional query parameter (q6)


ei = ext6 (registered)

rc = ext6

p = ext6 (new)


u6 = …/ext6/…?q5=...&q6=...


Old URI u5 continues to exist during transition


ei = ext

rc = ext6 (registered)

p = ext


u6 = …/ext/…?q5=...&q6=...


Clients still on rc ext5 when calling u5 do not break


ei = ext6 (registered)

rc = ext6

p = p5


u6 = …/p5/…?q5=...&q6=...


Clients still on rc ext5 when calling u5 do not break


8


Rename a required query parameter (q5 -> q7)


ei = ext7 (registered)

rc = ext7

p = ext7 (new)


u7 = …/ext7/…?q7=...&q6=...


Old URI u6 continues to exist during transition


ei = ext

rc = ext7 (registered)

p = ext


u7 = …/ext/…?q7=...&q6=...


Clients still on rc ext6 when calling u6 break


ei = ext7 (registered)

rc = ext7

p = p7 (new)


u7 = …/p7/…?q7=...&q6=...


Old URI u6 continues to exist during transition


9


Rename an optional query parameter (q6 -> q8)


ei = ext8 (registered)

rc = ext8

p = ext8 (new)


u8 = …/ext8/…?q7=...&q8=...


Old URI u7 continues to exist during transition


ei = ext

rc = ext8 (registered)

p = ext


u8 = …/ext/…?q7=...&q8=...


Clients still on rc ext7 when calling u7 break


ei = ext8 (registered)

rc = ext8

p = p8 (new)


u8 = …/p8/…?q7=...&q8=...


Old URI u7 continues to exist during transition


10


Add a new data member (object class, array, number, string, and/or literal) (d object) for a new response


ei = ext9 (registered)

rc = ext9

p = ext9 (new)


u9 = …/ext9/…?q7=...&q8=...


Old URI u8 continues to exist during transition


u9_d = …/ext9_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “ext9_d” : {

    “d0” : “a”

  }

}


ei = ext

rc = ext9 (registered)

p = ext


u8 = …/ext/…?q7=...&q8=...


u9_d = …/ext_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “ext_d” : {

    “d0” : “a”

  }

}


ei = ext9 (registered)

rc = ext9

p = p8


u8 = …/p8/…?q7=...&q8=...


u9_d = …/p8_d/…


{

  “rdapConformance” : [

    …,

    “ext9”

  ],

  “p8_d” : {

    “d0” : “a”

  }

}


11


Add a required data member (d1) to an existing response


ei = ext10 (registered)

rc = ext10

p = ext10 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “ext10_d1” : 8

}


ei = ext

rc = ext10 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “ext_d1” : 8

}


ei = ext10 (registered)

rc = ext10

p = p10 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”

  ],

  …,

  “p10_d1” : 8

}


12


Add an optional data member (d2) to an existing response


ei = ext11 (registered)

rc = ext11

p = ext11 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext10”,

    “ext11”

  ],

  …,

  “ext10_d1” : 8,

  “ext11_d1” : 8,

  “ext11_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break, at the expense of sending duplicate data for ext10


ei = ext

rc = ext11 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”

  ],

  …,

  “ext_d1” : 8,

  “ext_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break


ei = ext11 (registered)

rc = ext11

p = p10


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”

  ],

  …,

  “p10_d1” : 8,

  “p10_d2” : “abc”

}


Clients still on rc ext10 when calling u10 do not break


13


Rename a required data member (d1 -> d3)


ei = ext12 (registered)

rc = ext12

p = ext12 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”,

    “ext12”

  ],

  …,

  “ext11_d1” : 8,

  “ext11_d2” : “abc”,

  “ext12_d3” : 8,

  “ext12_d2” : “abc”

}


Clients still on rc ext11 when calling u10 do not break, at the expense of sending duplicate data for ext11


ei = ext

rc = ext12 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext12”

  ],

  …,

  “ext_d3” : 8,

  “ext_d2” : “abc”

}


Clients still on rc ext11 when calling u10 break


ei = ext12 (registered)

rc = ext12

p = p12 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext11”,

    “ext12”

  ],

  …,

  “p10_d1” : 8,

  “p10_d2” : “abc”,

  “p12_d3” : 8,

  “p12_d2” : “abc”

}


Clients still on rc ext11 when calling u10 do not break, at the expense of sending duplicate data for ext11


14


Modify a required data member’s type (d3 number -> string)


ei = ext13 (registered)

rc = ext13

p = ext13 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext12”,

    “ext13”

  ],

  …,

  “ext12_d3” : 8,

  “ext12_d2” : “abc”,

  “ext13_d3” : “def”,

  “ext13_d2” : “abc”

}


Clients still on rc ext12 when calling u10 do not break, at the expense of sending duplicate data for ext12


ei = ext

rc = ext13 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d2” : “abc”

}


Clients still on rc ext12 when calling u10 break


ei = ext13 (registered)

rc = ext13

p = p13 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext12”,

    “ext13”

  ],

  …,

  “p12_d3” : 8,

  “p12_d2” : “abc”,

  “p13_d3” : “def”,

  “p13_d2” : “abc”

}


Clients still on rc ext12 when calling u10 do not break, at the expense of sending duplicate data for ext12


15


Rename an optional data member (d2 -> d4)


ei = ext14 (registered)

rc = ext14

p = ext14 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”,

    “ext14”

  ],

  …,

  “ext13_d3” : “def”,

  “ext13_d2” : “abc”,

  “ext14_d3” : “def”,

  “ext14_d4” : “abc”

}


Clients still on rc ext13 when calling u10 do not break, at the expense of sending duplicate data for ext13


ei = ext

rc = ext14 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext14”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d4” : “abc”

}


Clients still on rc ext13 when calling u10 break if they were processing the optional data member


ei = ext14 (registered)

rc = ext14

p = p14 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext13”,

    “ext14”

  ],

  …,

  “p13_d3” : “def”,

  “p13_d2” : “abc”,

  “p14_d3” : “def”,

  “p14_d4” : “abc”

}


Clients still on rc ext13 when calling u10 do not break, at the expense of sending duplicate data for ext13


16


Modify an optional data member’s type (d4 string -> number)


ei = ext15 (registered)

rc = ext15

p = ext15 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext14”,

    “ext15”

  ],

  …,

  “ext14_d3” : “def”,

  “ext14_d4” : “abc”,

  “ext15_d3” : “def”,

  “ext15_d4” : 16

}


Clients still on rc ext14 when calling u10 do not break, at the expense of sending duplicate data for ext14


ei = ext

rc = ext15 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”

  ],

  …,

  “ext_d3” : “def”,

  “ext_d4” : 16

}


Clients still on rc ext14 when calling u10 break if they were processing the optional data member


ei = ext15 (registered)

rc = ext15

p = p15 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext14”,

    “ext15”

  ],

  …,

  “p14_d3” : “def”,

  “p14_d4” : “abc”,

  “p15_d3” : “def”,

  “p15_d4” : 16

}


Clients still on rc ext14 when calling u10 do not break, at the expense of sending duplicate data for ext14


17


Remove a required data member (d3)


ei = ext16 (registered)

rc = ext16

p = ext16 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”,

    “ext16”

  ],

  …,

  “ext15_d3” : “def”,

  “ext15_d4” : 16,

  “ext16_d4” : 16,

}


Clients still on rc ext15 when calling u10 do not break, at the expense of sending duplicate data for ext15


ei = ext

rc = ext16 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”

  ],

  …,

  “ext_d4” : 16

}


Clients still on rc ext15 when calling u10 break


ei = ext16 (registered)

rc = ext16

p = p16 (new)


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext15”,

    “ext16”

  ],

  …,

  “p15_d3” : “def”,

  “p15_d4” : 16,

  “p16_d4” : 16,

}


Clients still on rc ext15 when calling u10 do not break, at the expense of sending duplicate data for ext15


18


Remove an optional data member (d4)


ei = ext17 (registered)

rc = ext17

p = ext16


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”,

    “ext17”

  ],

  …,

  “ext16_d4” : 16

}


Clients still on rc ext16 when calling u10 do not break, at the expense of sending data for ext16


Note: This would be the case when phasing out jcard


ei = ext

rc = ext17 (registered)

p = ext


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext17”

  ],

  …

}


Clients still on rc ext16 when calling u10 break if they were processing the optional data member


ei = ext17 (registered)

rc = ext17

p = p16


u10 = …/…


{

  “rdapConformance” : [

    …,

    “ext16”,

    “ext17”

  ],

  …,

  “p16_d4” : 16

}


Clients still on rc ext16 when calling u10 do not break, at the expense of sending data for ext16


19


Remove a required query parameter (q7)


ei = ext18 (registered)

rc = ext18

p = ext18 (new)


u18 = …/ext18/…?q8=...


Old URI u9 continues to exist during transition


ei = ext

rc = ext18 (registered)

p = ext


u18 = …/ext/…?q8=...


Clients still on rc ext9 when calling u8 break


ei = ext18 (registered)

rc = ext18

p = p18 (new)


u18 = …/p18/…?q8=...


Old URI u8 continues to exist during transition


20


Remove an optional query parameter (q8)


ei = ext19 (registered)

rc = ext19

p = ext19 (new)


u19 = …/ext19/…


Old URI u18 continues to exist during transition


ei = ext

rc = ext19 (registered)

p = ext


u19 = …/ext/…


Clients still on rc ext18 when calling u18 break


ei = ext19 (registered)

rc = ext19

p = p19 (new)


u19 = …/p19/…


Old URI u18 continues to exist during transition


21


Remove a URI path (u19)


ei = ext20 (registered)

rc = ext20

p = ext19


u19 = …/ext19/…


Old URI u19 continues to exist during transition, and not beyond


ei = ext

rc = ext20 (registered)

p = ext


u19 = …/ext/…


Old URI u19 continues to exist during transition, and not beyond


ei = ext20 (registered)

rc = ext20

p = p19


u19 = …/p19/…


Old URI u19 continues to exist during transition, and not beyond


22


Add a query parameter (q9) to an existing, non-extension URI


ei = ext21 (registered)

rc = ext21

p = ext21 (new)


u21 = …?ext21_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


ei = ext

rc = ext21 (registered)

p = ext


u21 = …?ext_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


ei = ext21 (registered)

rc = ext21

p = p21 (new)


u21 = …?p21_q9=...


{

  “rdapConformance” : [

    …,

    “ext21”

  ],

  …

}


23


Remove a query parameter (q9) from an existing, non-extension URI, as well as add a query parameter (q10) to it


ei = ext22 (registered)

rc = ext22

p = ext22 (new)


u22 = …?ext21_q9=...&ext22_q10=...


{

  “rdapConformance” : [

    …,

    “ext21”,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 do not break


ei = ext

rc = ext22 (registered)

p = ext


u22 = …?ext_q10=...


{

  “rdapConformance” : [

    …,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 break


ei = ext22 (registered)

rc = ext22

p = p22 (new)


u22 = …?p21_q9=...&p22_q10=...


{

  “rdapConformance” : [

    …,

    “ext21”,

    “ext22”

  ],

  …

}


Clients still on rc ext21 when calling u22 do not break


Aspect Analysis


#


Aspect


Approach A - Tight coupling between extension identifier and rdapConformance


Approach B - Lack of tight coupling between extension identifier and rdapConformance


Approach C - Decouple extension identifier from prefix(es) used for naming


1


Providing a new spec to IANA for a new iteration of an extension


Registry stays as-is


Few non-compliant registrations need to be remedied


Registry needs to evolve for:


  Versioned rdapConformance


  Tying spec to versioned rdapConformance


Registry stays as-is


Prefix(es) listed in the spec


2


Risk of breaking changes for RDAP clients


Minimal since it would always be a controlled upgrade to the next iteration of an extension with sufficient transition time


Most risky out of all the approaches since there is no controlled way to upgrade for quite a few change scenarios<https://docs.google.com/document/d/1e3QD8z01KpYRd5LwdLBWjHHDoFVAVEL8u7Y52zsDdx0/edit#heading=h.zi62z1sce607>


Risk is minimal, like for approach A


However, requires carefully identifying the need for a new prefix on scenario-by-scenario basis; otherwise inadvertent mistakes possible


3


Cost of reprogramming clients for the next iteration of an extension


There is cost but not as high as it seems — replacing extension identifier in multiple places, and accounting for primarily query parameter and data member changes


Longer grace period for clients to reprogram if the server supports multiple iterations of an extension during transition


Reprogramming could become exigent for clients if the server switches to the new iteration without supporting the previous iteration


Cost slightly lower than that for Approach A — replacing prefixes for a majority (but not all) of scenarios


4


Cost of reprogramming servers for the next iteration of an extension


Highest cost — to simultaneously support multiple iterations during transition period, replicating code from the previous iteration and replacing extension identifier in multiple places, and accounting for primarily query parameter and data member changes


Eventually retiring code for the previous iteration


Lowest cost since only the latest iteration is supported


Cost is lower than for that for Approach A but not too low — for a majority (but not all) of scenarios, to simultaneously support multiple iterations during transition period, replicating code from the previous iteration and replacing prefixes in multiple places, and accounting for primarily query parameter and data member changes


Eventually retiring code for the previous iteration


5


Server-side signaling of the next iteration of an extension


Add the new value of the rdapConformance in the help response and related responses


Make new URIs available


Add the new value of the rdapConformance in the help response and related responses


No change in URIs for the new value of the rdapConformance


Add the new value of the rdapConformance in the help response and related responses


To a lower extent than Approach A, make new URIs available


6


Collisions risk


Zero since the new extension identifier is explicitly marked in data members and URIs


High since the new iteration of an extension is not marked in data members and URIs, and is only discoverable through the rdapConformance value in a response


Zero since the new prefix is explicitly marked in data members and URIs, just like the new extension identifier in Approach A