JuiceAPI

JuiceAPI is the new backend API for the Juice application. JuiceAPI is written in Golang — a high performance, concurrent, statically compiled programming language. It is highly recommended to always compile this with the latest released version of the tool chain. As such, users of Debian, *buntu, RedHat, etc based distributions should not install the version from their package repo.

Installing/Upgrading Golang

For directions on how to install Go please follow the official installation guide.

Downloading JuiceAPI

It is no longer required to download JuiceAPI to your $GOPATH. Select a suitable location for the development code to live and clone it from this repo.

$ git clone git@gitlab.com:utiliflex/Juice/juiceapi.git path-to-code-directory

Fetching vendored dependencies

JuiceAPI has a few 3rd party dependencies that must be fetched in order to build, dependencies are managed with golang modules.

Testing

Go has built in unit test tools, all tests go in a files that end with _test.go and by moniker only have tests relevant to the matching file. Example: content in a file named main.go would have tests located in main_test.go.

Prerequisites

JuiceAPI utilizes testfixtures and requires a running database for the tests to use. To setup a test database:

  1. Create a new database in MySQL/MariaDB with the string test in the name, e.g. juice4_test, test
  2. Dump out the current local DB, mysqldump jucie4 > test.sql
  3. Load the dump into the new DB, mysql juice4_test < test.sql
  4. Make a copy of the config.toml file for use in testing, cp config.toml config-test.toml
  5. Update config-test.toml accordingly to point to the test DB ``` … [database]

# Defines a master database (used for read/write queries) [database.master] # Name is the name of the database to use. # Default: ‘juice4’ > name = ‘juice4_test’ … ```

Running Tests

To run tests run the following command:

$ go test -p 1 ./...

To run tests on the internal packages run the following command:

$ go test -p 1 ./internal/...

Note: The option -p 1 is to force go test to only run tests one at a time. When testing multiple packages at one time go test will try to run tests in parallel. This can cause race conditions when using “testfixtures”.

Building

To build a binary first cd into the top level directory for this repo and run:

$ go build

This will compile the code and produce a binary for the same OS and system Architecture as the box it was built on.

Building For Deployment From non-Linux Host

Due to Go’s cross-compile nature it is possible to build binaries for different Operating Systems and Architectures than where it is being built. To do this the GOOS and GOARCH environment variables need to be set.

$ GOOS='linux' GOARCH='amd64' go build

This will build a binary for 64Bit Linux systems regardless of what it was built on. If the OS or Architecture are the same then the environment variable for that option can be left blank.

Applying DB Migrations

JuiceAPI uses golang-migrate/migrate to manage DataBase Migrations for both JuiceAPI and Juice4.

Installing migrate

  1. Download the correct pre-built binary for the system from: https://github.com/golang-migrate/migrate/releases e.g. $ curl -OL 'https://github.com/golang-migrate/migrate/releases/download/v4.4.0/migrate.linux-amd64.tar.gz'
  2. Extract the migrate binary from the tarball into your $PATH: # tar -C /usr/local/bin -xf migrate.linux-amd64.tar.gz migrate.linux-amd64
  3. Rename the binary: # mv /usr/local/bin/migrate.linux-amd64 /usr/local/bin/migrate
  4. Make the migrate binary executable: # chmod +x /usr/local/bin/migrate

Configuration

The migrate command takes all configuration information, including database connection information from run-time arguments. As such it is recommended to define environment variables with the connection information.o

Production/Dev Environments

For both Production and Development environments add the following to your $SHELL’s configuration file(s):

export MIGRATE_DB='mysql://USER:PASSWD@tcp(IPADDRESS:PORT)/DBNAME'

Replacing the following placeholders:

Unit Tests

Many of the unit tests for JuiceAPI depend on connecting to a database, this database should be different than the database used in the Dev environment and must have test in the name. For this a separate environment variable can be defined for this test database:

export MIGRATE_TEST_DB='mysql://USER:PASSWD@tcp(IPADDRESS:PORT)/TEST_DBNAME'

Like for the Production/Dev environments replace the placeholders with the correct values.

Running migrations

To create a new migration run the following:

$ migrate create -ext migration -dir (path to JuiceAPI root)/database/migrations NAME

Where NAME is (tableName)_(short description)

To apply migrations run the following:

$ migrate -path (path to JuiceAPI root)/database/migrations -database "${MIGRATE(_TEST)_DB}" up [N]

Where [N] is either a number of migrations to apply, or empty for all pending migrations

To Rollback migrations run the following:

$ migrate -path (path to JuiceAPI root)/database/migrations -database "${MIGRATE(_TEST)_DB}" down [N]

Where [N] is either a number of migrations to rollback, or empty for all migrations

For more details on using migrate see migrate -help

Updating the Changelog

The Changelog is managed through git-notes in a special changelog namespace.

To add a new changelog entry for a git commit run the following:

$ git notes --ref=changelog append (SHA sum)

This command will either create a new note in the changelog namespace for the given commit, or append the new information to the currently existing note.

Any changelog entry can also be updated with the following commands:

$ git notes --ref=changelog edit (SHA sum)

Adding aliases

Aliases can be setup for both append and edit subcommands to ensure the correct namespace is always used.

$ git config alias.cla 'notes --ref=changelog append'
$ git config alias.cle 'notes --ref=changelog edit'

Pushing and Pulling notes

It is possible to configure Git to automatically fetch note entries when pulling (fetch/pull/etc) by adding the following to the remote section of the .git/config file in your repo.

[remote "origin"]
fetch = +refs/notes/*:refs/notes/*
fetch = +refs/heads/*:refs/remotes/origin/*

Pushing notes is something that must be done manually, and can be easily aliased

push-notes = push origin ref/notes/*

Generating the changelog

The information from the changelog namespace can be used to generate an updated CHANGELOG.md file with this gen-changelog script.

$ gen-changelog > CHANGELOG.md