Skip to content

Conversation

margaretjgu
Copy link
Member

@margaretjgu margaretjgu commented Oct 3, 2025

Next steps:

  • Publish unstable release of @elastic/transport with middleware exports
  • Test in elasticsearch-js to validate client integration

Example client usage:

import { Client } from '@elastic/elasticsearch'
import { MiddlewareEngine, CompressionMiddleware } from '@elastic/transport/middleware'

// Custom middleware for Kibana
class KibanaMiddleware implements Middleware {
  readonly name = 'kibana'
  readonly priority = 15

  onBeforeRequest = async (ctx) => {
    return {
      context: {
        request: {
          headers: {
            ...ctx.request.headers,
            'x-elastic-product-origin': 'kibana'
          }
        }
      }
    }
  }
}

const client = new Client({
  node: 'https://localhost:9200',
  middleware: [
    new CompressionMiddleware({ enabled: true }),
    new KibanaMiddleware()
  ]
})

@margaretjgu margaretjgu requested a review from JoshMock as a code owner October 3, 2025 14:01
"./lib/pool/WeightedConnectionPool": "./lib/pool/WeightedConnectionPool.js"
"./lib/pool/WeightedConnectionPool": "./lib/pool/WeightedConnectionPool.js",
"./middleware": "./lib/middleware/index.js",
"./lib/middleware": "./lib/middleware/index.js"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oof, reminder that I want to refactor both libraries to properly support ESM. this pattern was a naive attempt to move that direction, but I'm almost certain there was a simpler way. 🙃

Comment on lines +30 to +33
onBeforeRequest = async (ctx: MiddlewareContext): Promise<MiddlewareResult | undefined> => {
if (!this.shouldCompress(ctx)) {
return undefined // void = no changes needed
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
onBeforeRequest = async (ctx: MiddlewareContext): Promise<MiddlewareResult | undefined> => {
if (!this.shouldCompress(ctx)) {
return undefined // void = no changes needed
}
onBeforeRequest = async (ctx: MiddlewareContext): Promise<MiddlewareResult | void> => {
if (!this.shouldCompress(ctx)) {
return // void = no changes needed
}

void is a little clearer than undefined, IMO.

Comment on lines +77 to +97
return {
...current,

// Merge request object if provided
request: updates.request != null
? {
...current.request,
...updates.request,
headers: updates.request.headers != null
? {
...current.request.headers,
...updates.request.headers
}
: current.request.headers
}
: current.request,

// Replace shared map if provided (maps are immutable)
shared: updates.shared ?? current.shared
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bit we were worried would be a perf issue: deep-merging objects on a very hot code path could lead to a lot more garbage collection, which is a CPU hog.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tried sth out here with benchmarked comparison b/w original code - original deep merge - optimized deep merge

#307

@margaretjgu margaretjgu changed the base branch from main to 9.3.0-unstable.20251003 October 7, 2025 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants