Golinx Introduction
I recently wrote about the concept of reinventing the wheel, and when it’s ok to do that. Golinx is one of those projects. The idea is simple: to create a web-app that lets you define custom URL redirects and short-links for some other URL. For the first iteration of this idea, I’m writing a Python web app in Flask, bundling it into a Docker container with Bazel build rules, and haven’t yet figured out what deployment looks like. Below I explain more about the basic functionality of the project, as well as some of the concepts I’m really looking to explore. The project is nowhere near complete (and may never be), but my plan is to document design trade-offs, decisions and progress as I go in a series of posts.
Functionality
As I alluded to above, golinx is meant to mimic something like bit.ly:
- A custom link redirector:
https://go/foo-doc→https://example.com/long/foo/url/to/some/doc - A link shortner:
https://go/-f3yji5→https://example.com/some/long/url/you/need/to/tweet
The idea behind the first feature is that you’ll often be working together on a
project with shared documents that live at some long URL. Rather than relying
on a bookmark to visit or share the doc, you just create a shortcut like
foo-project-design that points to
https://docs.google.com/document/reallylonguuidthatisimpossibletoremember.
If golinx is hosted at “go.mycorp.com” and you’ve got DNS set up with a search
domain of “mycorp.com” (or simply just have a record for “go”), then your
employees can visit go/foo-project-design in their browser, and voila.
This simple feature is a huge timesaver, especially these days when practically
all productivity apps live on the web.
There are some nuances in how you handle path suffixes, URL fragments, and query
strings that I haven’t really thought through yet, but I think you’d either
merge components passed in the shortcut when possible, or override when not.
E.g. if your shortcut is foo → http://bar.com/foo#baz?quux then
golinx should support the following:
foo/a→http://bar.com/foo/a(discard fragment and query string since this is a sub-path which would point to a new page)foo#b→http://bar.com/foo#b?quux(override fragment, keep query string)foo?c→http://bar.com/foo#baz?quux&c(keep fragment, merge query string)foo/a#b?c→http://bar.com/foo/a#b?c(discard fragment and query string, append new values)
Usage Patterns
Another aspect of the tool that should inform the design is it’ll likely be used. It is like users would follow shortcut links a lot more than they would create them (let’s guess it’s something on the order of 100 or 1,000 reads per write). This implies some sort of caching on reads to make the redirects lightning fast. Conversely, your persistance layer doesn’t need to be extremely fast handling writes, at least at a small scale.
Some Security Thoughts
Finally, there are some interesting security considerations to keep in mind. You
would definitely want to disable x-origin POST requests, probably only support
GETs for the shortcuts, and finally invalidate short-links that reference
the admin UI used to create the shortlinks themselves. Imagine a scenario where
a malicious person crafted a short-link to hijack a shortcut like
POST http://go/admin/links/your_link/transfer?user_id=bad_guy.
Tech Concepts
The features above are a canvas to illustrate a few tech concepts that have interested me for a while:
- Setting up a project with developer productivity in mind.
- Packaging a self-contained web app or API.
- Making deployment easy, repeatable, automated and portable.
- Writing readable, testable and composable code.
- Using as few external dependencies as possible (this helps understand the value certain libraries can bring were you to use them).
- Improving performance.
Through the course of the project, I plan to tackle these each at least once, and perhaps more than once in order to compare and contrast techniques. Check out the golinx series for updates on each.