Public holidays
This project showcases my proficiency in Go by creating a clear and readable
public holidays API. The primary focus is on writing clean, maintainable code
that effectively demonstrates the logic behind retrieving public holidays for a
country's ISO 3166-1 alpha-2 code.
GET /holidays/v1/{country}/{year}
This endpoint retrieves a list of public holidays for a specified country and
year. By replacing {country}
with the two-letter ISO 3166-1 alpha-2 code of
the desired country and {year}
with the target year, users can access detailed
information about each holiday, including dates, local names and English names.
This API is useful for applications that need to display or utilize holiday data
for various purposes, such as scheduling or planning.
This API is available at https://public-holidays.onrender.com.
IMPORTANT
The instance might be down due to inactivity, therefore, wait about 50s for the instance to be started again.
Example request
curl -s "https://public-holidays.onrender.com/holidays/v1/FI/2024" | jq
curl -s "http://localhost:10000/holidays/v1/FI/2024" | jq
Response format
The response will be in JSON format and includes an array of holiday objects
with the following details:
- date: The date of the holiday.
- name: The name of the holiday in the local language.
- englishName: The name of the holiday in English.
[
{
"date": "2024-01-01",
"name": "Uudenvuodenpäivä",
"englishName": "New Year's Day"
},
{
"date": "2024-01-06",
"name": "Loppiainen",
"englishName": "Epiphany"
},
...
]
Countries
Here is a list of the supported countries.
Prerequisites
- Go 1.23.0 or above
- make (if you want to use the
Makefile
provided) - Docker
Dependencies
IMPORTANT: No 3rd party dependencies are used.
I could easily use Cobra (and usually I do,
because it allows me to write powerful CLIs), but I felt it was too much for
such a tiny project. I only ever use dependencies when it's say an adapter for
an external service e.g. Redis, MySQL or Prometheus.
Setup
- Create and edit the
.env
(used when developing locally) and .env.production
(used when deploying to production)
cp .env.example .env
cp .env.example .env.production
Run not using Docker
go run .
or when using make
make
./public-holidays-cli
Version
Display the version of the application and exit.
make
./public-holidays-cli --version
./public-holidays-cli --json --version
Help
Display the help text and exit.
make
./public-holidays-cli --help
Run using Docker
- Build the Docker image with the tag
public-holidays
.
docker build -t public-holidays .
- Run the Docker image.
docker run -p "10000:10000" --rm public-holidays
Version
Display the version of the application and exit.
docker run --rm public-holidays --version
docker run --rm public-holidays --json --version
Help
Display the help text and exit.
docker run --rm public-holidays --help
Tests
Tests are written as Table-Driven Tests.
go test -cover -v ./...
or when using make
make test
Coverage
go test -cover -v github.com/softwarespot/public-holidays/internal/
Linting
Docker
docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:latest golangci-lint run -v --tests=false --disable-all -E durationcheck,errorlint,exhaustive,gocritic,gosimple,ineffassign,misspell,predeclared,revive,staticcheck,unparam,unused,whitespace --max-issues-per-linter=10000 --max-same-issues=10000
Local
golangci-lint run --tests=false --disable-all -E durationcheck,errorlint,exhaustive,gocritic,gosimple,ineffassign,misspell,predeclared,revive,staticcheck,unparam,unused,whitespace --max-issues-per-linter=10000 --max-same-issues=10000
Additional information
This section documents any additional information which might be deemed
important for the reviewer.
Decisions made
- Despite using 1.23.0+ and the
slices
pkg being available, I have opted not
to use it, and instead went for how I've been writing Go code before the
slices
pkg existed. Although for production code, I have started to use it
where applicable. - Loosely used https://jsonapi.org/.
License
The code has been licensed under the MIT license.