Skip to content

Commit

Permalink
Added guide for using raw JSON REST requests with low-level client. (#…
Browse files Browse the repository at this point in the history
…406)

* Added guide for using raw JSON REST requests with low-level client.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Added sample for using raw JSON REST requests with low-level client.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Added sample for using raw JSON REST requests with low-level client #2

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Created new samples project & PR review changes.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Aligned action examples with Python guide.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

PR change requests.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Changed to raw JSON in sample code.

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

Added new section to the guide for using PostData.Serializable()

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>

* Expand description of PostData types

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

* Complete working sample

Signed-off-by: Thomas Farr <tsfarr@amazon.com>

---------

Signed-off-by: Djcarrillo6 <djcarrillo6@yahoo.com>
Signed-off-by: Thomas Farr <tsfarr@amazon.com>
Co-authored-by: Thomas Farr <tsfarr@amazon.com>
  • Loading branch information
Djcarrillo6 and Xtansia authored Nov 13, 2023
1 parent 35a0fd8 commit 1924be9
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 0 deletions.
9 changes: 9 additions & 0 deletions OpenSearch.sln
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenSearch.Stack.ArtifactsA
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{22DF419F-9A90-4317-957D-E239EB3F95DF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{E89FE975-FA94-405F-B748-BF2EC8AFFEEE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "samples\Samples\Samples.csproj", "{0D084660-06BF-4F3A-A041-DAAB4837378F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -137,6 +141,7 @@ Global
{22DF419F-9A90-4317-957D-E239EB3F95DF} = {87ABA679-F3F4-48CE-82B3-1AAE5D0A5935}
{C80D225C-F072-4B24-9ACE-82EFD9362237} = {22DF419F-9A90-4317-957D-E239EB3F95DF}
{1F5A7B1A-2566-481F-91B5-A63D7F939973} = {22DF419F-9A90-4317-957D-E239EB3F95DF}
{0D084660-06BF-4F3A-A041-DAAB4837378F} = {E89FE975-FA94-405F-B748-BF2EC8AFFEEE}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5B393962-7586-49BA-BD99-3B1E35F48E94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -231,5 +236,9 @@ Global
{E7C0BDC2-28AD-4582-8FEA-0F6327A42C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7C0BDC2-28AD-4582-8FEA-0F6327A42C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7C0BDC2-28AD-4582-8FEA-0F6327A42C0E}.Release|Any CPU.Build.0 = Release|Any CPU
{0D084660-06BF-4F3A-A041-DAAB4837378F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D084660-06BF-4F3A-A041-DAAB4837378F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D084660-06BF-4F3A-A041-DAAB4837378F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D084660-06BF-4F3A-A041-DAAB4837378F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
7 changes: 7 additions & 0 deletions USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- [OpenSearch.Net](#opensearchnet)
- [Getting Started](#getting-started-2)
- [Connecting](#connecting-2)
- [Advanced Features](#advanced-features)

# User Guide

This user guide specifies how to include and use the .NET client in your application.
Expand Down Expand Up @@ -303,3 +305,8 @@ var client = new OpenSearchLowLevelClient(config);
```

Note the main difference here is that we are instantiating an `OpenSearchLowLevelClient` rather than `OpenSearchClient`, and `ConnectionConfiguration` instead of `ConnectionSettings`.


## Advanced Features

- [Making Raw JSON Requests](guides/json.md)
131 changes: 131 additions & 0 deletions guides/json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
- [Making Raw JSON REST Requests](#making-raw-json-rest-requests)
- [HTTP Methods](#http-methods)
- [GET](#get)
- [PUT](#put)
- [POST](#post)
- [DELETE](#delete)
- [Using Different Types Of PostData](#using-different-types-of-postdata)
- [PostData.String](#postdatastring)
- [PostData.Bytes](#postdatabytes)
- [PostData.Serializable](#postdataserializable)
- [PostData.MultiJson](#postdatamultijson)

# Making Raw JSON REST Requests
OpenSearch exposes a REST API that you can use to interact with OpenSearch. The OpenSearch .NET client provides a low-level API that allows you to send raw JSON requests to OpenSearch. This API is useful if you want to use a feature that is not yet supported by the OpenSearch .NET client, but it supported by the OpenSearch REST API.

The OpenSearch client implements many high-level REST DSLs that invoke OpenSearch APIs. However you may find yourself in a situation that requires you to invoke an API that is not supported by the client. You can use `client.LowLevel.DoRequest` to do so. See [samples/Samples/RawJsonSample/Program.cs](../samples/Samples/RawJsonSample/Program.cs) for a complete working sample.

## HTTP Methods

### GET
The following example returns the server version information via `GET /`.

```csharp
var info = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.GET, "/", CancellationToken.None);
Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!");
```

### PUT
The following example creates an index.

```csharp
var indexBody = new { settings = new { index = new { number_of_shards = 4 } } };

var createIndex = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Serializable(indexBody));
Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation);
```

### POST
The following example searches for a document.

```csharp
const string q = "miller";

var query = new
{
size = 5,
query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } }
};

var search = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.POST, $"/{indexName}/_search", CancellationToken.None, PostData.Serializable(query));
Debug.Assert(search.Success, search.DebugInformation);

foreach (var hit in search.Body.hits.hits) Console.WriteLine(hit["_source"]["title"]);
```

### DELETE
The following example deletes an index.

```csharp
var deleteDocument = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.DELETE, $"/{indexName}/_doc/{id}", CancellationToken.None);
Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation);
```

## Using Different Types Of PostData
The OpenSearch .NET client provides a `PostData` class that is used to provide the request body for a request. The `PostData` class has several static methods that can be used to create a `PostData` object from different types of data.

### PostData.String
The following example shows how to use the `PostData.String` method to create a `PostData` object from a string.

```csharp
string indexBody = @"
{{
""settings"": {
""index"": {
""number_of_shards"": 4
}
}
}}";

