Introducing the latest beta versions of the Azure SDK for Go management modules

Chenjie Shi

You may have heard that Go version 1.18 has been released. This release introduced support for generic code using parameterized types. After applying new language features and learnings from user studies, we’ve released new beta versions of the Azure SDK for Go management modules. We believe the new versions will provide a better development experience.

Get the latest modules

You can get the latest modules using pkg.go.dev or view the latest source code in the Azure SDK for Go repository. You can also find a list of all the management modules with the latest beta version on our Azure SDK Releases page. Because the new modules apply Go generics, you’ll need to upgrade to Go 1.18 first.

API changes

Generic poller for long-running operations (LROs)

We’ve removed all the non-generic poller response types for all LROs. They’re replaced with a new generic poller type armruntime.Poller[T]. The usage of poller hasn’t changed much. You can use poller.PollUntilDone to get the final response synchronously. Alternatively, you can use poller.Poll, poller.Done, and poller.Result to implement your own polling logic. The following example shows how to use the new poller to get the final result when capturing a virtual machine.

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
    panic(err)
}
ctx := context.TODO()
client, err := armcompute.NewVirtualMachinesClient("<subscription-id>", cred, nil)
if err != nil {
    panic(err)
}
poller, err := client.BeginCapture(ctx,
    "<resource-group-name>",
    "<vm-name>",
    armcompute.VirtualMachineCaptureParameters{
        DestinationContainerName: to.Ptr("<destination-container-name>"),
        OverwriteVhds:            to.Ptr(true),
        VhdPrefix:                to.Ptr("<vhd-prefix>"),
    },
    nil)
if err != nil {
    panic(err)
}
res, err := poller.PollUntilDone(ctx, nil)
if err != nil {
    panic(err)
}
// TODO: use response item
_ = res

Generic pager and new pager API

As was the case with the generic poller, all the non-generic pager response types for operations with paging result have been removed. They’re replaced with a new generic pager type runtime.Pager[T]. We also simplified the pager API and provided more direct error handling. You can use pager.More to determine if there are more result pages. Then use pager.NextPage to fetch the next result page. The following example shows how to use new pager API to list all virtual machines in a resource group.

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
    panic(err)
}
ctx := context.TODO()
client, err := armcompute.NewVirtualMachinesClient("<subscription-id>", cred, nil)
if err != nil {
    panic(err)
}
pager := client.NewListPager("<resource-group-name>",
    &armcompute.VirtualMachinesClientListOptions{Filter: to.Ptr("<filter>")})
for pager.More() {
    nextResult, err := pager.NextPage(ctx)
    if err != nil {
        panic(err)
    }
    for _, v := range nextResult.Value {
        // TODO: use page item
        _ = v
    }
}

New pattern to get raw HTTP response

The response envelope has been simplified for all the operations because a response with deserialized types is sufficient for common scenarios. Previously, you could obtain the raw HTTP response from the response envelope, but now you can get it from the request context instead. The following example shows how to get the raw HTTP response when getting info from a virtual machine.

cred, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
    panic(err)
}
client, err := armcompute.NewVirtualMachinesClient("<subscription-id>", cred, nil)
if err != nil {
    panic(err)
}
var rawResponse *http.Response
ctx := context.TODO()
ctxWithResp := runtime.WithCaptureResponse(ctx, &rawResponse)
res, err := client.Get(ctxWithResp,
    "<resource-group-name>",
    "<vm-name>",
    nil)
// TODO: use raw response
_ = rawResponse.Body

Generic pointer conversion helper

The new version provides generic to.Ptr[T] and to.SliceOfPtrs[T] for pointer conversion and removes all non-generic implementations.

int32Pointer := to.Ptr[int32](2)
intPointer := to.Ptr(3)
stringPointer := to.Ptr("test")
intSlicePointer := to.SliceOfPtrs([]int{1, 2, 3})

Conclusion

In these new beta modules, we reduced the number of top-level symbols and provide simplified APIs for operations. We’ll continue to add samples and docs to familiarize developers with the latest management modules. The stable versions of the Azure SDK for Go management modules are coming soon.

Feedback

We encourage you to upgrade to these new beta versions and always welcome your feedback. For feature requests, bug reports, or general support, open an issue in the Azure SDK for Go repository. For more information on how we triage issues, see Azure SDK GitHub Issue Support Process.

3 comments

Leave a comment

  • Paulo Pinto

    Looking at the Go SDK for the first time, the need for pointer helpers seems quite strange, as if not originally written by people with Go background.

    Also the use of handle(err) is quite unidiomatic in Go.

    • Chenjie ShiMicrosoft employee

      @Paulo Thank you for the feedback. In order to handle empty value marshaling, all properties of operation models are pointer type in our SDK. So, we provide this helper method. You could see some examples in the LRO part in this blog. Feel free to give your further idea about it. And handle(err) is a placeholder in blog, we are going to replace them with log.Fatal statement then.