Skip to content

Commit b9f4d55

Browse files
Guidance on extensibility patterns: main spec revision vs registries vs URIs (#596)
This includes a lot of advice on how to define registries and defines the "extension point" term. Co-authored-by: Martin Thomson <mt@lowentropy.net>
1 parent 031a3de commit b9f4d55

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

index.bs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3708,6 +3708,167 @@ and makes it clear when the state described by the flags is reset.
37083708

37093709
<!-- TODO: add examples -->
37103710

3711+
<h3 id="registries">Plan for future extensibility through main spec updates if possible; otherwise use a registry</h3>
3712+
3713+
When you expect a feature to need to be extended over time,
3714+
choose a kind of extensibility based on the kinds of changes you expect.
3715+
Revisions of the main standard are simplest and most coherent,
3716+
but use a registry when you need a wider set of participants to be able to define extensions.
3717+
3718+
[[spec-variability#variability|"Variability complicates interoperability."]]
3719+
When a feature needs optional components,
3720+
it is easiest to manage the complication if
3721+
a single group is in charge of the whole design.
3722+
This implies that most optional features should be defined
3723+
in the same specification that defined the original feature.
3724+
If new extensions are needed in the future,
3725+
it is often most appropriate
3726+
to define them by revising the original specification.
3727+
This reduces the need to precisely define requirements for extensions.
3728+
3729+
If implementers need to be able to add extensions
3730+
without going through the full specification revision process,
3731+
a registry is usually the right way to manage the known extensions.
3732+
Default to defining either
3733+
an IANA registry governed by [[RFC8126]] or a [[w3c-process#registries|W3C Registry]].
3734+
3735+
The place in a specification that dispatches to an extension's implementation
3736+
is known as an <dfn export>extension point</dfn>.
3737+
To maximize the chance that a specification with extension points is interoperably implemented,
3738+
each extension point should
3739+
3740+
* define how to uniquely identify extensions,
3741+
* define how implementations can negotiate which extensions are acceptable or
3742+
what to do with unrecognized extensions
3743+
(see [[RFC6709#section-4|section 4 of RFC6709]]),
3744+
* define what interface extensions are supposed to implement, and
3745+
* link to a specification of each extension that is
3746+
detailed enough to support interoperable implementations of the extension,
3747+
as is required by
3748+
the IETF's [[RFC8126#section-4.6|Specification Required]] registration policy.
3749+
3750+
Registries help because they
3751+
3752+
* create a place where extension developers can coordinate
3753+
the allocation of identifiers for their extensions,
3754+
* provide a place for implementers to find extension specifications
3755+
(if the registry requires this), and
3756+
* help readers discover when existing extensions address their needs.
3757+
3758+
It is tempting to additionally require that registry entries be
3759+
"good" in some way beyond what is needed to achieve interoperability.
3760+
Whether this can succeed depends on the ecosystem and the expected implementers.
3761+
Implementers are most likely to be willing to
3762+
navigate a demanding registration process and
3763+
constrain their implementations to match strict registration requirements
3764+
when they are a small set, well-resourced, and generally-aligned,
3765+
as in the case of web browser engines.
3766+
The more diverse or constrained implementers become,
3767+
the less you can expect them to consistently work to register extensions.
3768+
3769+
At the limit, implementers might not even be willing to document their extensions.
3770+
If the specification authors consider this likely, it may be worth allowing
3771+
[[rfc8126#section-4.4|first-come-first-served registrations without a specification]]
3772+
just to reduce the risk of name collisions,
3773+
although the registry should still encourage full specifications.
3774+
3775+
In the case of a registry that doesn't require specifications,
3776+
it can be tempting to identify extensions with URLs or URIs instead of registered strings.
3777+
This has the effect of defining a [[rfc8126#section-4.3|hierarchical registration policy]]
3778+
and making it very easy to extend the feature,
3779+
by just picking a URL from a domain that the extender controls.
3780+
This clearly loses the interoperability benefits of requiring a specification,
3781+
and in the case of DNS-based URLs,
3782+
it also risks that the entity that defined the extension may lose control of its domain.
3783+
URIs are appropriate for a few kinds of very-low-coordination extension,
3784+
such as the definition of an XML namespace [[XML-NAMES]],
3785+
but most of the time a WG-managed permissive registry table will work better.
3786+
3787+
Because an [=extension point=] defines an interface,
3788+
and it's difficult to be confident in an interface definition
3789+
before that interface has several implementations,
3790+
any new registry should start with more than one entry defined.
3791+
3792+
Consider the case of two implementations
3793+
that implement non-overlapping subsets
3794+
of the defined extensions for a given extension point.
3795+
If operating the feature requires that implementations
3796+
choose an extension that they both support,
3797+
implementations that support non-overlapping subsets cannot interoperate.
3798+
To avoid such failures, the registry must include at least 1 entry
3799+
that all implementations are required to support.
3800+
3801+
<div class=example heading="Well-Known URIs" id="example-well-known">
3802+
3803+
The [Well-Known URI registry](https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml),
3804+
defined by [[RFC8615]],
3805+
ensures that protocols don't collide when allocating a path in all web servers.
3806+
3807+
Part of the purpose of HTTP and similar URL schemes
3808+
is to allow new capabilities to be defined that use the core protocol,
3809+
without requiring an update to the core specification.
3810+
When information is needed about an entire origin,
3811+
the only need for coordination as a whole comes from avoiding the possibility of name collisions.
3812+
Since the registry itself mitigates that risk,
3813+
there isn't a need for the whole HTTP community
3814+
to agree on a new HTTP revision for each registration.
3815+
3816+
The registry's requirement for a specification isn't too much of a burden
3817+
because these cross-origin protocols
3818+
tend to be defined by an agreement between the participating origins,
3819+
which is documented in a specification.
3820+
3821+
</div>
3822+
3823+
Registries can get complicated,
3824+
especially when implementers work around mistakes in the registration requirements.
3825+
They're still usually better than providing no place to list extensions.
3826+
3827+
<div class="example" heading="Link Relations" id="example-link-relation-registry">
3828+
3829+
Link relations are currently registered in a 3-part registry.
3830+
[[rfc8288#procedure|RFC 8288]] defines the [[IANA-RELATIONS inline]] registry
3831+
which accepts entries that "reference a freely available, stable specification."
3832+
[[MFREL inline]] defines a second registry
3833+
to which anyone with a wiki account can add.
3834+
This registry has a column for specifications,
3835+
but nobody enforces that the column is filled in
3836+
or that the specifications meet any particular quality requirements.
3837+
[[html#linkTypes]] then repeats a subset of these relation types
3838+
to define how they work in web browsers.
3839+
3840+
In an ideal world, [[RFC8288]] and [[MFREL inline]] would probably be a single registry,
3841+
with [[html#linkTypes|HTML]] defining browser behavior.
3842+
3843+
The idea of <{a/rel}> as list of externally-defined keywords
3844+
dates to at least [[rfc1866 inline obsolete]], in 1995, which said
3845+
3846+
> The REL attribute gives the relationship(s) described by the hyperlink.
3847+
> The value is a whitespace separated list
3848+
> of relationship names. The semantics of link
3849+
> relationships are not specified in this document.
3850+
3851+
The [[html401 inline]], in 1999,
3852+
defined a list of [known link relations](https://www.w3.org/TR/html401/types.html#type-links)
3853+
but continued to encourage authors to invent their own.
3854+
3855+
The IETF eventually defined the IANA registry in [[rfc4287 inline]], in 2005,
3856+
and [[rfc5988 inline obsolete]], in 2010.
3857+
These required specifications and expert review,
3858+
but by this time too many custom link relations were in use
3859+
to get them all specified and registered.
3860+
Even if the registry had been in place from the beginning,
3861+
we believe this is a case where implementers are too diverse
3862+
to even know what kind of specification to expect for registered elements.
3863+
The modern [[html#linkTypes|HTML]] table
3864+
is a good way to align browser implementations
3865+
on the subset of link relations that they react to.
3866+
3867+
</div>
3868+
3869+
See [[qaframe-spec#extensions]] and [[RFC6709]] for
3870+
more guidance on how to design extensibility.
3871+
37113872
<h3 id="implementability">Resolving tension between interoperability and implementability</h3>
37123873

37133874
<!--

0 commit comments

Comments
 (0)