Parsing user-agent strings and go:embed
I’m currently in the process of writing a back-end for a small web application that I plan to deploy in my local environment. The application isn’t really relevant. The important bit is a new trick I learned while working on it.
Within the back-end, at some point, I’m parsing an user-agent string. These strings are standardised and should follow the format described by HTTP Semantics.
For convenience, I’ve chosen to go with uap-go to parse these strings and here lies the catch.
This library relies on a file regexes.yaml containing regular expressions to match user agent strings. The file is provided in uap-core repository. So, in order to use the library, I need the regex file as well. Since I’m planning on dockerising the back-end anyway, this shouldn’t be that much of a problem right?
Such approach, is a bit of a compromise - source code would become part
of the deployment. I’d have to put uap-core
or regexes.yaml
itself into my
image and that’s not really what I want.
go:embed to the rescue
go:embed
is a perfect solution for this kind of problems. Let’s start with a simple example.
I’m gonna create a small repo with a user-agent parser and add uap-go to it:
|
|
Additionally, I’m gonna add uap-core as a submodule to have the regexes.yaml
file.
|
|
Finally, my test application’s code:
|
|
The path to regexes.yaml
is hard-coded. This poses a problem. The path has
to be either configurable, the regexes.yaml
has to be installed in a fixed,
well known location or it has to be baked into docker image, in case the
application is meant to be dockerised.
But, with go:embed
, this can be solved quite elegantly:
|
|
The contents of the file become embedded in the application itself. The path is known and fixed at built time.
Embedding directories
In my case, embedding a single file was enough to solve the problem but it’s possible to embed entire directories equally easy. Let’s make a small change to the example program to show that:
|
|
This is perfect for embedding HTML templates or database migration files.
Conclusion
go:embed is a perfect solution for including application assets that are difficult to handle outside of docker giving a fixed, deterministic access and a guarantee that all needed files are part of the deployment, regardless of the environment.
It’s perfect for embedding source code dependencies which really shouldn’t be a part of docker images.
Example code is available here.