Skip to content

Commit 9f69146

Browse files
authored
Merge pull request #226111 from pauljewellmsft/pauljewell-client-management
Add new article for client creation and management
2 parents fbc6cc2 + 5bf61c5 commit 9f69146

File tree

2 files changed

+355
-0
lines changed

2 files changed

+355
-0
lines changed

articles/storage/blobs/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,8 @@ items:
582582
href: ../common/storage-auth-aad-app.md?toc=/azure/storage/blobs/toc.json&bc=/azure/storage/blobs/breadcrumb/toc.json
583583
- name: Write code
584584
items:
585+
- name: Create and manage client objects
586+
href: storage-blob-client-management.md
585587
- name: .NET
586588
items:
587589
- name: Get started
Lines changed: 353 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,353 @@
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

Comments
 (0)