Attempting to Learn Go - Let's Get Modular!
Tags: go, continuingeducation, atlg
Published: 2018-12-29 22:15:55

---
title: Attempting to Learn Go - Let's Get Modular!
published: true
description: "Let's Get Modular! Making the mailgunner package easier to use."
tags: go, golang, continuing-education, atlg
cover_image: https://shindakun.glitch.me/content/images/2018/01/attemptinggo.png
series: "Attempting to Learn Go"
---

# Let's Get Modular

Remember this?

```bash
mkdir $GOTPATH/github.com/shindakun/mailgunner
mkdir $GOTPATH/github.com/shindakun/mailgunner/client
```

You may not if you didn't [read the previous post](https://dev.to/shindakun/attempting-to-learn-go---now-sending-rest-requests-akp) on sending email through MailGun. It's really sloppy and I only really did it that way to make it a bit easier to use the package locally with a proper example. I didn't like it very much and it still hasn't been posted on GitHub because of it. So, I thought we'd do a quick post covering making `mailgunner` a proper Go module.

***

## Prep work

The first thing we'll do is create a directory outside of the `$GOPATH`. You can use modules inside with the `GO111MODULE=on` environment variable but, since this is all about doing away with `$GOPATH` we'll work outside of it.

```bash
mkdir ~/Code/mailgunner
```

Now, create a `main.go` and open it in VS Code.

```bash
touch main.go
code .
```

The code is already written so I just paste it in. Note, that I've updated the package name from `client` to `mailgunner`. I've also added simple comments to the exported functions. This gives us some details using Intellisense in VS Code. I should probably make them a bit more useful though.

![Intellisense in Action](https://thepracticaldev.s3.amazonaws.com/i/prw18wfddl76nb7mzcu7.png)

I'm not going to go through the code again, just providing it here so you do not have to jump to the repo or the previous article. *Note: I made a slight tweak to the code after the fact, and renamed the `NewMgClient` function to the more correct `New()`.

```go
package mailgunner

import (
  "net/http"
  "net/url"
  "strings"
)

// MgClient struct holds our URL and API key
type MgClient struct {
  MgAPIURL string
  MgAPIKey string
  Client   *http.Client
}

// New returns our MgClient with the proper settings
func New(apiurl, apikey string) MgClient {
  return MgClient{
    apiurl,
    apikey,
    http.DefaultClient,
  }
}

// FormatEmailRequest puts everything together for sending
func (mgc *MgClient) FormatEmailRequest(from, to, subject, body string) (r *http.Request, err error) {
  data := url.Values{}
  data.Add("from", from)
  data.Add("to", to)
  data.Add("subject", subject)
  data.Add("text", body)

  r, err = http.NewRequest(http.MethodPost, mgc.MgAPIURL+"/messages", strings.NewReader(data.Encode()))
  if err != nil {
    return nil, err
  }
  r.SetBasicAuth("api", mgc.MgAPIKey)
  r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  return r, nil
}
```

To make it a proper module we then need to initialize it.

```bash
$ go mod init github.com/shindakun/mailgunner
go: creating new go.mod: module github.com/shindakun/mailgunner
```

Now, let's get our Git repo set up. If you are not familiar with Git I recommend taking some time to check it out. [Pro Git](https://git-scm.com/book/en/v2) is available online for free.

```bash
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/shindakun/mailgunner.git
git push -u origin master
```

Now to make full use of Go modules we'll need to tag our release with a version number. We'll follow [Semantic Versioning](https://semver.org/) and tag our release as version 1 or `v1.0.0` and push the tag to Github.

```bash
git tag v1.0.0
git push --tags
```

{% github shindakun/mailgunner %}

## Using Modules

Alright, great - but, how do we use it? The Git repo includes an example bit of code. Go ahead and clone the repo into a directory outside your `$GOPATH`. Navigate to the example directory. Then we'll initialize it to make use of the module. Finally, run `go build`, it will look something like the following.

```bash
$ go mod init example
go: creating new go.mod: module example
$ go build
go: finding github.com/shindakun/mailgunner v1.0.0
go: downloading github.com/shindakun/mailgunner v1.0.0
```

Look, at that - no more using `go get`!

## Next time

I want to take some time to look at web servers in Go so we'll probably look at making simple servers. They may not be production ready but it should still be fun to throw them up on the internet to see them in action. I had some other ideas of silly projects to try and work which I may get to first, we'll see what happens.

Until then...

***

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

{% github shindakun/atlg %}

---

| Enjoy this post? |
|:----:|
| [How about buying me a coffee?](https://ko-fi.com/shindakun) |

---