Mastering writing Packages with Go when working with the Azure SDK.

Mastering writing Packages with Go when working with the Azure SDK.

·

4 min read

Please note I am Dyslexic, so if things don't make grammatical sense, please do not hold it against me. Be Kind

One thing you need to know well when working with the Go Azure SDK is how packages work with the removal of GOPATH.

This has taken me some time to get my head around.

Since Go 1.11 there was a fundamental change with the Go Compiler. GOPATH was gone; no more building your Go Projects in your machine's src/bin folder. Now, you can build your Go projects anywhere. Yay, I hear many of you say. Well, at first, when learning Go, I thought that made sense until I started messing about with making and importing packages.

The way making packages work is you must run go mod init module_name first. It's not such a big deal and easy enough to master.

Until you get to the point of wanting to import that package.

Take this example, for instance:

┣ 📂pkgwork
┃ ┗ 📂mypkg
┃   ┗ 📜mypkg.go
┣ 📜go.mod
┗ 📜packagework.go

Here, I have made a package called packagework, which just sits outside the folder pkgwork.

I tried to import the package like this in my code:

package main

import (
    "fmt"
    mypkg "pkgwork/mypkg"
)

func main() {
    var value mypkg.MyInterface
    value = mypkg.MyType(5)
    value.MethodWithoutParameters()
    value.MethodWithParamaters(127.3)
    fmt.Println(value.MethodWithReturnValue())

}

In my head, that makes sense because I'm thinking Well, the root of my package is pkgwork/mypkg

Yet, when I run go run packagework.go I get the following error:

package pkgwork/mypkg is not in GOROOT (/usr/local/go/src/pkgwork/mypkg)

This means the GO compiler went to look for my package within the module and expected my module name, pkgwork, to be in the pkgwork folder. Yet my module_name in this instance, is not called pkgwork it's called packagework.

Once Go realised that the module was not in this destination, what it did was It went outside the pkgwork folder. Therefore, its next course of action is to go and check the main Go libraries in the GOROOT folder. When all places are searched and not found, it comes back with the error we just saw.

Essentially, my understanding of importing packages was wrong, and I have seen many others think the same way. To import your package, it's not package_path/package_name it's module_name/package_name

To fix this and to make this easier to understand in my own head. I put my main go file called packagework.go in a folder called pkgwork, so my folder structure looks like this:

┗ 📂pkgwork
  ┣ 📂mypkg
  ┃ ┗ 📜mypkg.go
  ┣ 📜go.mod
  ┗ 📜packagework.go

I re-modulated my project with the module_name of packagework and then imported that into my packagework.go file like this:

mypkg "packagework/mypkg"

So essentially, my main Go file looks like this:

package main

import (
    "fmt"
    mypkg "packagework/mypkg"
)

func main() {
    var value mypkg.MyInterface
    value = mypkg.MyType(5)
    value.MethodWithoutParameters()
    value.MethodWithParamaters(127.3)
    fmt.Println(value.MethodWithReturnValue())

}

This then allowed Go to find the package I was referring to.

One other thing I have picked up whilst learning Go is labelling my packages when importing them; if you noticed, I import like this: mypkg "packagework/mypkg" which is label module_name/pkgname

I find it is then much easier to call to my package when coding in main; it's also easier to read. Just a little hint.

Now, you have come down this far, and I have not mentioned the Azure SDK once, so rightly you are thinking, why is this important to the Azure SDK?

Well, what I have found when working with the Azure SDK is everything is split up into packages, which are essentially modules with pkg names. Let's look at the main one you will find yourself working with a lot:

The azidentity package tinyurl.com/azidentity. This package is used to authenticate into Azure. To work with it, you have to import it into your project like this:

"github.com/Azure/azure-sdk-for-go/sdk/azidentity"

And you reference it like this: without a label, you take the end part of the full path, so in this instance, azindentity Here is a small example:

azCLI, err := azidentity.NewAzureCLICredential(nil)
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("Authenticated!!")
        armcompute.NewVirtualMachinesClient(subscriptionID, azCLI, nil)
    }

On another note, the Github.com URLS are no different to just calling your module_name something like packagework. Essentially, Go does not see them as URLS when you are first making your packages, so If I call my module github.com/jasric89/packagework, then Go will see that as a name. Only when it goes into GitHub does it become something to download as a package for another developer using the go get -u URL to package_name.

I hope this helps someone. It took me a while to get my head around this subject.