diff --git a/UPGRADING.md b/UPGRADING.md index 03c2c2dff..ef0e6c0d3 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,23 +1,23 @@ * [Upgrading The Opensearch JavaScript Client](#upgrading-the-opensearch-javascript-client) * [Upgrading from 2.x to 3.x](#upgrading-from-2x-to-3x) - * [Breaking Changes](#breaking-changes) - * [Removed camelCase params:](#removed-camelcase-params-) - * [Removed overridden HTTP methods:](#removed-overridden-http-methods-) - * [Changes in Request and Response types:](#changes-in-request-and-response-types-) + * [Removed camelCase params:](#removed-camelcase-params-) + * [Removed overridden HTTP methods:](#removed-overridden-http-methods-) + * [Typescript - New request and response types:](#typescript---new-request-and-response-types-) + * [Typescript - Stricter type definitions:](#typescript---stricter-type-definitions) * [Deprecations](#deprecations) # Upgrading The Opensearch JavaScript Client ## Upgrading from 2.x to 3.x Starting from 3.x, the API functions and modules in opensearch-js are generated from the [OpenSearch REST API specification](https://github.com/opensearch-project/opensearch-api-specification/). While the vast majority of the API remains the same, there are some breaking changes that may require updating your application when upgrading from 2.x to 3.x. -### Breaking Changes -#### Removed camelCase params: -Every API function now only accepts parameters matching the OpenSearch API Spec, which are also what the OpenSearch server expects. In previous versions, some API functions would convert camelCase parameters to snake_case before sending them to the server. This is no longer the case. For example, the client now only accepts `filter_path` as a parameter, and passing `filterPath` will result in an error from the server. +Here are some of the breaking changes you should be aware of when upgrading from 2.x to 3.x: +### Removed camelCase params: +Every API function now only accepts parameters matching the OpenSearch API Spec, which are also what the OpenSearch server expects. In previous versions, some API functions would convert camelCase parameters to snake_case before sending them to the server. This is no longer the case. For example, the client now only accepts `filter_path` as a parameter, and passing `filterPath` will result in an error from the server. -#### Removed overridden HTTP methods: +### Removed overridden HTTP methods: The 3.x client no longer allows overriding the HTTP method for API functions. In previous versions, some API functions let you pass `method` as a parameter to the API functions to override the default HTTP method. Now, `method` will be considered a querystring param, and using it will likely result in an error. If you need to send a custom request, you should use the `client.http` namespace. In 2.x: @@ -33,7 +33,7 @@ client.http.get({ path: '/_search', body: { query: { match: { director: 'miller' ``` -#### Changes in Request and Response types: +### Typescript - New request and response types: The biggest improvement in 3.x is the addition of all the request and response types for each API function. This means that you can now see the exact shape of the request and response objects for each API function. This is especially useful for TypeScript users, as it provides a better developer experience. However, previously handwritten request and response types have been replaced by those generated from the spec, so you may need to update your code to match the new types: In 2.x: @@ -57,6 +57,42 @@ const searchResponse = (await client.search(searchBody)).body; // Note that the response type is now inferred, and you don't need to cast with `as API.Search_ResponseBody` ``` +### Typescript - Stricter type definitions: +In the same vein as the previous point, the typescript definitions are now stricter and more accurate. This means that you may need to update your code to match the new types. For example, the `client.search` function now only accepts a `API.Search_Request` object, and passing an object with a different shape will result in a type error. And since the response object is now inferred to match the proper response type, accessing undefined properties will also result in a type error. + +Since the types are generated from the OpenSearch API spec, they are guaranteed to be accurate and up-to-date, and this rarely results in any breaking changes. However, there are cases where the generated type is a union of multiple types, and you may need to use type guards to access the correct properties. + +For example, the response body for the `client.deleteByQuery()` function is defined as a union of two types: `Common.BulkByScrollResponseBase` and `{ task?: Common.TaskId; }`. + +```ts +export type DeleteByQuery_ResponseBody = Common.BulkByScrollResponseBase | { + task?: Common.TaskId; +} + +export type BulkByScrollResponseBase = BulkByScrollTaskStatus & { + failures: BulkByScrollFailure[]; + timed_out: boolean; + took: number; +} +``` +This means that the following code will result in a type error: +```ts +const body = await client.deleteByQuery({ body: { query: { match: { director: 'miller' } } } }).body; +console.log(body.failures); // Type error: Property 'failures' does not exist on type { task?: TaskId; }'. +``` +because TypeScript cannot infer the correct type of `body` from the union type. To fix this, you can use a type guard to check the type of `body` before accessing the properties: +```ts +const body = await client.deleteByQuery({ body: { query: { match: { director: 'miller' } } } }).body; + +if ('failures' in body) { + console.log(body.failures); + console.log(body.took); + console.log(body.timed_out); +} else { + console.log(body.task); +} +``` + ### Deprecations - **snake_case API modules and functions**: In 3.x, all API modules and functions are now in camelCase, comforming to the naming convention of Javascript. The snake_case aliases are still available but are deprecated and will be removed in a future version. \ No newline at end of file diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 16569dd34..c6594ea9c 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -1,22 +1,27 @@ -# User Guide + +* [User Guide](#user-guide) + * [Initializing a Client](#initializing-a-client) + * [Authenticate with Amazon OpenSearch Service](#authenticate-with-amazon-opensearch-service) + * [Using AWS V2 SDK](#using-aws-v2-sdk) + * [Using AWS V3 SDK](#using-aws-v3-sdk) + * [Special topics](#special-topics) + * [TypeScript: Handling Request and Response Types](#typescript-handling-request-and-response-types) + * [Enable Handling of Long Numerals](#enable-handling-of-long-numerals) + * [Examples](#examples) + * [Create an Index](#create-an-index) + * [Add a Document to the Index](#add-a-document-to-the-index) + * [Search for the Document](#search-for-the-document) + * [Multi-Search (msearch)](#multi-search-msearch) + * [Delete the document](#delete-the-document) + * [Delete the index](#delete-the-index) + * [Create a Point in Time](#create-a-point-in-time) + * [Get all PITs](#get-all-pits) + * [Delete a Point in Time](#delete-a-point-in-time) + * [Delete all PITs](#delete-all-pits) + * [Empty all Pool Connections](#empty-all-pool-connections) + -- [User Guide](#user-guide) - - [Initializing a Client](#initializing-a-client) - - [Authenticate with Amazon OpenSearch Service](#authenticate-with-amazon-opensearch-service) - - [Using AWS V2 SDK](#using-aws-v2-sdk) - - [Using AWS V3 SDK](#using-aws-v3-sdk) - - [Enable Handling of Long Numerals](#enable-handling-of-long-numerals) - - [Create an Index](#create-an-index) - - [Add a Document to the Index](#add-a-document-to-the-index) - - [Search for the Document](#search-for-the-document) - - [Multi-Search (msearch)](#multi-search-msearch) - - [Delete the document](#delete-the-document) - - [Delete the index](#delete-the-index) - - [Create a Point in Time](#create-a-point-in-time) - - [Get all PITs](#get-all-pits) - - [Delete a Point in Time](#delete-a-point-in-time) - - [Delete all PITs](#delete-all-pits) - - [Empty all Pool Connections](#empty-all-pool-connections) +# User Guide ## Initializing a Client @@ -120,6 +125,31 @@ const client = new Client({ // node: "https://xxx.region.aoss.amazonaws.com" for OpenSearch Serverless }); ``` +## Special topics + +### TypeScript: Handling Request and Response Types +All API functions in the client, along with their request and response types, are generated from the OpenSearch REST API specification. This provides a better developer experience, especially for TypeScript users. Here's how you can use the generated types: + +```typescript +import { Client, type API } from '@opensearch-project/opensearch'; + +const client = new Client({ node: 'http://localhost:9200' }); + +const searchRequest: API.Search_Request = { body: { query: { match: { director: 'miller' } } } }; // is type checked against API.Search_Request +const searchResponse = (await client.search(searchRequest)).body; // is inferred as API.Search_ResponseBody +``` + +Note that even though there are types generated for the components of the request and response, only the top-level request and response types are exported. This is intentional! You should NOT access those component types directly, as it can result in breaking changes when the API spec changes. Instead, access the component types through the top-level request and response types: + +```typescript +// Do NOT do this! +import { type IndexSettings } from '@opensearch-project/opensearch/api/_types/indices._common'; +const settings: IndexSettings = { number_of_shards: 1, number_of_replicas: 0 }; + +// Do this instead! +import { type API } from '@opensearch-project/opensearch'; +const settings: API.Indices_Create_RequestBody['settings'] = { number_of_shards: 1, number_of_replicas: 0 }; +``` ### Enable Handling of Long Numerals @@ -135,8 +165,11 @@ const client = new Client({ enableLongNumeralSupport: true, }); ``` +## Examples + +(for more examples, see the [guides](guides) directory) -## Create an Index +### Create an Index ```javascript console.log('Creating index:'); @@ -159,7 +192,7 @@ var response = await client.indices.create({ console.log(response.body); ``` -## Add a Document to the Index +### Add a Document to the Index ```javascript console.log('Adding document:'); @@ -183,7 +216,7 @@ var response = await client.index({ console.log(response.body); ``` -## Search for the Document +### Search for the Document ```javascript console.log('Search results:'); @@ -206,7 +239,7 @@ var response = await client.search({ console.log(response.body.hits); ``` -## Multi-Search (msearch) +### Multi-Search (msearch) ```javascript const queries = [ @@ -230,7 +263,7 @@ const queries = [ Explore `msearch` further with a detailed guide in [msearch.md](guides/msearch.md) and find sample code in [msearch.js](samples/msearch.js). -## Delete the document +### Delete the document ```javascript console.log('Deleting document:'); @@ -243,7 +276,7 @@ var response = await client.delete({ console.log(response.body); ``` -## Delete the index +### Delete the index ```javascript console.log('Deleting index:'); @@ -255,7 +288,7 @@ var response = await client.indices.delete({ console.log(response.body); ``` -## Create a Point in Time +### Create a Point in Time ```javascript console.log('Creating a PIT:'); @@ -269,7 +302,7 @@ var response = await client.createPit({ console.log(response.body); ``` -## Get all PITs +### Get all PITs ```javascript console.log('Getting all PITs:'); @@ -279,7 +312,7 @@ var response = await client.getAllPits(); console.log(response.body); ``` -## Delete a Point in Time +### Delete a Point in Time ```javascript console.log('Deleting a PIT:'); @@ -295,7 +328,7 @@ var response = await client.deletePit({ console.log(response.body); ``` -## Delete all PITs +### Delete all PITs ```javascript console.log('Deleting all PITs:'); @@ -305,7 +338,7 @@ var response = await client.deleteAllPits(); console.log(response.body); ``` -## Empty all Pool Connections +### Empty all Pool Connections ```javascript var pool = new ConnectionPool({ Connection }); diff --git a/package.json b/package.json index 482320192..0d0fd0489 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "LICENSE.txt" ], "homepage": "https://www.opensearch.org/", - "version": "3.0.0-beta.9", + "version": "3.0.0", "versionCanary": "7.10.0-canary.6", "keywords": [ "opensearch",