]> git.r.bdr.sh - rbdr/blog/blobdiff - doc/specs/20200601-serving-different-versions.md
Add the spec for this feature
[rbdr/blog] / doc / specs / 20200601-serving-different-versions.md
diff --git a/doc/specs/20200601-serving-different-versions.md b/doc/specs/20200601-serving-different-versions.md
new file mode 100644 (file)
index 0000000..351cc8c
--- /dev/null
@@ -0,0 +1,198 @@
+# Problem
+
+Feed reader users should be able to subscribe to the blog
+
+# Background
+
+As of this writing, the blog is served as HTML which is appropriate for
+web browsers but maybe not for other mechanisms like feed readers.
+
+Feed readers have different formats that they support:
+  * h-feed is a microformat built into the page
+  * rss and atom are XML based publishing formats
+  * JSON feed is a JSON based publishing format
+  * rss 3.0 is a text based pblishing format :P
+
+Currently the blog contains a single generator function that copies
+assets and generates HTML out of markdown files. This is good enough for
+the current setup, but if it were to generate more it would get messy
+real quick.
+
+Given the constraints listed below, some formats are not recommended:
+  * RSS 3.0 is not a good candidate at the moment as it would require
+    us to parse the markdown to extract the title.
+  * Atom would work, however, given the requirement for an id, title, and
+    date this would require more effort than a more lenient format.
+  * RSS 2.0 fits the constraints as we wouldn't need to specify anything
+    for the item.
+  * JSON Feed would work, however given the requirement for an id, thtis
+    would require more effort than a more lenient format.
+
+It is unclear whether the current constraints are good enough for feed
+readers. If this causes issues, it's likely we will have to include date,
+id or title as required in the other formats.
+
+After reviewing the functionality of existing readers, it has been found
+that an id and publication date would be needed for readers to behave
+correctly. This means that ATOM and JSON Feed would be equally valid
+as solutions than RSS 2.0
+
+The current generator function depends on knowing a source for the post
+being generated, and a target on where the assets will be placed.
+
+# Hypothesis
+
+Given we serve the blog in a feed reader friendly format, users will be able to subscribe.
+
+# Test of Hypothesis
+
+Given I add the blog to a feed reader service like Reeder or Feedly, I will be able to see the entries.
+Given I add a new entry to the blog, the entries will be updated.
+
+# Assumptions
+
+* We can generate a valid feed with just the entries themselves and the existing
+  blog data.
+  * We can: Validated by generating an example file.
+* Including just a list of items with the whole content is good enough for
+  feed readers.
+  * We can't: It seems like we'll require at least a guid. The old reader
+    behaves correctly with just the guid. It's unclear whether feedly
+    does since it has caching. Will leave grok running.
+* It isn't required to link back, and we can include the whole text.
+  * This is correct, however it might make sense to just link to the
+    blog itself.
+
+# Constraints
+
+* We won't be parsing the markdown to generate feed items.
+* We won't be adding any sort of frontmatter to the entries.
+* The blog will remain ephemeral, and we won't introduce permalinks.
+* We won't have configurable templating or options to add/remove
+  output types.
+
+# Solution Proposal
+
+(Note: This solution is incomplete. We need to add guid and pubDate
+generation, as this is required for the RSS to be usable)
+
+We will split the current generator function into generators, and create
+a new generator that will generate an RSS 2.0 file
+
+# Blackbox
+
+```
+                      ┌─────────────────┐           ┌───────────────┐
+                      │                 │           │               │
+               ┌─────▶│ StaticGenerator │──────────▶│ Static Assets │
+               │      │                 │           │               │
+               │      └─────────────────┘           └───────────────┘
+┌───────┐      │      ┌───────────────┐             ┌───────────┐
+│       │      │      │               │             │           │
+│ Blog  │──────┼─────▶│ HTMLGenerator │────────────▶│ HTML File │
+│       │      │      │               │             │           │
+└───────┘      │      └───────────────┘             └───────────┘
+               │      ┌──────────────┐              ┌──────────┐
+               │      │              │              │          │
+               └─────▶│ RSSGenerator │─────────────▶│ RSS File │
+                      │              │              │          │
+                      └──────────────┘              └──────────┘
+```
+
+# Theory of Operation
+
+When the generate function of the blog is triggered, it will iterate over
+a list of generator functions and call them with the source and target
+directories, and an array containing the parsed markdown from the post.
+Each generator function will do its work, throwing an exception if they
+encounter an error.
+
+When the static generator is called, it will remove the current assets
+directory in the target directory, and recursively copy the assets from
+the source directory.
+
+When the HTML generator is called, it will parse an `html` template, using
+the posts as the context, and will place the resulting file in the target
+directory.
+
+When the RSS generator is called, it will parse an `rss` template, using
+the posts as the context, and will place the resulting file in the target
+directory.
+
+# Technical Specification
+
+## The Generator Interface
+
+Every generator must implement this interface in order to work with
+Blog.
+
+* Generators MUST be a function
+* Generators SHOULD read the source, destination, and posts parameters to
+  write files.
+* Generators MUST NOT write anything into the source directory
+* Generators MUST return a promise
+* Generators SHOULD NOT resolve the promise with any information, as it will
+  be discarded
+* Generators MUST throw exceptions if they encounter an unrecoverable error
+
+```
+IGenerator(source<String>, destination<String>, posts<Array<String>>) => Promise
+```
+
+## New Generators
+
+### Static Generator
+
+This generator will have the logic to move static assets around. It will
+re-use the current asset logic in the `#_generate` method in Blog.
+
+```
+StaticGenerator <IGenerator>
+```
+
+### HTML Generator
+
+This generator will have the logic to generate an HTML file. It will
+re-use the current HTML logic in the `#_generate` method in Blog.
+
+```
+HTMLGenerator <IGenerator>
+```
+
+### RSS Generator
+
+This generator will have the logic to generate an RSS file. It will
+re-use the current HTML logic in the `#_generate` method in Blog,
+however, instead of using the `index.html` template it will use a
+`feed.xml` template that generates a valid RSS 2.0 feed document.
+
+```
+RSSGenerator <IGenerator>
+```
+
+## Modifications to existing parts of the code
+
+The `#_generate` function will be modified so it will now parse the
+post markdown, and then iterate over the generators, calling them 
+so they create the appropriatet files.
+
+## Important Metrics
+
+Given we're only processing 3 blog posts, and this is a compile time
+activity and not runtime, there are no recommended metrics in terms
+of file throughput performance or runtime performance.
+
+This should change if this would ever handle a higher volume, or would
+be expected to run this process runtime.
+
+## Furhter Improvements
+
+It's recommended to eventually put more effort in assigning a unique ID
+to each post so we can use more feed formats.
+
+For more compatibility and future proofing, the same solution for
+RSS could be used to generate other feed formats, just adding
+a new generator
+
+This same solution could be extended to serve the blog in different formats
+(eg. a .txt that is easy to read in terminals)