]> git.r.bdr.sh - rbdr/blog/blob - doc/specs/20200601-serving-different-versions.md
Add the spec for this feature
[rbdr/blog] / doc / specs / 20200601-serving-different-versions.md
1 # Problem
2
3 Feed reader users should be able to subscribe to the blog
4
5 # Background
6
7 As of this writing, the blog is served as HTML which is appropriate for
8 web browsers but maybe not for other mechanisms like feed readers.
9
10 Feed readers have different formats that they support:
11 * h-feed is a microformat built into the page
12 * rss and atom are XML based publishing formats
13 * JSON feed is a JSON based publishing format
14 * rss 3.0 is a text based pblishing format :P
15
16 Currently the blog contains a single generator function that copies
17 assets and generates HTML out of markdown files. This is good enough for
18 the current setup, but if it were to generate more it would get messy
19 real quick.
20
21 Given the constraints listed below, some formats are not recommended:
22 * RSS 3.0 is not a good candidate at the moment as it would require
23 us to parse the markdown to extract the title.
24 * Atom would work, however, given the requirement for an id, title, and
25 date this would require more effort than a more lenient format.
26 * RSS 2.0 fits the constraints as we wouldn't need to specify anything
27 for the item.
28 * JSON Feed would work, however given the requirement for an id, thtis
29 would require more effort than a more lenient format.
30
31 It is unclear whether the current constraints are good enough for feed
32 readers. If this causes issues, it's likely we will have to include date,
33 id or title as required in the other formats.
34
35 After reviewing the functionality of existing readers, it has been found
36 that an id and publication date would be needed for readers to behave
37 correctly. This means that ATOM and JSON Feed would be equally valid
38 as solutions than RSS 2.0
39
40 The current generator function depends on knowing a source for the post
41 being generated, and a target on where the assets will be placed.
42
43 # Hypothesis
44
45 Given we serve the blog in a feed reader friendly format, users will be able to subscribe.
46
47 # Test of Hypothesis
48
49 Given I add the blog to a feed reader service like Reeder or Feedly, I will be able to see the entries.
50 Given I add a new entry to the blog, the entries will be updated.
51
52 # Assumptions
53
54 * We can generate a valid feed with just the entries themselves and the existing
55 blog data.
56 * We can: Validated by generating an example file.
57 * Including just a list of items with the whole content is good enough for
58 feed readers.
59 * We can't: It seems like we'll require at least a guid. The old reader
60 behaves correctly with just the guid. It's unclear whether feedly
61 does since it has caching. Will leave grok running.
62 * It isn't required to link back, and we can include the whole text.
63 * This is correct, however it might make sense to just link to the
64 blog itself.
65
66 # Constraints
67
68 * We won't be parsing the markdown to generate feed items.
69 * We won't be adding any sort of frontmatter to the entries.
70 * The blog will remain ephemeral, and we won't introduce permalinks.
71 * We won't have configurable templating or options to add/remove
72 output types.
73
74 # Solution Proposal
75
76 (Note: This solution is incomplete. We need to add guid and pubDate
77 generation, as this is required for the RSS to be usable)
78
79 We will split the current generator function into generators, and create
80 a new generator that will generate an RSS 2.0 file
81
82 # Blackbox
83
84 ```
85 ┌─────────────────┐ ┌───────────────┐
86 │ │ │ │
87 ┌─────▶│ StaticGenerator │──────────▶│ Static Assets │
88 │ │ │ │ │
89 │ └─────────────────┘ └───────────────┘
90 ┌───────┐ │ ┌───────────────┐ ┌───────────┐
91 │ │ │ │ │ │ │
92 │ Blog │──────┼─────▶│ HTMLGenerator │────────────▶│ HTML File │
93 │ │ │ │ │ │ │
94 └───────┘ │ └───────────────┘ └───────────┘
95 │ ┌──────────────┐ ┌──────────┐
96 │ │ │ │ │
97 └─────▶│ RSSGenerator │─────────────▶│ RSS File │
98 │ │ │ │
99 └──────────────┘ └──────────┘
100 ```
101
102 # Theory of Operation
103
104 When the generate function of the blog is triggered, it will iterate over
105 a list of generator functions and call them with the source and target
106 directories, and an array containing the parsed markdown from the post.
107 Each generator function will do its work, throwing an exception if they
108 encounter an error.
109
110 When the static generator is called, it will remove the current assets
111 directory in the target directory, and recursively copy the assets from
112 the source directory.
113
114 When the HTML generator is called, it will parse an `html` template, using
115 the posts as the context, and will place the resulting file in the target
116 directory.
117
118 When the RSS generator is called, it will parse an `rss` template, using
119 the posts as the context, and will place the resulting file in the target
120 directory.
121
122 # Technical Specification
123
124 ## The Generator Interface
125
126 Every generator must implement this interface in order to work with
127 Blog.
128
129 * Generators MUST be a function
130 * Generators SHOULD read the source, destination, and posts parameters to
131 write files.
132 * Generators MUST NOT write anything into the source directory
133 * Generators MUST return a promise
134 * Generators SHOULD NOT resolve the promise with any information, as it will
135 be discarded
136 * Generators MUST throw exceptions if they encounter an unrecoverable error
137
138 ```
139 IGenerator(source<String>, destination<String>, posts<Array<String>>) => Promise
140 ```
141
142 ## New Generators
143
144 ### Static Generator
145
146 This generator will have the logic to move static assets around. It will
147 re-use the current asset logic in the `#_generate` method in Blog.
148
149 ```
150 StaticGenerator <IGenerator>
151 ```
152
153 ### HTML Generator
154
155 This generator will have the logic to generate an HTML file. It will
156 re-use the current HTML logic in the `#_generate` method in Blog.
157
158 ```
159 HTMLGenerator <IGenerator>
160 ```
161
162 ### RSS Generator
163
164 This generator will have the logic to generate an RSS file. It will
165 re-use the current HTML logic in the `#_generate` method in Blog,
166 however, instead of using the `index.html` template it will use a
167 `feed.xml` template that generates a valid RSS 2.0 feed document.
168
169 ```
170 RSSGenerator <IGenerator>
171 ```
172
173 ## Modifications to existing parts of the code
174
175 The `#_generate` function will be modified so it will now parse the
176 post markdown, and then iterate over the generators, calling them
177 so they create the appropriatet files.
178
179 ## Important Metrics
180
181 Given we're only processing 3 blog posts, and this is a compile time
182 activity and not runtime, there are no recommended metrics in terms
183 of file throughput performance or runtime performance.
184
185 This should change if this would ever handle a higher volume, or would
186 be expected to run this process runtime.
187
188 ## Furhter Improvements
189
190 It's recommended to eventually put more effort in assigning a unique ID
191 to each post so we can use more feed formats.
192
193 For more compatibility and future proofing, the same solution for
194 RSS could be used to generate other feed formats, just adding
195 a new generator
196
197 This same solution could be extended to serve the blog in different formats
198 (eg. a .txt that is easy to read in terminals)