Skip to content

Commit 062da41

Browse files
committed
docs: Add slot naming and life cycle ADR
1 parent 73ab604 commit 062da41

File tree

1 file changed

+159
-0
lines changed

1 file changed

+159
-0
lines changed
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
====================================
2+
3. Plugin Slot Naming and Life Cycle
3+
====================================
4+
5+
Status
6+
======
7+
8+
Proposed
9+
10+
11+
Context
12+
=======
13+
14+
The Frontend Plugin Framework introduced the concept of plugin slots as a way
15+
to customize micro-frontends. Slots are defined in each applications codebase
16+
with React, currently taking the following form:
17+
18+
<PluginSlot id="arbitrary_slot_name">
19+
...
20+
</PluginSlot>
21+
22+
Operators can subsequently insert plugins into this slot by referencing the
23+
slot name in configuration, "arbitrary_slot_name":
24+
25+
pluginSlots: {
26+
arbitrary_slot_name: {
27+
plugins: [{
28+
op: PLUGIN_OPERATIONS.Insert,
29+
widget: {
30+
id: 'arbitrary_plugin_name',
31+
...
32+
}
33+
}]
34+
}
35+
}
36+
37+
However, the following concerns are identified with regard to completely
38+
arbitrary slot names:
39+
40+
1. The codebase can become progressively littered with slot names that are
41+
unintuitively or inconsistently named, making it harder to document,
42+
maintain, and use them
43+
44+
2. There is no expectation that one should be able to infer purpose and
45+
location from the slot name
46+
47+
3. While Frontend Plugin Framework supports defining multiple slots with the
48+
same name in a frontend application, as the number of slots across the
49+
codebase increases it becomes harder and harder for developers to avoid
50+
introducing accidental name collisions
51+
52+
4. Without a versioning scheme, there's no way to modify a slot's API without
53+
an implicit breaking change
54+
55+
This is a common problem in computer science, one that has often been addressed
56+
by use of `reverse domain name notation`_. It can be seen everywhere, from
57+
Android package names to Open edX's own specification for `server event
58+
types`_.
59+
60+
.. _reverse domain name notation: https://en.wikipedia.org/wiki/Reverse_domain_name_notation
61+
.. _server event types: https://docs.openedx.org/projects/openedx-proposals/en/latest/architectural-decisions/oep-0041-arch-async-server-event-messaging.html#id5
62+
63+
This technique allows for both namespace uniqueness and a self-documentated
64+
hierarchy. For instance, take this fictitious slot name that uses reverse
65+
domain notation:
66+
67+
org.openedx.frontend.layout.header.v1
68+
69+
Even without any further information, it's possible to tell that:
70+
71+
* The slot belongs to an app in the Open edX org
72+
* It's a frontend app
73+
* It applies to the app's layout module
74+
* The slot probably wraps the header
75+
* This is version 1 of the slot, which indicates changes are possible in the
76+
future
77+
78+
And last but not least:
79+
80+
* There's little chance that a slot with the same name exists anywhere in the
81+
codebase other than where the layout header is defined
82+
83+
Based on this concept, this ADR aims to define rules that govern how developers
84+
maintain plugin slots in Open edX frontend apps throughout their lifecycle. In
85+
particular:
86+
87+
* When adding new slots
88+
* When deprecating and removing slots
89+
90+
91+
Decisions
92+
=========
93+
94+
1. Naming format
95+
----------------
96+
97+
The full name of a plugin slot will be a ``string`` that follows the following
98+
format:
99+
100+
{Reverse DNS}.{Subdomain}.{Module}.{Identifier}.{Version}
101+
102+
Where:
103+
104+
* *Reverse DNS* is always ``org.openedx``
105+
* *Subdomain* is always ``frontend``
106+
* *Module* denotes the frontend module where the slot is exposed, such as
107+
``courseware``, or ``authoring``
108+
* *Identifier* is a snake-case string that identifies the slot, which must be
109+
unique for the module that contains it
110+
* *Version* is a monotonically increasing integer prefaced by a `v`, starting
111+
with `v1`.
112+
113+
For example:
114+
115+
* org.openedx.frontend.layout.footer.v1
116+
* org.openedx.frontend.courseware.navigation_sidebar.v2
117+
118+
2. Versioning
119+
-------------
120+
121+
For the purposes of versioning, a given slot's API contract is comprised of:
122+
123+
* Its location, visual or otherwise, in the Module
124+
* The type (but not implementation!) of the content it is expected to wrap
125+
* The specific set of `pluginProps` it exposes
126+
127+
If one of the above changes for a particular slot in such a way that existing
128+
plugins break or present undefined behavior, *and* if it still make sense to
129+
use the same Identifier, the version string appended to its name will be
130+
incremented by `1`.
131+
132+
Note: a given slot's default content is explicitly *not* part of its contract.
133+
Changes to it do not result in a version bump.
134+
135+
3. Deprecation process
136+
----------------------
137+
138+
When a slot changes sufficiently to require its version to be incremented, the
139+
developer will take care to:
140+
141+
* Propose the previous version's deprecation via the official Open edX
142+
Deprecation Process
143+
144+
* Keep the definition of the previously released version of the slot in the
145+
codebase for the duration of the deprecation process, which should include at
146+
least one Open edX release where it co-exists with the new version
147+
148+
* Implement the new version of the slot in such a way that coexists with the
149+
previous one with no detriment to either's functionality
150+
151+
152+
Consequences
153+
============
154+
155+
The decisions above are intend to let plugin authors create and maintain
156+
plugins that are stable across releases of Open edX, while also allowing slots
157+
themselves to evolve. The naming convention itself has no significant
158+
downsides, and while the deprecation process does add some maintenance burden,
159+
it is expected to be offset by the additional stability provided.

0 commit comments

Comments
 (0)