Application: router
Router in front on GOV.UK to proxy to backend servers on the single domain
- GitHub
- router
- Ownership
- #govuk-navigation-tech
- Hosting
- AWS (EKS)
- Category
- Supporting apps
README
-# router
This is a HTTP reverse proxy router built on top of triemux
. It
loads a routing table into memory from a MongoDB database and acts as a:
- Reverse proxy, forwarding requests to and serving responses from multiple backend servers on a single domain.
- Redirector, serving HTTP
301
and302
redirects to new URLs. - Gone responder, serving HTTP
410
responses for resources that used to but no longer exist.
The sister project router-api
provides a read/write
interface to the underlying database and route reloading.
Technical documentation
Recommended reading: How to Write Go Code
You can use the GOV.UK Docker environment to run the application and its tests with all the necessary dependencies. Follow the usage instructions to get started.
Use GOV.UK Docker to run any commands that follow.
Running the test suite
You can run all tests by running:
make test
The trie
and triemux
sub-packages have unit tests and benchmarks written
in Go’s own testing framework. To run them individually:
go test -bench=. ./trie ./triemux
The router
itself doesn’t really benefit from having unit tests around
individual functions. Instead it has a comprehensive set of integration
tests to exercise it’s HTTP handling, error reporting, and performance.
go test ./integration_tests
Updating dependencies
This project uses Go Modules to vendor its dependencies. To update the dependencies:
go mod vendor
Updating the version of Go
Dependabot raises PR’s to update the dependencies for Router. This includes raising a PR when a new version of Go is available. However to update the version of Go, it’s necessary to do more than just merge this dependabot PR. Here is an example PR with all the below changes, and here are the steps:
- Dependabot’s PR will modify the Go version in the Dockerfile (and thus what is build in the Kubernetes engine), but you also need to update the version number in the file
.go-version
. - You will also have to update the Go version in
go.mod
. This will necessitate having Go installed on your local machine, changing the version number and running in terminalgo mod tidy
andgo mod vendor
in sequence to update correctly. This may have no changes at all, but see example pr for a larger update. Also see Upgrading Go Modules. - Finally you need to update the go version in
ci.yml
. - Before you merge this PR, put the branch onto staging and leave it there for a couple of weekdays. Check for anything unexpected in icinga and sentry.
- If you are confident that the version bump is safe for production, you can merge your PR and deploy it to production. It is best to do this at a quiet time of the day (such as 7am) to minimise any potential disruption.
- Make sure govuk-docker is updated to match the new version. See here.
Upgrading Go Modules
Sometimes modules will need to be manually upgraded after the above steps. This will satisfy dependencies that are old and do not use the go.mod
file management system. Most likely you will see errors that require this when there is a failure to properly vendor go.mod
due to an unsupported feature call in a dependency.
To do this, you’ll require GoLang installed on your machine.
- First, follow point 3 of the above guide for upgrating the version of Go.
- If you determine through test failures that a module will need to be upgraded, in terminal at the root of
router
type in the following:go get -u [repo-of-module]
- For example:go get -u github.com/streadway/quantile
- Run
go mod tidy
andgo mod vendor
. Check for any errors and commit.
You may have to push your branch to see if this causes further errors on the Jenkins CI machines.
Why do we install Go on CI machines rather than Cache machines?
Router is built on CI machines; the artefact is then uploaded to S3 for use in deployment. In deployment, the artefact is retrieved from S3 and uploaded to the cache machines prior to a restart.
The updated version of golang is only uploaded to Jenkins and CI agents.
Further documentation
- Data structure
- Original thinking behind the router
- Example of adding a metric using the Go prometheus client library