Convert from/to JSON decimal fields in Go (golang) structs

1 minute read

Yesterday we had to marshal and umarshal to/from JSON some HTTP requests and responses in a Go microservice we are building. We already use ericlagergren/decimal. However we have spotted that the struct for the response were declared like this:

type IncomeExpensesResponse struct {
	Income   string `json:"income"`
	Expenses string `json:"expenses"`
}

and inside the source code, my colleagues were trying to manually convert from/to string to *decimal.Big for responses like:

{
    "income": "14.67",
    "expenses": "340.75"
}

This is actually not needed! Why should we reinvent the wheel?

Hence I created a small test to demonstrate ericlagergren/decimal JSON marshalling and unmarshalling capabilities:

package main

import (
	"encoding/json"
	"testing"

	"github.com/ericlagergren/decimal"
	"github.com/stretchr/testify/assert"
)

type IncomeExpenses struct {
	Income   *decimal.Big `json:"income"`
	Expenses *decimal.Big `json:"expenses"`
}

func TestMarshalIncomeExpensesToJson(t *testing.T) {

	pentochiliaro := decimal.New(1467, 2)
	drachmaEuro := decimal.New(34075, 2)

	testExpense := IncomeExpenses{
		Income:   pentochiliaro,
		Expenses: drachmaEuro,
	}

	expectedJson := `{"income": "14.67", "expenses": "340.75"}`
	jsonStr, _ := json.Marshal(testExpense)

	assert.JSONEq(t, expectedJson, string(jsonStr))
}
func TestUnMarshalIncomeExpensesFromJson(t *testing.T) {

	pentochiliaro := decimal.New(1467, 2)
	drachmaEuro := decimal.New(34075, 2)

	expectedExpense := IncomeExpenses{
		Income:   pentochiliaro,
		Expenses: drachmaEuro,
	}

	inputJson := `{"income": "14.67", "expenses": "340.75"}`
	var incomeExpences IncomeExpenses
	_ = json.Unmarshal([]byte(inputJson), &incomeExpences)

	assert.Equal(t, expectedExpense, incomeExpences)
}

If you are puzzled by the words pentochiliaro and drachmaEuro, let me explain!

  • Pentochiliaro (πεντοχίλιαρο) is a complex word consisting of the words Pente (Πέντε), which means five in Greek and Chiliades (Χιλιάδες) which means thousands in Greek. This how it the 5000 drachma banknote was called before Euro currency came!
  • drachmaEuro: This is the currency exchange rate while we used both Drachmas and Euros in Greece. 1 Euro was 340.75 Greek Drachmas.

I hope this helps! Have a nice evening from sunny Greece!

Comments