Middleware System

Vectra includes a Rack-style middleware stack that lets you extend the client without forking the gem or patching providers.

You can:


Core Concepts

Request / Response

Base i Stack


Enabling Middleware

Global Middleware

Primjenjuje se na sve Vectra::Client instance.

require "vectra"

# Global logging + retry + cost tracking
Vectra::Client.use Vectra::Middleware::Logging
Vectra::Client.use Vectra::Middleware::Retry, max_attempts: 5
Vectra::Client.use Vectra::Middleware::CostTracker

Sve sljedeće Vectra::Client.new(...) instance će koristiti ovaj globalni stack.

Per‑Client Middleware

Dodatni ili prilagođeni middleware samo za jedan klijent:

client = Vectra::Client.new(
  provider: :qdrant,
  index: "products",
  middleware: [
    Vectra::Middleware::PIIRedaction,
    Vectra::Middleware::Instrumentation
  ]
)

Koje operacije prolaze kroz stack?

Sve standardne operacije Vectra::Clienta koriste middleware stack:

To znači da middleware može:


Built‑in Middleware

Logging (Vectra::Middleware::Logging)

Što radi:

Konfiguracija:

# Globalno
Vectra::Client.use Vectra::Middleware::Logging

# S custom loggerom
logger = Logger.new($stdout)
Vectra::Client.use Vectra::Middleware::Logging, logger: logger

Tipična upotreba: debugiranje, audit logovi, korelacija s HTTP logovima.


Retry (Vectra::Middleware::Retry)

Što radi:

Konfiguracija:

# 3 pokušaja, exponential backoff (default)
Vectra::Client.use Vectra::Middleware::Retry

# 5 pokušaja, linearni backoff
Vectra::Client.use Vectra::Middleware::Retry,
  max_attempts: 5,
  backoff: :linear

# Fiksni delay 1.0s
Vectra::Client.use Vectra::Middleware::Retry,
  max_attempts: 3,
  backoff: 1.0

Tipična upotreba: zaštita od povremenih mrežnih problema i rate‑limit grešaka.


Instrumentation (Vectra::Middleware::Instrumentation)

Što radi:

Primjer:

Vectra::Client.use Vectra::Middleware::Instrumentation

Vectra.on_operation do |event|
  # event[:operation], event[:provider], event[:duration_ms], event[:success], ...
  StatsD.timing("vectra.#{event[:operation]}", event[:duration_ms])
end

Tipična upotreba: integracija s Prometheus/Grafana, Datadog, New Relic…


PII Redaction (Vectra::Middleware::PIIRedaction)

Što radi:

Primjer:

Vectra::Client.use Vectra::Middleware::PIIRedaction

client.upsert(
  index: "sensitive",
  vectors: [
    {
      id: "user-1",
      values: [0.1, 0.2, 0.3],
      metadata: {
        email: "user@example.com",
        phone: "555-1234",
        note:  "Contact at user@example.com"
      }
    }
  ]
)

Nakon upsert‑a, provider će vidjeti već redaktirani metadata.

Custom patterni:

patterns = {
  credit_card: /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/,
  api_key: /sk-[a-zA-Z0-9]{32}/
}

Vectra::Client.use Vectra::Middleware::PIIRedaction, patterns: patterns

Tipična upotreba: GDPR, SOC2, PCI‑DSS okruženja gdje je zabranjen PII u vektor bazi.


CostTracker (Vectra::Middleware::CostTracker)

Što radi:

Primjer:

Vectra::Client.use Vectra::Middleware::CostTracker,
  on_cost: ->(event) {
    puts "💰 Cost: $#{event[:cost_usd].round(6)} for #{event[:operation]} (#{event[:provider]})"
  }

Custom pricing:

pricing = {
  pinecone: { read: 0.0001, write: 0.0002 },
  qdrant:   { read: 0.00005, write: 0.0001 }
}

Vectra::Client.use Vectra::Middleware::CostTracker, pricing: pricing

Tipična upotreba: unutarnji billing, budget guardrails, cost dashboards.


Custom Middleware

Najjednostavniji način je naslijediti Vectra::Middleware::Base i override-ati hookove:

class MyAuditMiddleware < Vectra::Middleware::Base
  def before(request)
    AuditLog.create!(
      operation: request.operation,
      index:     request.index,
      namespace: request.namespace,
      provider:  request.provider
    )
  end

  def after(_request, response)
    puts "Duration: #{response.metadata[:duration_ms]}ms"
  end

  def on_error(request, error)
    ErrorTracker.notify(error, context: { operation: request.operation })
  end
end

Vectra::Client.use MyAuditMiddleware

Savjeti:


Primjer: examples/middleware_demo.rb

U repozitoriju imaš kompletan demo:

Pokretanje:

bundle exec ruby examples/middleware_demo.rb

Ovaj demo je dobar “živi” primjer kako kombinirati više middleware-a u praksi.