[SSS] Creating an RSS feed

:  ~ 1 min read

Back when the blog was written in Ruby, I wrote that I eventually went ahead and implemented an RSS feed, and that it was much easier than expected. Turns out I didn't even need a library to do it, it's only a matter of creating an XML document.

Sure, it might be prettier to assign properties (e.g rss.item.content = "content here") versus creating the document manually (e.g xml += <content>content here</content>), but with proper formatting, the latter can look pretty great too. Besides, printing the document, or looking at the source in a browser will be easier to track / spot bugs.

Let's start with adding the route to our droplet:

func addRoutes() -> Droplet {
	get("/feed", handler: FeedController.create)
	// [...]

Let's now create our Feed controller, that needs to have a method with the same signature as the handler:

struct FeedController {

	static func create(with request: Request) throws -> ResponseRepresentable {

		// 1
		let posts = try Post.query().sorted().run()

		guard !posts.isEmpty else { return Response(redirect: "/") }

		// 2
		request.setValue("application/xml", forHTTPHeaderField: "Content-Type")

		// 3
		var xml = ""
		xml += "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
		xml += "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
		xml += "<title type=\"text\">Roland Leth</title>\n"
		// [...]

		posts.forEach {
			xml += "<entry>\n"
			// 4
			xml += "\t<id>\(url)</id>\n" // 5
			xml += "\t<title>\($0.title)</title>\n"
			// [...]

			xml += "</entry>\n"

		xml += "</feed>"

		return xml // 6

In here, we have to set the content type to XML (2), fetch the posts (1), and create our document, bit by bit (3), finally returning the xml string (6).

This might be a lot of xml += ... typing, but it keeps everything nicely aligned. Also, the hassle of adding tabs (4) and new lines (5) all over the place will pay off when printing / looking at the source in a browser. You can check the whole file here.