Into the Golang land: part #2

I have a few lessons left to learn from my last Golang kata. Namely module creation, running tests on docker-compose up and trying something more related with the work I do. For this final Golang kata, I have decided to implement a client library handling CRUD methods.

I have then ran our of time and ended up implementing only Health service. Still the rest of the code is extensible enough to try and create some non-existing API later. Sadly, given I mainly work on python, I already feel like I learned enough on Golang. I won’t be coming back to it soon.

Gopher mascot wallpaper : golang
source: reddit.com

There were a few goals I set for myself:

  • learn local packages for golang and how to use them
  • run tests on docker-compose up
  • write a client library for potential use with an API using Golang standard libraries as much as possible

I have managed to achieve these goals. The repository is here.

It is sweet where you can provide such a simple and nice example on how to initialize your client:

package main

import (
	"fmt"
	"log"

	"client-api/clientapi"
)

func main() {
	client := clientapi.CreateClient()

	status, err := client.Health.Check()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Healthcheck status: %v\n", status.Status)
}

There were many things I have learned from this exercise.

First, how to structure a client into more or less a Repository pattern. Golang pointers are pretty useful here.

Second, how to test an api client, that really has no api behind it. It was all just worked up in my mind. Probably why it was hard to build a reasonable Create, Get, List, Delete :). Standard Golang libraries for testing are absolutely wicked though. The code below allows you to create a ‘fake’ http server, which will then allow for injecting any response in the unit tests. The concept of ‘mux’ is really nice.

func setup() (client *Client, mux *http.ServeMux, serverURL string, teardown func()) {
	// mux is the HTTP request multiplexer used with the test server.
	mux = http.NewServeMux()

	// server is a test HTTP server used to provide mock API responses.
	server := httptest.NewServer(mux)

	// client is the client being tested and is
	// configured to use test server.
	client = CreateClient()
	url, _ := url.Parse(server.URL + "/")
	client.BaseURL = url

	return client, mux, server.URL, server.Close
}

Third, while I have not used it in full eventually. Docker-compose allows for network sharing with host (to avoid this pesky 1:1 port mappings). network_mode: host is all that you need in your service definition.

Fourth, marshalling and unmarshalling json feels reasonable in Golang. All you need to do is tag your structures, similar to below to be able to operate on the response string as a struct (see more in the repo).

// Status represents a healthcheck status.
type Status struct {
	Status string `json:"status,omitempty"`
}

And last, I have finally managed to understand packages (use mod-name) and run tests on docker-compose up. You can checkout the repo and take a look yourself.

This took me about 2-3 hours to complete, with the hardest task being – finding a pattern I could use to build it.


That’s all for today. Thank you very much and lets ‘read’ each other soon.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s