{"id":8026,"date":"2024-05-21T08:00:04","date_gmt":"2024-05-21T15:00:04","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/cosmosdb\/?p=8026"},"modified":"2024-05-15T07:49:43","modified_gmt":"2024-05-15T14:49:43","slug":"announcing-the-stable-release-of-the-azure-cosmos-db-client-library-for-go","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cosmosdb\/announcing-the-stable-release-of-the-azure-cosmos-db-client-library-for-go\/","title":{"rendered":"Announcing the stable release of the Azure Cosmos DB client library for Go"},"content":{"rendered":"<p>We&#8217;re excited to announce the stable release of the <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/nosql\/sdk-go\">Azure Cosmos DB client library for Go<\/a>, a native Go library that enables you to interact with Azure Cosmos DB for NoSQL accounts from your Go applications. The Azure Cosmos DB client library for Go provides an idiomatic API for you to perform operations on databases, containers, and items.<\/p>\n<p>Learn how to use the Azure Cosmos DB client library for Go to build fast and scalable applications with Azure Cosmos DB. This release brings critical Azure Cosmos DB features for multi-region support and high availability to Go, such as the ability to set preferred regions and improved request diagnostics.<\/p>\n<p>&nbsp;<\/p>\n<h2>Install the package<\/h2>\n<p>The Azure Cosmos DB client library for Go is named <code>azcosmos<\/code>. To install the latest version, use the <code>go get<\/code> command.<\/p>\n<p style=\"padding-left: 40px;\"><code>go get -u github.com\/Azure\/azure-sdk-for-go\/sdk\/data\/azcosmos<\/code><\/p>\n<p><code><\/code>Prerequisites for using the library include:<\/p>\n<ul>\n<li>An Azure subscription, <a href=\"https:\/\/aka.ms\/trycosmosdb\">Azure Cosmos DB for NoSQL free trial account<\/a>, or the <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/how-to-develop-emulator\">Azure Cosmos DB Emulator<\/a>.<\/li>\n<li>A working development environment for Go version 1.21 or above.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>Creating a client<\/h2>\n<p>You need to have an Azure Cosmos DB for NoSQL account to create a client, which is the entry point for all operations on your account. If you have an Azure Subscription, you can use the Azure portal, Azure CLI, or Azure Resource Manager templates to create an account. If you don\u2019t have an Azure Subscription you can create an <a href=\"https:\/\/aka.ms\/trycosmosdb\">Azure Cosmos DB for NoSQL free trial account<\/a> or use the <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/how-to-develop-emulator\">Azure Cosmos DB Emulator<\/a>.<\/p>\n<p>Once you have an account, you can use the <code>NewCosmosClient<\/code> function to create a client. The client should be created as a singleton, and it can interact with all databases and containers in your account. \u00a0You can authenticate using your account endpoint and either a <code>TokenCredential<\/code>, like <code>DefaultAzureCredential<\/code>, or you can use your account key. It&#8217;s recommended to use <code>TokenCredential<\/code> types for authentication and avoid password-based authentication.<\/p>\n<p>&nbsp;<\/p>\n<h3>Use the <code>DefaultAzureCredential<\/code> token credential (recommended)<\/h3>\n<p><code>DefaultAzureCredential<\/code> combines several credential types into one for common production and development scenarios. It can authenticate using environment variables, managed identities, and more. To use Microsoft Entra identities to authenticate your data plane requests, configure <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/how-to-setup-rbac\">Azure Cosmos DB data plane role-based access control<\/a>. For more information about <code>DefaultAzureCredential<\/code>, see the <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity#section-readme\">azidentity\u00a0documentation<\/a>.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">import (\r\n\t\"github.com\/Azure\/azure-sdk-for-go\/sdk\/data\/azcosmos\"\r\n\t\"github.com\/Azure\/azure-sdk-for-go\/sdk\/azidentity\"\r\n)\r\n\r\ncred, err := azidentity.NewDefaultAzureCredential(nil)\r\nhandle(err)\r\nclient, err := azcosmos.NewClient(\"myAccountEndpointURL\", cred, nil)\r\nhandle(err)<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Use the Azure Cosmos DB account key<\/h3>\n<p>Azure Cosmos DB also supports authentication using account keys, which you can get from the Azure portal. Similarly, you can also authenticate using the account\u2019s connection string.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">const (\r\n    cosmosDbEndpoint = \"myAccountEndpointURL\"\r\n    cosmosDbKey = \"myAccountKey\"\r\n)\r\n\r\ncred, err := azcosmos.NewKeyCredential(cosmosDbKey)\r\nhandle(err)\r\nclient, err := azcosmos.NewClientWithKey(cosmosDbEndpoint, cred, nil)\r\nhandle(err)<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Configure <code>ClientOptions<\/code><\/h3>\n<p>Optionally, you can pass client configuration options using the <code>ClientOptions<\/code> struct. For accounts deployed in multiple regions, it\u2019s recommended to <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/nosql\/troubleshoot-sdk-availability\">configure preferred regions<\/a> in the client options. The order of preferred regions guides the SDK on which region requests should be retried during an outage or transient failure. Configuring preferred regions is critical for high availability.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">clientOptions := azcosmos.ClientOptions{\r\n    PreferredRegions: []string{\"West US\", \"East US\"}\r\n}\r\n    \r\ncred, err := azcosmos.NewKeyCredential(cosmosDbKey)\r\nhandle(err)\r\nclient, err := azcosmos.NewClientWithKey(cosmosDbEndpoint, cred, &amp;clientOptions)\r\nhandle(err)<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Creating a database<\/h2>\n<p>To create a database, you can use the <code>CreateDatabase<\/code> method of the client and pass a <code>DatabaseProperties<\/code> struct. Creating resources in the application isn\u2019t supported when authenticating with Azure Cosmos DB role-based access control. It\u2019s recommended to create resources outside of the flow of your application. The <code>NewDatabase<\/code> method returns a struct that represents an existing database and allows database level operations.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">databaseProps := azcosmos.DatabaseProperties{ID: dbName}\r\nresponse, err := client.CreateDatabase(context, databaseProps, nil)\r\nhandle(err)\r\ndatabase, err := client.NewDatabase(dbName)\r\nhandle(err)\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Creating a container<\/h2>\n<p>To create a container, you can use the <code>CreateContainer<\/code> method of the database and pass a <code>ContainerProperties<\/code> struct. Similar to creating a database, creating containers isn\u2019t recommended in the application flow and isn\u2019t supported when authenticating with Azure Cosmos DB role-based access control. The <code>NewContainer<\/code> method returns a struct that represents an existing container and allows container level operations, including operations on items in the container.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">containerProperties := azcosmos.ContainerProperties{\r\n    ID: containerName,\r\n    PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{\r\n        Paths: []string{\"\/myPartitionKeyPath\"},\r\n    },\r\n}\r\n    \r\nthroughput := azcosmos.NewManualThroughputProperties(400)\r\ncontainerRes, err := database.CreateContainer(context, containerProperties, &amp;azcosmos.CreateContainerOptions{\r\nThroughputProperties: &amp;throughput\r\n})\r\nhandle(err)\r\ncontainer, err := client.NewContainer(dbName, containerName)\r\nhandle(err)\r\n<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Operations on items<\/h2>\n<h3>Create an item<\/h3>\n<p>The <code>CreateItem<\/code> method of the container creates an item. You need to pass the partition key value of the item, the item to be created, and optionally, an <code>ItemOptions<\/code> struct. <code>ItemOptions<\/code> contains the request options, such as the consistency level and enabling content response on write. If you\u2019re using <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/consistency-levels#session-consistency\">session consistency<\/a>, you should obtain the session token from your write operation. Pass the session token to your read operations to maintain the read-your-writes guarantee.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">item := map[string]string{\r\n    \"id\": \"myDocId\",\r\n    \"myPartitionKeyPath\": \"myPartitionKeyValue\",\r\n    \"property\": \"value\",\r\n}\r\nmarshalledItem, err := json.Marshal(item)\r\nhandle(err)\r\n\r\npk := azcosmos.NewPartitionKeyString(\"myPartitionKeyValue\")\r\nitemResponse, err := container.CreateItem(context, pk, marshalledItem, nil)\r\nhandle(err)\r\n\r\nitemSessionToken := itemResponse.SessionToken<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Read an item<\/h3>\n<p>The <code>ReadItem<\/code> method of the container gets an item by its partition key and id. Like <code>CreateItem<\/code>, <code>ReadItem<\/code> also optionally takes the <code>ItemOptions<\/code> struct. When using session consistency, pass the session token from your write with each read request to maintain consistency.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">id := \"myDocId\"\r\npk := azcosmos.NewPartitionKeyString(\"myPartitionKeyValue\")\r\nitemResponse, err = container.ReadItem(context, pk, id, &amp;azcosmos.ItemOptions{SessionToken: itemSessionToken})\r\nhandle(err)\r\n    \r\nvar itemResponseBody map[string]string\r\nerr = json.Unmarshal(itemResponse.Value, &amp;itemResponseBody)\r\nhandle(err)<\/code><\/pre>\n<p>Inevitably, you will get an error response in your application at some point. One common scenario is attempting to read an item that doesn\u2019t exist, which will return a 404 Not Found. You can inspect the status code of the error to decide how to handle it.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">itemResponse, err = container.ReadItem(context, pk, id, &amp;azcosmos.ItemOptions{SessionToken: itemSessionToken})\r\nif err != nil {\r\n    var responseErr *azcore.ResponseError\r\n    errors.As(err, &amp;responseErr)\r\n\r\n    if responseErr.StatusCode != 404 {\r\n        panic(responseErr)\r\n    }\r\n}<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h3>Query items<\/h3>\n<p>The <code>NewQueryItemsPager<\/code> method of the container performs a query over items in the container. Optionally, you can use <code>QueryOptions<\/code> to configure options for the request including setting query parameters and populating index metrics. Currently, queries must specify a partition key to execute against. You can see the request charge for each round trip of the query as part of the query response.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">queryOptions := azcosmos.QueryOptions{\r\n    QueryParameters: []azcosmos.QueryParameter{\r\n        {\"@property\", \"value\"},\r\n    },\r\n}\r\npk := azcosmos.NewPartitionKeyString(\"myPartitionKeyValue\")\r\nquery := \"SELECT * FROM c WHERE c.property = @property\",\r\n\r\nqueryPager := container.NewQueryItemsPager(query, pk, &amp;queryOptions)\r\nfor queryPager.More() {\r\n    queryResponse, err := queryPager.NextPage(context)\r\n    handle(err)\r\n    \r\n    for _, item := range queryResponse.Items {\r\n        var itemResponseBody map[string]interface{}\r\n        json.Unmarshal(item, &amp;itemResponseBody)\r\n    }\r\n\r\n    fmt.Printf(\"Query page received with %v items consuming %v RU\", len(queryResponse.Items), queryResponse.RequestCharge)\r\n}<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Logging request diagnostics<\/h2>\n<p>All requests have associated diagnostics which are useful for debugging your application. The SDK uses the logging implementation from <code>azcore<\/code> to collect this information. To <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/azcore#hdr-Built_in_Logging\">enable logging<\/a>, set the environment variable <code>AZURE_SDK_GO_LOGGING<\/code> to <code>all<\/code>.<\/p>\n<p>The SDK records logs for all types of events including requests, responses, and retries by default. They are output to <code>stdout<\/code> and printed directly to your console. You can configure a listener that acts differently, for example, writing logs to a file. If you apply log filtering based on event type, it\u2019s recommended to keep logs from <code>azlog.EventResponseError<\/code> at a minimum.<\/p>\n<pre class=\"prettyprint language-default\" style=\"padding-left: 40px;\"><code class=\"language-default\">import (\r\n\t\"os\"\r\n\tazlog \"github.com\/Azure\/azure-sdk-for-go\/sdk\/azcore\/log\"\r\n)\r\n\r\nf, err := os.Create(\"cosmos-log-file.txt\")\r\nhandle(err)\r\ndefer f.Close()\r\n\r\n\/\/ Configure the listener to write to a file rather than to the console\r\nazlog.SetListener(func(event azlog.Event, s string) {\r\n\tf.WriteString(s + \"\\n\")\r\n})<\/code><\/pre>\n<p>&nbsp;<\/p>\n<h2>Next steps<\/h2>\n<p>The Azure Cosmos DB client library for Go allows you to build and debug highly available applications built on Azure Cosmos DB. You can find more information and code samples in the <a href=\"https:\/\/pkg.go.dev\/github.com\/Azure\/azure-sdk-for-go\/sdk\/data\/azcosmos#pkg-types\">API reference documentation<\/a>, or follow the <a href=\"https:\/\/learn.microsoft.com\/azure\/cosmos-db\/nosql\/quickstart-go\">quick-start<\/a>. Additionally, you can provide feedback and report issues on the <a href=\"https:\/\/github.com\/Azure\/azure-sdk-for-go\/issues\">GitHub issues page<\/a>. We look forward to hearing from you and seeing what you build with Azure Cosmos DB and Go!<\/p>\n<p>&nbsp;<\/p>\n<h2>About Azure Cosmos DB<\/h2>\n<p>Azure Cosmos DB is a fully managed and serverless distributed database for modern app development, with SLA-backed speed and availability, automatic and instant scalability, and support for open-source PostgreSQL, MongoDB, and Apache Cassandra. <a href=\"https:\/\/cosmos.azure.com\/try\/\">Try Azure Cosmos DB for free here.<\/a> To stay in the loop on Azure Cosmos DB updates, follow us on <a href=\"https:\/\/twitter.com\/AzureCosmosDB\">X<\/a>, <a href=\"https:\/\/aka.ms\/AzureCosmosDBYouTube\">YouTube<\/a>, and <a href=\"https:\/\/www.linkedin.com\/company\/azure-cosmos-db\/\">LinkedIn<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;re excited to announce the stable release of the Azure Cosmos DB client library for Go, a native Go library that enables you to interact with Azure Cosmos DB for NoSQL accounts from your Go applications. The Azure Cosmos DB client library for Go provides an idiomatic API for you to perform operations on databases, [&hellip;]<\/p>\n","protected":false},"author":94159,"featured_media":8031,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[12,14],"tags":[1738],"class_list":["post-8026","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-announcements","category-core-sql-api","tag-go"],"acf":[],"blog_post_summary":"<p>We&#8217;re excited to announce the stable release of the Azure Cosmos DB client library for Go, a native Go library that enables you to interact with Azure Cosmos DB for NoSQL accounts from your Go applications. The Azure Cosmos DB client library for Go provides an idiomatic API for you to perform operations on databases, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/8026","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/users\/94159"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/comments?post=8026"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/posts\/8026\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media\/8031"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/media?parent=8026"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/categories?post=8026"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cosmosdb\/wp-json\/wp\/v2\/tags?post=8026"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}