Skip to content

Commit

Permalink
Corrected content type for bulk operations (#275)
Browse files Browse the repository at this point in the history
* Corrected content type for bulk operations

Signed-off-by: Theo Truong <theotr@amazon.com>

* # linting

Signed-off-by: Theo Truong <theotr@amazon.com>

---------

Signed-off-by: Theo Truong <theotr@amazon.com>
  • Loading branch information
nhtruong authored Apr 30, 2024
1 parent eb271e6 commit 3c9f025
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 24 deletions.
4 changes: 3 additions & 1 deletion CLIENT_GENERATOR_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ def search(self, index=None, body=None):
You will also encounter `x-overloaded-param: metric` for the `node_id` path parameter of the `GET /_nodes/{node_id}` operation in `nodes.info` action. This is a special case where the path parameter is overloaded to accept either a node ID or a metric name. When the user evokes the `client.nodes.info` method with either `metric` or `node_id` (but not both), the method will use the `GET /_nodes/{node_id}` operation. When evoked with both `metric` and `node_id`, it will use the `GET /_nodes/{node_id}/{metric}` operation.

## Handling Bulk Operations
Some operations accept a bulk of data in the request body. For example, the `bulk` action accepts a bulk of index, update, and delete operations on multiple documents. Unlike other operations where the request body is a **JSON object**, the request body for bulk operations is an **NDJSON** (i.e a [Newline-delimited JSON](https://github.com/ndjson/ndjson-spec)). When encountering this type of operation, the client must serialize the request body accordingly, and set the `Content-Type` header to `application/x-ndjson`.
Some operations accept a bulk of data in the request body. For example, the `bulk` action accepts a bulk of index, update, and delete operations on multiple documents. Unlike other operations where the request body is a **JSON object**, the request body for bulk operations is an **NDJSON** (i.e a [Newline-delimited JSON](https://github.com/ndjson/ndjson-spec)).

In the spec, these request bodies have the `content` of `application/x-ndjson` and their schemas are of type array. In this situation, the client must serialize the request body accordingly, and set the `Content-Type` header to `application/x-ndjson`.

## Parameter Validation
As of right now, most clients only validate whether required parameters are present. The clients do not validate the values of parameters against the enum values or regex patterns. This is to reduce performance overhead for the clients as the validation is already done on the server. However, the list of enum values and regex patterns are often written into the parameter description.
Expand Down
9 changes: 3 additions & 6 deletions spec/namespaces/_core.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2110,7 +2110,7 @@ components:
requestBodies:
bulk:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
Expand All @@ -2119,7 +2119,6 @@ components:
- $ref: '../schemas/_core.bulk.yaml#/components/schemas/UpdateAction'
- type: object
description: The operation definition and data (action-data pairs), separated by newlines
x-serialize: bulk
required: true
clear_scroll:
content:
Expand Down Expand Up @@ -2220,23 +2219,21 @@ components:
required: true
msearch:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/_core.msearch.yaml#/components/schemas/RequestItem'
description: The request definitions (metadata-search request definition pairs), separated by newlines
x-serialize: bulk
required: true
msearch_template:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/_core.msearch_template.yaml#/components/schemas/RequestItem'
description: The request definitions (metadata-search request definition pairs), separated by newlines
x-serialize: bulk
required: true
mtermvectors:
content:
Expand Down
2 changes: 1 addition & 1 deletion spec/namespaces/search_pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ components:
in: query
description: Operation timeout.
schema:
$ref: '../schemas/_common.yaml#/components/schemas/Duration'
$ref: '../schemas/_common.yaml#/components/schemas/Duration'
26 changes: 13 additions & 13 deletions spec/namespaces/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -637,103 +637,103 @@ components:
required: true
security.patch_action_group:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_action_groups:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_audit_configuration:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_configuration:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_distinguished_names:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_role:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_role_mapping:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_role_mappings:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_roles:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_tenant:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_tenants:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_user:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
$ref: '../schemas/security._common.yaml#/components/schemas/PatchOperation'
required: true
security.patch_users:
content:
application/json:
application/x-ndjson:
schema:
type: array
items:
Expand Down
17 changes: 16 additions & 1 deletion tools/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import fs from 'fs'
import YAML from 'yaml'
import _ from 'lodash'

export function resolve (ref: string, root: Record<string, any>) {
export function resolveRef (ref: string, root: Record<string, any>): Record<string, any> | undefined {
const paths = ref.replace('#/', '').split('/')
for (const p of paths) {
root = root[p]
Expand All @@ -11,6 +11,21 @@ export function resolve (ref: string, root: Record<string, any>) {
return root
}

export function resolveObj (obj: Record<string, any> | undefined, root: Record<string, any>) {

Check warning on line 14 in tools/helpers.ts

View workflow job for this annotation

GitHub Actions / tools-tests

Missing return type on function
if (obj === undefined) return undefined
if (obj.$ref) return resolveRef(obj.$ref, root)

Check warning on line 16 in tools/helpers.ts

View workflow job for this annotation

GitHub Actions / tools-tests

Unexpected any value in conditional. An explicit comparison or type cast is required

Check warning on line 16 in tools/helpers.ts

View workflow job for this annotation

GitHub Actions / tools-tests

Unsafe argument of type `any` assigned to a parameter of type `string`
return obj
}

export function dig (obj: Record<string, any>, path: string[], root: Record<string, any>): any {
let value = obj
for (const p of path) {
value = resolveObj(value, root)?.[p]
if (value === undefined) break
}
return value
}

export function sortByKey (obj: Record<string, any>, priorities: string[] = []) {

Check warning on line 29 in tools/helpers.ts

View workflow job for this annotation

GitHub Actions / tools-tests

Missing return type on function
const orders = _.fromPairs(priorities.map((k, i) => [k, i + 1]))
const sorted = _.entries(obj).sort((a, b) => {
Expand Down
4 changes: 2 additions & 2 deletions tools/linter/components/NamespaceFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type OperationSpec, type ValidationError } from '../../types'
import OperationGroup from './OperationGroup'
import _ from 'lodash'
import Operation from './Operation'
import { resolve } from '../../helpers'
import { resolveRef } from '../../helpers'
import FileValidator from './base/FileValidator'

const HTTP_METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace']
Expand Down Expand Up @@ -68,7 +68,7 @@ export default class NamespaceFile extends FileValidator {

validate_unresolved_refs (): ValidationError[] {
return Array.from(this.refs()).map((ref) => {
if (resolve(ref, this.spec()) === undefined) return this.error(`Unresolved reference: ${ref}`, ref)
if (resolveRef(ref, this.spec()) === undefined) return this.error(`Unresolved reference: ${ref}`, ref)
}).filter((e) => e) as ValidationError[]
}

Expand Down

0 comments on commit 3c9f025

Please sign in to comment.