|
| 1 | +--- |
| 2 | +title: Create and manage clients that interact with data resources |
| 3 | +titleSuffix: Azure Storage |
| 4 | +description: Learn how to create and manage clients that interact with data resources in Blob Storage. |
| 5 | +services: storage |
| 6 | +author: pauljewellmsft |
| 7 | + |
| 8 | +ms.service: storage |
| 9 | +ms.topic: how-to |
| 10 | +ms.date: 02/08/2023 |
| 11 | +ms.author: pauljewell |
| 12 | +ms.subservice: blobs |
| 13 | +ms.devlang: csharp, java, javascript, python |
| 14 | +ms.custom: devguide-csharp, devguide-java, devguide-javascript, devguide-python |
| 15 | +--- |
| 16 | + |
| 17 | +# Create and manage client objects that interact with data resources |
| 18 | + |
| 19 | +The Azure SDKs are collections of libraries built to make it easier to use Azure services from different languages. The SDKs are designed to simplify interactions between your application and Azure resources. Working with Azure resources using the SDK begins with creating a client instance. This article shows how to create client objects to interact with data resources in Azure Blob Storage, and offers best practices on how to manage clients in your application. |
| 20 | + |
| 21 | +## About client objects |
| 22 | + |
| 23 | +The Azure Blob Storage client libraries allow you to interact with three types of resources in the storage service: |
| 24 | + |
| 25 | +- Storage accounts |
| 26 | +- Blob containers |
| 27 | +- Blobs |
| 28 | + |
| 29 | +Depending on the needs of your application, you can create client objects at any of these three levels. |
| 30 | + |
| 31 | +For blobs, there's a general blob client that covers common blob operations across all types, and there are specialized blob clients for each type (block blob, append blob, and page blob). |
| 32 | + |
| 33 | +The following table lists the different client classes for each language: |
| 34 | + |
| 35 | +| Language | Packages | Service client class | Container client class | Blob client classes | |
| 36 | +| --- | --- | --- | --- | --- | |
| 37 | +| .NET | [Azure.Storage.Blobs](/dotnet/api/azure.storage.blobs)<br>[Azure.Storage.Blobs.Models](/dotnet/api/azure.storage.blobs.models)<br>[Azure.Storage.Blobs.Specialized](/dotnet/api/azure.storage.blobs.specialized) | [BlobServiceClient](/dotnet/api/azure.storage.blobs.blobserviceclient) | [BlobContainerClient](/dotnet/api/azure.storage.blobs.blobcontainerclient) | [BlobClient](/dotnet/api/azure.storage.blobs.blobclient)<br>[BlockBlobClient](/dotnet/api/azure.storage.blobs.specialized.blockblobclient)<br>[AppendBlobClient](/dotnet/api/azure.storage.blobs.specialized.appendblobclient)<br>[PageBlobClient](/dotnet/api/azure.storage.blobs.specialized.pageblobclient) | |
| 38 | +| Java | [com.azure.storage.blob](/java/api/com.azure.storage.blob)<br>[com.azure.storage.blob.models](/java/api/com.azure.storage.blob.models)<br>[com.azure.storage.blob.specialized](/java/api/com.azure.storage.blob.specialized) | [BlobServiceClient](/java/api/com.azure.storage.blob.blobserviceclient)<br>[BlobServiceAsyncClient](/java/api/com.azure.storage.blob.blobserviceasyncclient)<br>[BlobServiceClientBuilder](/java/api/com.azure.storage.blob.blobserviceclientbuilder) | [BlobContainerClient](/java/api/com.azure.storage.blob.blobcontainerclient)<br>[BlobContainerAsyncClient](/java/api/com.azure.storage.blob.blobcontainerasyncclient)<br>[BlobContainerClientBuilder](/java/api/com.azure.storage.blob.blobcontainerclientbuilder) | [BlobClient](/java/api/com.azure.storage.blob.blobclient)<br>[BlobAsyncClient](/java/api/com.azure.storage.blob.blobasyncclient)<br>[BlobClientBuilder](/java/api/com.azure.storage.blob.blobclientbuilder)<br>[BlockBlobClient](/java/api/com.azure.storage.blob.specialized.blockblobclient)<br>[AppendBlobClient](/java/api/com.azure.storage.blob.specialized.appendblobclient)<br>[PageBlobClient](/java/api/com.azure.storage.blob.specialized.pageblobclient) | |
| 39 | +| JavaScript | [@azure/storage-blob](/javascript/api/overview/azure/storage-blob-readme) | [BlobServiceClient](/javascript/api/@azure/storage-blob/blobserviceclient) | [ContainerClient](/javascript/api/@azure/storage-blob/containerclient) | [BlobClient](/javascript/api/@azure/storage-blob/blobclient)<br>[BlockBlobClient](/javascript/api/@azure/storage-blob/blockblobclient)<br>[AppendBlobClient](/javascript/api/@azure/storage-blob/appendblobclient)<br>[PageBlobClient](/javascript/api/@azure/storage-blob/pageblobclient) | |
| 40 | +| Python | [azure.storage.blob](/python/api/azure-storage-blob/azure.storage.blob) | [BlobServiceClient](/python/api/azure-storage-blob/azure.storage.blob.blobserviceclient) | [ContainerClient](/python/api/azure-storage-blob/azure.storage.blob.containerclient) | [BlobClient](/python/api/azure-storage-blob/azure.storage.blob.blobclient)<sup>1 | |
| 41 | + |
| 42 | +<sup>1</sup> For Python, `BlobClient` includes methods for specialized blob types. |
| 43 | + |
| 44 | +Each client type can be instantiated by calling a simple constructor, or an overload that takes various configuration options. For Java, each client type has a separate class which provides a builder API to help with configuration and instantiation. Depending on the language SDK, these client configuration options are passed to the constructor in different ways. See the class reference from the table for details. |
| 45 | + |
| 46 | +## Authorize a client object |
| 47 | + |
| 48 | +For an app to access blob resources and interact with them, a client object must be authorized. The code samples in this article use [DefaultAzureCredential](/dotnet/api/azure.identity.defaultazurecredential) to authenticate to Azure via an Azure Active Directory (Azure AD) security principal. The authentication process includes obtaining an access token for authorization. This access token is passed as a credential when the client is instantiated, and the credential persists throughout the client lifetime. The Azure AD security principal requesting the token must be assigned an appropriate Azure RBAC role that grants access to blob data. To learn more, see [Assign an Azure role for access to blob data](assign-azure-role-data-access.md). |
| 49 | + |
| 50 | +The following authorization mechanisms can be used to grant the appropriate level of access to a client object: |
| 51 | +- [Azure AD](authorize-access-azure-active-directory.md): recommended for optimal security |
| 52 | +- [Shared access signature (SAS)](../common/storage-sas-overview.md): supported, and most secure when using a user delegation SAS token |
| 53 | +- [Account access key (Shared Key)](/rest/api/storageservices/authorize-with-shared-key): supported, but not recommended as it can be less secure |
| 54 | + |
| 55 | +To learn more about authorization, see [Authorize access to data in Azure Storage](../common/authorize-data-access.md). |
| 56 | + |
| 57 | +## Create a client object |
| 58 | + |
| 59 | +Working with any Azure resource using the SDK begins with creating a client object. In this section, you learn how to create client objects to interact with the three types of resources in the storage service: storage accounts, containers, and blobs. |
| 60 | + |
| 61 | +### Create a BlobServiceClient object |
| 62 | + |
| 63 | +An authorized `BlobServiceClient` object allows your app to interact with resources at the storage account level. |
| 64 | + |
| 65 | +A common scenario is to instantiate a single service client, then create container clients and blob clients from the service client, as needed. `BlobServiceClient` provides methods to retrieve and configure account properties, as well as list, create, and delete containers within the storage account. This client object is the starting point for interacting with resources in the storage account. |
| 66 | + |
| 67 | +To work with a specific container or blob, you can use the `BlobServiceClient` object to create a [container client](#create-a-blobcontainerclient-object) or [blob client](#create-a-blobclient-object). Clients created from a `BlobServiceClient` will inherit its client configuration, including client options and credentials. |
| 68 | + |
| 69 | +The following examples show how to create a `BlobServiceClient` object: |
| 70 | + |
| 71 | +## [.NET](#tab/dotnet) |
| 72 | + |
| 73 | +Add the following `using` directives: |
| 74 | + |
| 75 | +```csharp |
| 76 | +using Azure.Identity; |
| 77 | +using Azure.Storage.Blobs; |
| 78 | +``` |
| 79 | + |
| 80 | +Add the following code to create the client object: |
| 81 | + |
| 82 | +```csharp |
| 83 | +public BlobServiceClient GetBlobServiceClient(string accountName) |
| 84 | +{ |
| 85 | + BlobServiceClient client = new( |
| 86 | + new Uri($"https://{accountName}.blob.core.windows.net"), |
| 87 | + new DefaultAzureCredential()); |
| 88 | + |
| 89 | + return client; |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +## [Java](#tab/java) |
| 94 | + |
| 95 | +Add the following `import` directives: |
| 96 | + |
| 97 | +```java |
| 98 | +import com.azure.identity.*; |
| 99 | +import com.azure.storage.blob.*; |
| 100 | +``` |
| 101 | + |
| 102 | +Add the following code to create the client object: |
| 103 | + |
| 104 | +```java |
| 105 | +public BlobServiceClient GetBlobServiceClient(String accountName) { |
| 106 | + String endpointString = String.format("https://%s.blob.core.windows.net", accountName); |
| 107 | + BlobServiceClient client = new BlobServiceClientBuilder() |
| 108 | + .endpoint(endpointString) |
| 109 | + .credential(new DefaultAzureCredentialBuilder().build()) |
| 110 | + .buildClient(); |
| 111 | + |
| 112 | + return client; |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +## [JavaScript](#tab/javascript) |
| 117 | + |
| 118 | +Add the following `require` statements: |
| 119 | + |
| 120 | +```javascript |
| 121 | +const { BlobServiceClient } = require('@azure/storage-blob'); |
| 122 | +const { DefaultAzureCredential } = require('@azure/identity'); |
| 123 | +``` |
| 124 | + |
| 125 | +Add the following code to create the client object: |
| 126 | + |
| 127 | +```javascript |
| 128 | +const accountName = "<storage-account-name>"; |
| 129 | + |
| 130 | +const blobServiceClient = new BlobServiceClient( |
| 131 | + `https://${accountName}.blob.core.windows.net`, |
| 132 | + new DefaultAzureCredential() |
| 133 | +); |
| 134 | +``` |
| 135 | + |
| 136 | +## [Python](#tab/python) |
| 137 | + |
| 138 | +Add the following `import` statements: |
| 139 | + |
| 140 | +```python |
| 141 | +from azure.identity import DefaultAzureCredential |
| 142 | +from azure.storage.blob import BlobServiceClient |
| 143 | +``` |
| 144 | + |
| 145 | +Add the following code to create the client object: |
| 146 | + |
| 147 | +```python |
| 148 | +def get_blob_service_client(self, account_name): |
| 149 | + account_url = f"https://{account_name}.blob.core.windows.net" |
| 150 | + credential = DefaultAzureCredential() |
| 151 | + |
| 152 | + # Create the BlobServiceClient object |
| 153 | + blob_service_client = BlobServiceClient(account_url, credential=credential) |
| 154 | + |
| 155 | + return blob_service_client |
| 156 | +``` |
| 157 | + |
| 158 | +--- |
| 159 | + |
| 160 | +### Create a BlobContainerClient object |
| 161 | + |
| 162 | + You can use a `BlobServiceClient` object to create a new `BlobContainerClient` object (`ContainerClient` for JavaScript and Python). A `BlobContainerClient` object allows you to interact with a specific container resource. This resource doesn't need to exist in the storage account for you to create the client object. `BlobContainerClient` provides methods to create, delete, or configure a container, and includes methods to list, upload, and delete the blobs within it. To perform operations on a specific blob within the container, you can [create a blob client](#create-a-blobclient-object). |
| 163 | + |
| 164 | +The following examples show how to create a container client from a `BlobServiceClient` object to interact with a specific container resource: |
| 165 | + |
| 166 | +## [.NET](#tab/dotnet) |
| 167 | + |
| 168 | +```csharp |
| 169 | +public BlobContainerClient GetBlobContainerClient( |
| 170 | + BlobServiceClient blobServiceClient, |
| 171 | + string containerName) |
| 172 | +{ |
| 173 | + // Create the container client using the service client object |
| 174 | + BlobContainerClient client = blobServiceClient.GetBlobContainerClient(containerName); |
| 175 | + return client; |
| 176 | +} |
| 177 | +``` |
| 178 | + |
| 179 | +## [Java](#tab/java) |
| 180 | + |
| 181 | +```java |
| 182 | +public BlobContainerClient getBlobContainerClient( |
| 183 | + BlobServiceClient blobServiceClient, |
| 184 | + String containerName) { |
| 185 | + // Create the container client using the service client object |
| 186 | + BlobContainerClient client = blobServiceClient.getBlobContainerClient(containerName); |
| 187 | + return client; |
| 188 | +} |
| 189 | +``` |
| 190 | + |
| 191 | +## [JavaScript](#tab/javascript) |
| 192 | + |
| 193 | +```javascript |
| 194 | +const containerName = "sample-container"; |
| 195 | +let containerClient = blobServiceClient.getContainerClient(containerName); |
| 196 | +``` |
| 197 | + |
| 198 | +## [Python](#tab/python) |
| 199 | + |
| 200 | +```python |
| 201 | +def get_blob_container_client(self, blob_service_client: BlobServiceClient, container_name): |
| 202 | + container_client = blob_service_client.get_container_client(container=container_name) |
| 203 | + return container_client |
| 204 | +``` |
| 205 | + |
| 206 | +--- |
| 207 | + |
| 208 | +If your work is narrowly scoped to a single container, you might choose to create a `BlobContainerClient` object directly without using `BlobServiceClient`. You can still set client options on a container client just like you would on a service client. |
| 209 | + |
| 210 | +The following examples show how to create a container client directly *without* using `BlobServiceClient`: |
| 211 | + |
| 212 | +## [.NET](#tab/dotnet) |
| 213 | + |
| 214 | +```csharp |
| 215 | +public BlobContainerClient GetBlobContainerClient( |
| 216 | + string accountName, |
| 217 | + string containerName, |
| 218 | + BlobClientOptions clientOptions) |
| 219 | +{ |
| 220 | + // Append the container name to the end of the URI |
| 221 | + BlobContainerClient client = new( |
| 222 | + new Uri($"https://{accountName}.blob.core.windows.net/{containerName}"), |
| 223 | + new DefaultAzureCredential(), |
| 224 | + clientOptions); |
| 225 | + |
| 226 | + return client; |
| 227 | +} |
| 228 | +``` |
| 229 | + |
| 230 | +## [Java](#tab/java) |
| 231 | + |
| 232 | +```java |
| 233 | +public BlobContainerClient getBlobContainerClient( |
| 234 | + String accountName, |
| 235 | + String containerName) { |
| 236 | + // Append the container name to the URI |
| 237 | + String endpointString = String.format("https://%s.blob.core.windows.net/%s", |
| 238 | + accountName, containerName); |
| 239 | + |
| 240 | + BlobContainerClient client = new BlobContainerClientBuilder() |
| 241 | + .endpoint(endpointString) |
| 242 | + .credential(new DefaultAzureCredentialBuilder().build()) |
| 243 | + .buildClient(); |
| 244 | + |
| 245 | + return client; |
| 246 | +} |
| 247 | +``` |
| 248 | + |
| 249 | +## [JavaScript](#tab/javascript) |
| 250 | + |
| 251 | +```javascript |
| 252 | +const accountName = "<storage-account-name>"; |
| 253 | +const containerName = "sample-container"; |
| 254 | + |
| 255 | +// Append the container name to the URI |
| 256 | +const containerClient = new ContainerClient( |
| 257 | + `https://${accountName}.blob.core.windows.net/${containerName}`, |
| 258 | + new DefaultAzureCredential() |
| 259 | +``` |
| 260 | +
|
| 261 | +## [Python](#tab/python) |
| 262 | +
|
| 263 | +```python |
| 264 | +def get_blob_container_client(self, account_name, container_name): |
| 265 | + # Append the container name to the URI |
| 266 | + account_url = f"https://{account_name}.blob.core.windows.net/{container_name}" |
| 267 | + credential = DefaultAzureCredential() |
| 268 | + |
| 269 | + # Create the client object |
| 270 | + container_client = ContainerClient(account_url, credential=credential) |
| 271 | + |
| 272 | + return container_client |
| 273 | +``` |
| 274 | +
|
| 275 | +--- |
| 276 | +
|
| 277 | +### Create a BlobClient object |
| 278 | +
|
| 279 | +To interact with a specific blob resource, create a `BlobClient` object from a service client or container client. A `BlobClient` object allows you to interact with a specific blob resource. This resource doesn't need to exist in the storage account for you to create the client object. `BlobClient` provides methods to upload, download, delete, and create snapshots of a blob. |
| 280 | +
|
| 281 | +The following examples show how to create a blob client to interact with a specific blob resource: |
| 282 | +
|
| 283 | +## [.NET](#tab/dotnet) |
| 284 | +
|
| 285 | +```csharp |
| 286 | +public BlobClient GetBlobClient( |
| 287 | + BlobServiceClient blobServiceClient, |
| 288 | + string containerName, |
| 289 | + string blobName) |
| 290 | +{ |
| 291 | + BlobClient client = |
| 292 | + blobServiceClient.GetBlobContainerClient(containerName).GetBlobClient(blobName); |
| 293 | + return client; |
| 294 | +} |
| 295 | +``` |
| 296 | +
|
| 297 | +## [Java](#tab/java) |
| 298 | +
|
| 299 | +```java |
| 300 | +public BlobClient getBlobClient( |
| 301 | + BlobServiceClient blobServiceClient, |
| 302 | + String containerName, |
| 303 | + String blobName) { |
| 304 | + // Create a blob client using the service client object |
| 305 | + BlobClient client = blobServiceClient.getBlobContainerClient(containerName).getBlobClient(blobName); |
| 306 | + return client; |
| 307 | +} |
| 308 | +``` |
| 309 | +
|
| 310 | +## [JavaScript](#tab/javascript) |
| 311 | +
|
| 312 | +```javascript |
| 313 | +const containerName = "sample-container"; |
| 314 | +const blobName = "sample-blob"; |
| 315 | +let blobClient = blobServiceClient.getContainerClient(containerName).getBlobClient(blobName); |
| 316 | +``` |
| 317 | +
|
| 318 | +## [Python](#tab/python) |
| 319 | +
|
| 320 | +```python |
| 321 | +def get_blob_client(self, blob_service_client: BlobServiceClient, container_name, blob_name): |
| 322 | + # Create a blob client using the service client object |
| 323 | + blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name) |
| 324 | + return blob_client |
| 325 | +``` |
| 326 | +
|
| 327 | +--- |
| 328 | +
|
| 329 | +## Manage client objects |
| 330 | +
|
| 331 | +A best practice for Azure SDK client management is to treat a client as a singleton, meaning that a class will only have one object at a time. There's no need to keep more than one instance of a client for a given set of constructor parameters or client options. This concept can be implemented in many ways, including: |
| 332 | +
|
| 333 | +- Creating a single client object and passing it as a parameter throughout the application. This approach is shown in the code examples in this article. |
| 334 | +- Storing a client instance in a field. To learn more about C# fields, see [Fields (C# Programming Guide)](/dotnet/csharp/programming-guide/classes-and-structs/fields). |
| 335 | +- Registering the client object as a singleton in a dependency injection container of your choice. For more information on dependency injection in ASP.NET Core apps, see [Dependency injection with the Azure SDK for .NET](/dotnet/azure/sdk/dependency-injection). |
| 336 | +
|
| 337 | +This approach is far more efficient at scale than calling a constructor for each client that you need. |
| 338 | +
|
| 339 | +### Client immutability and thread safety |
| 340 | +
|
| 341 | +Azure SDK clients are immutable after they're created, which means that you can't change the endpoint it connects to, the credential used for authorization, or other values passed in as client options. Client immutability also means that clients are safe to share and reuse throughout the application. |
| 342 | +
|
| 343 | +If your app needs to use different configurations or credentials for clients of the same type, you can instantiate a client for each set of configuration options. |
| 344 | +
|
| 345 | +The Azure SDK guarantees that all client instance methods are thread-safe and independent of each other. This design ensures that sharing and reusing client instances is always safe, even across threads. |
| 346 | +
|
| 347 | +## Next steps |
| 348 | +
|
| 349 | +To learn more about using the Azure Storage client libraries to work with data resources, see the following articles: |
| 350 | +- [Get started with Azure Blob Storage and .NET](storage-blob-dotnet-get-started.md) |
| 351 | +- [Get started with Azure Blob Storage and Java](storage-blob-java-get-started.md) |
| 352 | +- [Get started with Azure Blob Storage and JavaScript](storage-blob-javascript-get-started.md) |
| 353 | +- [Get started with Azure Blob Storage and Python](storage-blob-python-get-started.md) |
0 commit comments