This is an implementation of a service asked for in the application process to Relayr. See the requirements PDF for details.
This is a recruiting task, so I'm making a couple of assumptions that simplify the implementation.
- Names of products in a category are unique. If two products have the same name and category, they're identical.
- Supplier names are unique.
This means I can store all offers in one table. In a real-world implementation, the database schema would look something
like this:
The API documentation can be found in the file openapi.yaml
in the OpenAPI 3.0 format. A rendered,
dependency-free HTML version exists in docs/html/index.html.
The documentation can be rebuilt with the following command. It requires the OpenAPI generator.
openapi-generator generate -i api/openapi.yaml -g html2 -o docs/html
This project uses Go modules. As such, all you need is a recent version of Go (1.14+
) installed. Dependencies will be
automatically installed when go build
is called (e.g. as part of make build
). Details about all make
targets can
be found in its own section below.
If you'd like to build a Docker image, you'll also need Docker.
There are two ways to run the service:
make run
will bring up the servicemake build
will compile a binary which can be run separately
To run the server:
make run
You should see:
$ make run
(...)
2020/10/09 18:02:21 Serving on port 8080
If this worked, you can navigate to http://localhost:8080/ and see a welcome message from Go.
The makefile contains shortcuts for common commands:
make compile
compiles everything, but doesn't create an executablemake build
creates an executablemake run
runs the servermake deps
fetches and installs all dependenciesmake updatedeps
updates all dependencies to their latest versions. Updatesgo.mod
.make golint
runs Golint on all source filesmake govet
runsgo vet
on all source filesmake goimports
runsgoimports
on all source files, updating them in-placemake goimports-check
runsgoimports
on all source files, but returns a non-0 exit code when changes are requiredmake tidy
runsgo mod tidy
, removing all unnecessary dependenciesmake tidy-check
checks ifgo mod tidy
has been run (useful to fail a CI step)make checks
runs all linters and checks, specifically:golint
,goimports-check
,govet
,tidy-check
make test
runs the testsmake test-coverprofile
runs the tests and creates a coverage profilemake coverage
runs the tests and creates an HTML coverage reportmake bench
runs the benchmark testsmake clean
deletes the binary and report files
The project comes with a Dockerfile
which can be used to build an image, for example using the following command:
docker build -t relayr-challenge .
To start the service in a Docker container, run the following command:
docker run -p 8080:8080 relayr-challenge
Alternatively, you can run the service with docker-compose
. Remember to rebuild the image if you change the code.
docker-compose up
The service will then be available at http://localhost:8080.
The service comes with a Helm chart named relayr-challenge
in the deploy
directory. This facilitates the
deployment to a Kubernetes cluster. It deploys two replicas by default.
To use it locally, we can use Minikube and Helm. This enables the ingress and registry addons, builds a Docker image, pushes it to Minikube's registry, and deploys the service.
minikube start --vm=true
minikube addons enable ingress
minikube addons enable registry
eval $(minikube -p minikube docker-env)
docker build -t relayr-challenge .
helm init
cd deploy
helm install --name relayr relayr-challenge
Once that's set up, we can add an entry to our /etc/hosts
file which points the name relayr-challenge
at the IP of
Minikube's virtual machine.