loading...
Cover image for Attempting to Learn Go - Let's Get Modular - Again!

Attempting to Learn Go - Let's Get Modular - Again!

shindakun profile image Steve Layton ・3 min read

Attempting to Learn Go (23 Part Series)

1) Attempting to Learn Go - Building a Downloader Part 01 2) Attempting to Learn Go - Building a Downloader Part 02 3 ... 21 3) Attempting to Learn Go - Building a Downloader Part 03 4) Attempting to Learn Go - Building a Downloader Part 04 5) Attempting to Learn Go - Building a Downloader Part 05 6) Attempting to Learn Go - Consuming a REST API 7) Attempting to Learn Go - Continuing REST Adventures 8) Attempting to Learn Go - Now Sending REST Requests 9) Attempting to Learn Go - REST API and A Bit On Templates 10) Attempting to Learn Go - Sending Email Via API Again 11) Attempting to Learn Go - Let's Get Modular! 12) Attempting to Learn Go - Let's Get Modular - Again! 13) Attempting to Learn Go - Building Dev Log Part 01 14) Attempting to Learn Go - Building Dev Log Part 02 15) Attempting to Learn Go - Building Dev Log Part 03 16) Attempting to Learn Go - Building Dev Log Part 04 17) Attempting to Learn Go - Building Dev Log Part 05 18) Attempting to Learn Go - Listing Files By Extension 19) Attempting to Learn Go - Sorting and Moving Files by Extension 20) Attempting to Learn Go - Issuer 01 21) Attempting to Learn Go - Issuer 02 22) Attempting to Learn Go - Issuer 03 - Cloud Function Go! 23) Attempting to Learn Go - Issuer 04 - Addendum

Let's Get Modular - Again

Previously, we released our very first module version of the mailgunner package. This time around let's see what we would need to do to release a new version - we'll make a few small tweaks to the code, update the readme, and then cut a new release.


Ditch http.DefaultClient, Sort of

One of the issues with using http.DefaultClient is that it doesn't set some sensible defaults, it's basically, just like it says, a barebones client. What if someone needs to proxy a request? Or set a timeout? It can't be done easily with our previous module. Since that's the case, we want to make it so our module isn't reliant on it. So we're going to extend it a bit to make it possible to pass in a custom client. We're really own changing the New() function so, I'll only show that here, refer to the repo or the previous article to see the complete code.

Our original function was very simple, just returning a struct that contained two strings and http.DefaultClient.

type MgClient struct {
  MgAPIURL string
  MgAPIKey string
  Client   *http.Client
}

func New(apiurl, apikey string) MgClient {
  return MgClient{
    apiurl,
    apikey,
    http.DefaultClient,
  }
}

As I said we won't be changing the struct itself - we'll simply update New() to take another parameter. Also, note that we're now returning a pointer to the MgClient which probably should have been in the previous version. But hey, we're still learning. Our new parameter, cleverly named, client will accept *http.Client - we'll go over how to actually use it in a bit.

func New(apiurl, apikey string, client *http.Client) *MgClient {
  if client == nil {
    client = http.DefaultClient
  }
  return &MgClient{
    apiurl,
    apikey,
    client,
  }
}

If whoever is using the module declines to create a custom client and passes nil instead we'll fall back to using http.DefaultClient.

  mgc := mailgunner.New(apiurl, mgKey, nil)

Custom Client

Alright, but how do we make use of the custom client? It's actually pretty easy! Before calling New() we'll make a new variable named cc and give it &http.Client{} with a timeout of 10 seconds.

  cc := &http.Client{
    Timeout: time.Second * 10,
  }

With our fancy custom client in hand, we'll pass that into New() as our shiny new third parameter.

  mgc := mailgunner.New(apiurl, mgKey, cc)

Everything else works as it did before. 🎉

Lets Go v2

We're not quite ready to release our new module, first, we'll have to update the readme, which I won't repost here for brevity. Afterward, we then need to update our go.mod file to indicate we're at a new version. I've decided this is a major version since we've changed the signature of the New() function. The new go.mod simply has "v2" appended to it.

module github.com/shindakun/mailgunner/v2

We'll run through our Git commands to push everything to Github. We'll start by making a v2 branch (which you likely would create before you started making code changes, I didn't happen to though), adding our changes, which are then committed to that branch.

git checkout -b v2
git add .
git commit -m "Updated New() to take http.Client so we don't have to rely on http.DefaultClient"

So far so good. Now we'll push our branch up to the remote, then tag and push the tags.

git push --set-upstream origin v2
git tag v2.0.0
git push --tags origin v2

Now anyone can simply import the module with a /v2 and run go build to be in business!

GO111MODULE=on go build -v
github.com/shindakun/mailgunner/v2
github.com/shindakun/mailgunner/v2/example

GitHub logo shindakun / mailgunner

A super simplistic send only implementation of a Mailgun client in Go.

mailgunner

A super simplistic send only implementation of a Mailgun client in Go.

Installation

Use as a module, import github.com/shindakun/mailgunner/v2, then run

go mod init module
go build

If you are new to modules checkout my post on Dev.to for some more details.

go get github.com/shindakun/mailgunner

Usage

See example/main.go for a usage example.

Change log

  • Updated New() to take http.Client so we don't have to rely on http.DefaultClient

Next time

I'm still thinking about putting together a series of posts on how I want to build out a "devlog" over on my own domain. I just need to decide how I want to tackle it.

Well, until then...


You can find the code for this and most of the other Attempting to Learn Go posts in the repo on GitHub.




Attempting to Learn Go (23 Part Series)

1) Attempting to Learn Go - Building a Downloader Part 01 2) Attempting to Learn Go - Building a Downloader Part 02 3 ... 21 3) Attempting to Learn Go - Building a Downloader Part 03 4) Attempting to Learn Go - Building a Downloader Part 04 5) Attempting to Learn Go - Building a Downloader Part 05 6) Attempting to Learn Go - Consuming a REST API 7) Attempting to Learn Go - Continuing REST Adventures 8) Attempting to Learn Go - Now Sending REST Requests 9) Attempting to Learn Go - REST API and A Bit On Templates 10) Attempting to Learn Go - Sending Email Via API Again 11) Attempting to Learn Go - Let's Get Modular! 12) Attempting to Learn Go - Let's Get Modular - Again! 13) Attempting to Learn Go - Building Dev Log Part 01 14) Attempting to Learn Go - Building Dev Log Part 02 15) Attempting to Learn Go - Building Dev Log Part 03 16) Attempting to Learn Go - Building Dev Log Part 04 17) Attempting to Learn Go - Building Dev Log Part 05 18) Attempting to Learn Go - Listing Files By Extension 19) Attempting to Learn Go - Sorting and Moving Files by Extension 20) Attempting to Learn Go - Issuer 01 21) Attempting to Learn Go - Issuer 02 22) Attempting to Learn Go - Issuer 03 - Cloud Function Go! 23) Attempting to Learn Go - Issuer 04 - Addendum

Posted on by:

shindakun profile

Steve Layton

@shindakun

I've been known to write some code from time to time.

Discussion

markdown guide