Vanity Redirection

Krishna Iyer Easwaran

March 20, 2020

Golang’s extensive list of existing packages for various commonly used functions is one of its biggest strengths. To use an existing project/package in code, all that needs to be done is to import in a .go file. Golang’s package management (ex: go modules, dep etc) manage how the packages are fetched and updated.

import "google.golang.org/grpc/metadata"

The same goes for installing a binary from an project.

$ go get -u google.golang.org/protobuf/cmd/protoc-gen-go

Go packages are described in the format <hostname>/[username]/[package-name] [version]. They are usually hosted on a compatible VCS server (ex: Github, Bitbucket, private VCS).

Go supports flexible remote import paths where the URL used by the clients to import a package can be independent of the actual location where it’s hosted.

This means that instead of serving packages via source dependent links (ex: https://github.com/KrishnaIyer/go-vanity-gen), a custom “vanity” URL can be used on a domain that you control (ex: https://go.krishnaiyer.dev/go-vanity-gen).

This post briefly explains the technicalities of vanity redirection and some existing tools that can be made use of to set up your own vanity redirects.

Why

How does it work

When the go tooling queries a custom import path, it expects an html page with two important meta tags. These meta tags in turn tell the go tooling where the package is actually hosted. A second request is made to this path and the package is fetched.

Vanity

This is the html file that’s served at <your-domain>/<package-name> containing the important go-import and go-source meta tags. The body of this file is ignored by the tooling.

<meta name="go-import" content="import-prefix vcs repo-root">

Ex:

<meta name="go-import" content="go.krishnaiyer.dev/go-vanity-gen git https://github.com/krishnaiyer/go-vanity-gen">
<meta name="go-source" content="import-prefix repo-root directory file">

Ex:

<meta name="go-source" content="go.krishnaiyer.dev/go-vanity-gen https://github.com/krishnaiyer/go-vanity-gen https://github.com/krishnaiyer/go-vanity-gen/tree/master{/dir} https://github.com/krishnaiyer/go-vanity-gen/blob/master{/dir}/{file}#L{line}">

Index

This is the index.html that’s served at the root of the custom domain; ex: go.example.com. This file is not necessary to use vanity redirection but is a common practice. This page is meant for (human) users and not for go tooling. The content of this index file can be anything, but it’s typically used to catalogue go packages (with links to documentation and the source package).

The following is a simple example of go packages listed on the index page.

`<!DOCTYPE html>
<html>
<h1>Welcome to go.my-domain.com </h1>
<h2> Here's a list of my go packages</h2>
<ul>
<li><a href="https://pkg.go.dev/repo/pkg1">repo/pkg1</a></li>
<li><a href="https://pkg.go.dev/repo/pkg2">repo/pkg2</a></li>
<li><a href="https://pkg.go.dev/repo/pkg3">repo/pkg3</a></li>
</ul>
</html>
`))

It’s advisable to keep the styling to a minimum to keep the file size low.

Tooling

Handling vanity redirects is essentially having a web server on the index and vanity paths that serves the requested assets. Depending on the hosting environment, there are a few solutions already available that can be used.

Hosting EnvironmentRepositoryWhen to use itComments
Google Cloud PlatformGoogleCloudPlatform/govanityurlsIf you’re already familiar with GCP and use Google App Engine for your existing workloads.Maintained by Google
Google Cloud FunctionsKrishnaIyer/go-vanity-cloud-functionIf you use GCP but don’t want to deploy a serverI don’t really maintain the repository as I don’t use it much.
Self Hosting (docker)KrishnaIyer/go-vanity-dockerIf you’re a more experienced cloud user with your own server.This is the most versatile option.
Simple static websiteKrishnaIyer/go-vanity-genIf you already host static content and your hosting infrastructure is easily extendable.This is what I use for go.krishnaiyer.dev and is really the simplest option.

Showcase

Head over to go.krishnaiyer.dev.

References

  1. govanityurls repository
  2. go-vanity-gen repository