await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.String(indexBody));
```

### PostData.Bytes
The following example shows how to use the `PostData.Bytes` method to create a `PostData` object from a byte array.

```csharp
byte[] indexBody = Encoding.UTF8.GetBytes(@"
{{
""settings"": {
""index"": {
""number_of_shards"": 4
}
}
}}");

await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Bytes(indexBody));
```

### PostData.Serializable
The following example shows how to use the `PostData.Serializable` method to create a `PostData` object from a serializable object.

```csharp
var indexBody = new
{
settings = new
{
index = new
{
number_of_shards = 4
}
}
};

await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, "/movies", CancellationToken.None, PostData.Serializable(indexBody));
```

### PostData.MultiJson
The following example shows how to use the `PostData.MultiJson` method to create a `PostData` object from a collection of serializable objects.
The `PostData.MultiJson` method is useful when you want to send multiple documents in a bulk request.

```csharp
var bulkBody = new object[]
{
new { index = new { _index = "movies", _id = "1" } },
new { title = "The Godfather", director = "Francis Ford Coppola", year = 1972 },
new { index = new { _index = "movies", _id = "2" } },
new { title = "The Godfather: Part II", director = "Francis Ford Coppola", year = 1974 }
};

await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.POST, "/_bulk", CancellationToken.None, PostData.MultiJson(bulkBody));
```
71 changes: 71 additions & 0 deletions samples/Samples/RawJsonSample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

using System.Diagnostics;
using OpenSearch.Client;
using OpenSearch.Net;
using HttpMethod = OpenSearch.Net.HttpMethod;

public class Program
{
public static async Task Main(string[] args)
{
var node = new Uri("http://localhost:9200");
var config = new ConnectionSettings(node)
.ServerCertificateValidationCallback(CertificateValidations.AllowAll)
.BasicAuthentication("admin", "admin")
.DisableDirectStreaming();

var client = new OpenSearchClient(config);

var info = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.GET, "/", CancellationToken.None);
Console.WriteLine($"Welcome to {info.Body.version.distribution} {info.Body.version.number}!");

// Create an index

const string indexName = "movies";

var indexBody = new { settings = new { index = new { number_of_shards = 4 } } };

var createIndex = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, $"/{indexName}", CancellationToken.None, PostData.Serializable(indexBody));
Debug.Assert(createIndex.Success && (bool)createIndex.Body.acknowledged, createIndex.DebugInformation);

// Add a document to the index
var document = new { title = "Moneyball", director = "Bennett Miller", year = 2011};

const string id = "1";

var addDocument = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.PUT, $"/{indexName}/_doc/{id}", CancellationToken.None, PostData.Serializable(document));
Debug.Assert(addDocument.Success, addDocument.DebugInformation);

// Refresh the index
var refresh = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.POST, $"/{indexName}/_refresh", CancellationToken.None);
Debug.Assert(refresh.Success, refresh.DebugInformation);

// Search for a document
const string q = "miller";

var query = new
{
size = 5,
query = new { multi_match = new { query = q, fields = new[] { "title^2", "director" } } }
};

var search = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.POST, $"/{indexName}/_search", CancellationToken.None, PostData.Serializable(query));
Debug.Assert(search.Success, search.DebugInformation);

foreach (var hit in search.Body.hits.hits) Console.WriteLine(hit["_source"]["title"]);

// Delete the document
var deleteDocument = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.DELETE, $"/{indexName}/_doc/{id}", CancellationToken.None);
Debug.Assert(deleteDocument.Success, deleteDocument.DebugInformation);

// Delete the index
var deleteIndex = await client.LowLevel.DoRequestAsync<DynamicResponse>(HttpMethod.DELETE, $"/{indexName}", CancellationToken.None);
Debug.Assert(deleteIndex.Success && (bool)deleteIndex.Body.acknowledged, deleteIndex.DebugInformation);
}
}
15 changes: 15 additions & 0 deletions samples/Samples/Samples.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>False</IsPackable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="$(SolutionRoot)\src\OpenSearch.Client\OpenSearch.Client.csproj" />
</ItemGroup>

</Project>

0 comments on commit 1924be9

Please sign in to comment.