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
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.
Source repo for the "Attempting to Learn Go" posts I've been putting up over on dev.to
Attempting to Learn Go
Here you can find the code I've been writing for my Attempting to Learn Go posts that I've been writing and posting over on Dev.to.
Post Index