Skip to content

Commit

Permalink
Edit pass on protocol methods doc (#42396)
Browse files Browse the repository at this point in the history
* Edit pass on protocol methods doc

* Fix errors

* Update description to meet min length req

* Tweak

* Test

* Verbiage tweak

* Improve code sample

* Update diff and patterns list

* Code formatting

* React to feedback
  • Loading branch information
scottaddie authored Aug 30, 2024
1 parent 58d8e24 commit 2ee642b
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 35 deletions.
49 changes: 23 additions & 26 deletions docs/azure/sdk/protocol-convenience-methods.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: Understand Azure SDK client library method types
description: Learn about the key differences between Azure SDK client library protocol and convenience methods.
description: Learn about the key differences between protocol and convenience methods in the Azure SDK client libraries for .NET.
ms.topic: conceptual
ms.custom: devx-track-dotnet, engagement-fy23, devx-track-arm-template
ms.date: 08/29/2024
ms.date: 08/30/2024
---

# Azure SDK for .NET protocol and convenience methods overview
Expand All @@ -15,15 +15,13 @@ The Azure SDK client libraries provide an interface to Azure services by transla
An Azure SDK for .NET client library can expose two different categories of methods to make requests to an Azure service:

- **Protocol methods** provide a thin wrapper around the underlying REST API for a corresponding Azure service. These methods map primitive input parameters to HTTP request values and return a raw HTTP response object.

- **Convenience methods** provide a convenience layer over the lower-level protocol layer to add support for the .NET type system and other benefits. Convenience methods accept primitives or .NET model types as parameters and map them to the body of an underlying REST API request. These methods also handle various details of request and response management to allow developers to focus on sending and receiving data objects, instead of lower-level concerns.

### Azure SDK client library dependency patterns

Protocol and convenience methods implement slightly different patterns based on the underlying package dependency chain of the respective library. An Azure SDK for .NET client library depends on one of two different foundational libraries:

- [**Azure.Core**](/dotnet/api/overview/azure/core-readme) provides shared primitives, abstractions, and helpers for building modern Azure SDK client libraries. These libraries follow the [Azure SDK Design Guidelines for .NET](https://azure.github.io/azure-sdk/dotnet_introduction.html) and use package names and namespaces prefixed with *Azure*, such as [`Azure.Storage.Blobs`](/dotnet/api/overview/azure/storage.blobs-readme).

- [**System.ClientModel**](/dotnet/api/overview/azure/system.clientmodel-readme) is a core library that provides shared primitives, abstractions, and helpers for .NET service client libraries. The `System.ClientModel` library is a general purpose toolset designed to help build libraries for various platforms and services, whereas the `Azure.Core` library is specifically designed for building Azure client libraries.

> [!NOTE]
Expand All @@ -34,8 +32,8 @@ The following table compares some of the request and response types used by prot
| Request or response concern | Azure.Core | System.ClientModel |
|-------------------------------|----------------------------------|-------------------------------------------------------|
| Request body | <xref:Azure.Core.RequestContent> | <xref:System.ClientModel.BinaryContent> |
| Advanced options | <xref:Azure.RequestContext> | <xref:System.ClientModel.Primitives.RequestOptions> |
| Raw HTTP Response | <xref:Azure.Response> | <xref:System.ClientModel.Primitives.PipelineResponse> |
| Advanced request options | <xref:Azure.RequestContext> | <xref:System.ClientModel.Primitives.RequestOptions> |
| Raw HTTP response | <xref:Azure.Response> | <xref:System.ClientModel.Primitives.PipelineResponse> |
| Return type with output model | <xref:Azure.Response%601> | <xref:System.ClientModel.ClientResult%601> |

The sections ahead provide implementation examples of these concepts.
Expand All @@ -52,7 +50,7 @@ Azure SDK client libraries adhering to the [latest design guidelines](https://az

The following code uses a `ContentSafetyClient` to call the `AnalyzeText` convenience method:

:::code source="snippets/protocol-convenience-methods/AzureCoreConvenience/Program.cs" highlight="10":::
:::code source="snippets/protocol-convenience-methods/AzureCore/Convenience/Program.cs" highlight="10":::

The preceding code demonstrates the following `Azure.Core` convenience method patterns:

Expand All @@ -63,17 +61,18 @@ The preceding code demonstrates the following `Azure.Core` convenience method pa

The following code uses a `ContentSafetyClient` to call the `AnalyzeText` protocol method:

:::code source="snippets/protocol-convenience-methods/AzureCoreProtocol/Program.cs" highlight="19-24":::
:::code source="snippets/protocol-convenience-methods/AzureCore/Protocol/Program.cs" highlight="19-24":::

The preceding code demonstrates the following protocol method patterns:
The preceding code demonstrates the following `Azure.Core` protocol method patterns:

- Uses the `RequestContent` type to supply data for the request body.
- Uses the `RequestContext` type to configure request options.
- Returns data using the `Response` type.
- Reads content from the response data into a [dynamic](../../csharp/advanced-topics/interop/using-type-dynamic.md) type using <xref:Azure.AzureCoreExtensions.ToDynamicFromJson%2A>. For more information, see [Announcing dynamic JSON in the Azure Core library for .NET](https://devblogs.microsoft.com/azure-sdk/dynamic-json-in-azure-core/).
1. **Create the request**, using a `RequestContent` object for the request body.
1. **Invoke the protocol method**, using a `RequestContext` object to configure request options.
1. **Handle the response** by reading:
- The HTTP status code from the `Response` object to determine success or failure.
- Data from the `Response` object's content into a [dynamic](../../csharp/advanced-topics/interop/using-type-dynamic.md) type using <xref:Azure.AzureCoreExtensions.ToDynamicFromJson%2A>. For more information, see [Announcing dynamic JSON in the Azure Core library for .NET](https://devblogs.microsoft.com/azure-sdk/dynamic-json-in-azure-core/).

> [!NOTE]
> The preceding code configures the `ClientErrorBehaviors.NoThrow` for the `RequestOptions`. This option prevents non-success service responses status codes from throwing an exception, which means the app code should manually handle the response status code checks.
> The preceding code configures the [ErrorOptions.NoThrow](/dotnet/api/azure.erroroptions) behavior. This option prevents non-success service responses status codes from throwing an exception, which means the app code should manually handle the response status code checks.
---

Expand All @@ -85,7 +84,7 @@ Some client libraries that connect to non-Azure services use patterns similar to

Consider the following code that uses a `ChatClient` to call the `CompleteChat` convenience method:

:::code source="snippets/protocol-convenience-methods/SCMConvenience/Program.cs" highlight="9":::
:::code source="snippets/protocol-convenience-methods/SCM/Convenience/Program.cs" highlight="9":::

The preceding code demonstrates the following `System.ClientModel` convenience method patterns:

Expand All @@ -96,14 +95,15 @@ The preceding code demonstrates the following `System.ClientModel` convenience m

The following code uses a `ChatClient` to call the `CompleteChat` protocol method:

:::code source="snippets/protocol-convenience-methods/SCMProtocol/Program.cs" highlight="26-31":::
:::code source="snippets/protocol-convenience-methods/SCM/Protocol/Program.cs" highlight="26-31":::

The preceding code demonstrates the following `System.ClientModel` protocol method patterns:

- Uses the `BinaryContent` type as a parameter to supply data for the request body.
- Uses the `RequestContext` type to configure request options.
- Returns data using the `ClientResult` type.
- Calls the <xref:System.ClientModel.ClientResult.GetRawResponse%2A> method to access the response data.
1. **Create the request**, using a `BinaryContent` object for the request body.
1. **Invoke the protocol method**, using a `RequestOptions` object to configure request options.
1. **Handle the response** by reading:
- The HTTP status code from the `PipelineResponse` object to determine success or failure.
- Data from the `PipelineResponse` object's content using `System.Text.Json` APIs.

> [!NOTE]
> The preceding code configures the [ClientErrorBehaviors.NoThrow](/dotnet/api/system.clientmodel.primitives.clienterrorbehaviors) behavior for the `RequestOptions`. This option prevents non-success service responses status codes from throwing an exception, which means the app code should manually handle the response status code checks.
Expand All @@ -113,9 +113,8 @@ A `System.ClientModel`-based response can be processed like a convenience model,
```diff
PipelineResponse response = result.GetRawResponse();

- BinaryData output = result.GetRawResponse().Content;
- using JsonDocument outputAsJson = JsonDocument.Parse(output);
- JsonElement message = outputAsJson.RootElement
- using JsonDocument output = JsonDocument.Parse(response.Content);
- JsonElement message = output.RootElement
- .GetProperty("choices"u8)[0]
- .GetProperty("message"u8);

Expand Down Expand Up @@ -147,6 +146,4 @@ Protocol methods:

## See also

- [Understanding the Azure Core library for .NET](https://devblogs.microsoft.com/azure-sdk/understanding-the-azure-core-library-for-net/)
- [Azure.Core library for .NET](/dotnet/api/overview/azure/core-readme)
- [System.ClientModel library for .NET](/dotnet/api/overview/azure/system.clientmodel-readme)
[Understanding the Azure Core library for .NET](https://devblogs.microsoft.com/azure-sdk/understanding-the-azure-core-library-for-net/)
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.AI.ContentSafety" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageVersion Include="Azure.Identity" Version="1.12.0" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.AI.ContentSafety" Version="1.0.0" />
<PackageReference Include="Azure.Identity" Version="1.12.0" />
<PackageReference Include="Azure.AI.ContentSafety" />
<PackageReference Include="Azure.Identity" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="OpenAI" Version="2.0.0-beta.10" />
<PackageReference Include="OpenAI" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="OpenAI" Version="2.0.0-beta.10" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@
throw new ClientResultException(response);
}

BinaryData output = result.GetRawResponse().Content;
using JsonDocument outputAsJson = JsonDocument.Parse(output);
JsonElement message = outputAsJson.RootElement
using JsonDocument output = JsonDocument.Parse(response.Content);
JsonElement message = output.RootElement
.GetProperty("choices"u8)[0]
.GetProperty("message"u8);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="OpenAI" Version="2.0.0-beta.10" />
<PackageReference Include="OpenAI" />
</ItemGroup>

</Project>

0 comments on commit 2ee642b

Please sign in to comment.