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

*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:

```plaintext
┣ 📂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:

```plaintext
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:

```plaintext
┗ 📂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:

```plaintext
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 https://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:

```plaintext
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.
