Skip to content

Commit

Permalink
[Client SDK] Improve ergonomics (#339)
Browse files Browse the repository at this point in the history
* Simplifies search APIs on `NuGetClient`
* Makes it a little easier to create a `CatalogProcessor`
  • Loading branch information
loic-sharma authored Sep 17, 2019
1 parent 61c288a commit 059662e
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 41 deletions.
8 changes: 3 additions & 5 deletions docs/tools/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,10 @@ Search for "json" packages:

```csharp
NuGetClient client = new NuGetClient("https://api.nuget.org/v3/index.json");
SearchResponse response = await client.SearchAsync("json");
IReadOnlyList<SearchResult> results = await client.SearchAsync("json");

Console.WriteLine($"Found {response.TotalHits} total results");

foreach (SearchResult searchResult in response.Data)
foreach (SearchResult result in results)
{
Console.WriteLine($"Found package {searchResult.Id} {searchResult.Version}");
Console.WriteLine($"Found package {result.PackageId} {searchResult.Version}");
}
```
25 changes: 10 additions & 15 deletions samples/Sample02_Search.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using BaGet.Protocol.Models;
using Xunit;
Expand All @@ -12,18 +13,16 @@ public async Task Search()
{
// Search for packages that are relevant to "json".
NuGetClient client = new NuGetClient("https://api.nuget.org/v3/index.json");
SearchResponse response = await client.SearchAsync("json");

Console.WriteLine($"Found {response.TotalHits} results");
IReadOnlyList<SearchResult> results = await client.SearchAsync("json");

var index = 1;
foreach (SearchResult searchResult in response.Data)
foreach (SearchResult result in results)
{
Console.WriteLine($"Result #{index}");
Console.WriteLine($"Package id: {searchResult.PackageId}");
Console.WriteLine($"Package version: {searchResult.Version}");
Console.WriteLine($"Package downloads: {searchResult.TotalDownloads}");
Console.WriteLine($"Package versions: {searchResult.Versions.Count}");
Console.WriteLine($"Package id: {result.PackageId}");
Console.WriteLine($"Package version: {result.Version}");
Console.WriteLine($"Package downloads: {result.TotalDownloads}");
Console.WriteLine($"Package versions: {result.Versions.Count}");
Console.WriteLine();

index++;
Expand All @@ -35,15 +34,11 @@ public async Task Autocomplete()
{
// Search for packages whose names' start with "Newt".
NuGetClient client = new NuGetClient("https://api.nuget.org/v3/index.json");
AutocompleteResponse response = await client.AutocompleteAsync("Newt");

Console.WriteLine($"Found {response.TotalHits} results");
IReadOnlyList<string> packageIds = await client.AutocompleteAsync("Newt");

var index = 1;
foreach (string packageId in response.Data)
foreach (string packageId in packageIds)
{
Console.WriteLine($"Found package ID #{index}: '{packageId}'");
index++;
Console.WriteLine($"Found package ID '{packageId}'");
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions src/BaGet.Protocol/Extensions/NuGetClientFactoryExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System.Threading;
using System.Threading.Tasks;
using BaGet.Protocol.Catalog;
using Microsoft.Extensions.Logging;

namespace BaGet.Protocol
{
public static class NuGetClientFactoryExtensions
{
/// <summary>
/// Create a new <see cref="CatalogProcessor"/> to discover and download catalog leafs.
/// Leafs are processed by the <see cref="ICatalogLeafProcessor"/>.
/// </summary>
/// <param name="clientFactory">The factory used to create NuGet clients.</param>
/// <param name="cursor">Cursor to track succesfully processed leafs. Leafs before the cursor are skipped.</param>
/// <param name="leafProcessor">The leaf processor.</param>
/// <param name="options">The options to configure catalog processing.</param>
/// <param name="logger">The logger used for telemetry.</param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The catalog processor.</returns>
public static async Task<CatalogProcessor> CreateCatalogProcessorAsync(
this NuGetClientFactory clientFactory,
ICursor cursor,
ICatalogLeafProcessor leafProcessor,
CatalogProcessorOptions options,
ILogger<CatalogProcessor> logger,
CancellationToken cancellationToken = default)
{
var catalogClient = await clientFactory.CreateCatalogClientAsync(cancellationToken);

return new CatalogProcessor(
cursor,
catalogClient,
leafProcessor,
options,
logger);
}
}
}
64 changes: 48 additions & 16 deletions src/BaGet.Protocol/NuGetClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,11 +254,14 @@ public virtual async Task<PackageMetadata> GetPackageMetadataAsync(string packag
/// </param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The search results, including prerelease packages.</returns>
public virtual async Task<SearchResponse> SearchAsync(string query = null, CancellationToken cancellationToken = default)
public virtual async Task<IReadOnlyList<SearchResult>> SearchAsync(
string query = null,
CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);
var response = await client.SearchAsync(query, cancellationToken: cancellationToken);

return await client.SearchAsync(query, cancellationToken: cancellationToken);
return response.Data;
}

/// <summary>
Expand All @@ -270,14 +273,18 @@ public virtual async Task<SearchResponse> SearchAsync(string query = null, Cance
/// <param name="includePrerelease">Whether to include prerelease packages.</param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The search results.</returns>
public virtual async Task<SearchResponse> SearchAsync(string query, bool includePrerelease, CancellationToken cancellationToken = default)
public virtual async Task<IReadOnlyList<SearchResult>> SearchAsync(
string query,
bool includePrerelease,
CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);

return await client.SearchAsync(
var response = await client.SearchAsync(
query,
includePrerelease: includePrerelease,
cancellationToken: cancellationToken);

return response.Data;
}

/// <summary>
Expand All @@ -290,11 +297,20 @@ public virtual async Task<SearchResponse> SearchAsync(string query, bool include
/// <param name="take">The number of results to include.</param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The search results, including prerelease packages.</returns>
public virtual async Task<SearchResponse> SearchAsync(string query, int skip, int take, CancellationToken cancellationToken = default)
public virtual async Task<IReadOnlyList<SearchResult>> SearchAsync(
string query,
int skip,
int take,
CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);
var response = await client.SearchAsync(
query,
skip,
take,
cancellationToken: cancellationToken);

return await client.SearchAsync(query, skip, take, cancellationToken: cancellationToken);
return response.Data;
}

/// <summary>
Expand All @@ -308,11 +324,23 @@ public virtual async Task<SearchResponse> SearchAsync(string query, int skip, in
/// <param name="take">The number of results to include.</param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The search results, including prerelease packages.</returns>
public virtual async Task<SearchResponse> SearchAsync(string query, bool includePrerelease, int skip, int take, CancellationToken cancellationToken = default)
public virtual async Task<IReadOnlyList<SearchResult>> SearchAsync(
string query,
bool includePrerelease,
int skip,
int take,
CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);
var response = await client.SearchAsync(
query,
skip,
take,
includePrerelease,
includeSemVer2: true,
cancellationToken);

return await client.SearchAsync(query, skip, take, includePrerelease, includeSemVer2: true, cancellationToken);
return response.Data;
}

/// <summary>
Expand All @@ -322,12 +350,15 @@ public virtual async Task<SearchResponse> SearchAsync(string query, bool include
/// The search query. If <see langword="null"/>, gets default autocomplete results.
/// </param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The autocomplete results.</returns>
public virtual async Task<AutocompleteResponse> AutocompleteAsync(string query = null, CancellationToken cancellationToken = default)
/// <returns>The package IDs that matched the query.</returns>
public virtual async Task<IReadOnlyList<string>> AutocompleteAsync(
string query = null,
CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);
var response = await client.AutocompleteAsync(query, cancellationToken: cancellationToken);

return await client.AutocompleteAsync(query, cancellationToken: cancellationToken);
return response.Data;
}

/// <summary>
Expand All @@ -339,16 +370,17 @@ public virtual async Task<AutocompleteResponse> AutocompleteAsync(string query =
/// <param name="skip">The number of results to skip.</param>
/// <param name="take">The number of results to include.</param>
/// <param name="cancellationToken">A token to cancel the task.</param>
/// <returns>The autocomplete results.</returns>
public virtual async Task<AutocompleteResponse> AutocompleteAsync(string query, int skip, int take, CancellationToken cancellationToken = default)
/// <returns>The package IDs that matched the query.</returns>
public virtual async Task<IReadOnlyList<string>> AutocompleteAsync(string query, int skip, int take, CancellationToken cancellationToken = default)
{
var client = await _clientFactory.CreateSearchClientAsync(cancellationToken);

return await client.AutocompleteAsync(
var response = await client.AutocompleteAsync(
query,
skip: skip,
take: take,
cancellationToken: cancellationToken);

return response.Data;
}
}
}
8 changes: 3 additions & 5 deletions src/BaGet.Protocol/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,10 @@ Search for "json" packages:

```csharp
NuGetClient client = new NuGetClient("https://api.nuget.org/v3/index.json");
SearchResponse response = await client.SearchAsync("json");
IReadOnlyList<SearchResult> results = await client.SearchAsync("json");

Console.WriteLine($"Found {response.TotalHits} total results");

foreach (SearchResult searchResult in response.Data)
foreach (SearchResult result in results)
{
Console.WriteLine($"Found package {searchResult.Id} {searchResult.Version}");
Console.WriteLine($"Found package {result.PackageId} {searchResult.Version}");
}
```

0 comments on commit 059662e

Please sign in to comment.