# Send Query (/sdks/nodejs/tutorials/query-send)



## Overview [#overview]

This tutorial builds the RPC half of KubeMQ's request/reply patterns: a **query**, where the caller awaits a handler's data payload instead of just a completion status. Reach for it whenever a caller needs an answer — fetching a record, running a lookup, or asking another service to compute a value on demand. You'll send a query against a separately running handler to see the full round trip.

`createQuery()` builds an immutable query message with a `channel`, `body`, and `timeoutInSeconds`; `await client.sendQuery()` blocks until a handler replies or the timeout elapses. The response carries `executed: true`, a `body` payload, and optionally `error` — KubeMQ correlates the reply to this call automatically, so the caller never tracks request IDs itself.

**Gotchas:** the timeout must cover however long the handler takes to run — a slow handler leaves `executed: false` even though the handler eventually succeeds. No handler subscribed yet also times out rather than erroring immediately, so startup order matters. `response.body` is a raw `Uint8Array` — decoding it is your application's job.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* Node.js SDK installed (`npm install kubemq-js`)

## Code [#code]

```typescript title="send-query.ts"
/**
 * Example: Send Query and Receive Data Response
 *
 * Demonstrates sending a query (request/reply with data response).
 * Queries are used when you need to retrieve data from a responder.
 *
 * Prerequisites:
 *   - KubeMQ server running on localhost:50000
 *   - A query handler running (see handle-query.ts)
 *
 * Run: npx tsx examples/rpc/send-query.ts
 */
import { KubeMQClient, createQuery } from 'kubemq-js';

async function main(): Promise<void> {
  const client = await KubeMQClient.create({
    address: 'localhost:50000',
    clientId: 'js-rpc-send-query-client',
  });

  try {
    const response = await client.sendQuery(
      createQuery({
        channel: 'js-rpc.send-query',
        body: JSON.stringify({ sku: 'WIDGET-42', warehouse: 'east' }),
        timeoutInSeconds: 10,
      }),
    );

    if (response.executed && response.body) {
      const data = JSON.parse(new TextDecoder().decode(response.body));
      console.log('Inventory response:', data);
    } else {
      console.error('Query failed:', response.error);
    }
  } finally {
    await client.close();
  }
}

main().catch(console.error);

// Expected output:
// Inventory response: { sku: 'WIDGET-42', inStock: 150, price: 12.99, warehouse: 'east' }

```

## How It Works [#how-it-works]

* `createQuery()` builds an immutable query message with `timeoutInSeconds: 10`; unlike commands, queries expect a data payload in the response.
* `await client.sendQuery()` blocks until a handler replies or the timeout elapses; the response carries `executed: true`, `body` (the response payload), and optionally `error`.
* `response.body` is a `Uint8Array` — `new TextDecoder().decode(response.body)` and `JSON.parse()` extract the structured data returned by the handler.
* Use `handle-query.ts` to run the responder side; the two examples together demonstrate the full synchronous request/reply cycle.

## Related [#related]

* [Pattern overview](/learn/rpc/getting-started)
* [Node.js SDK Reference](/sdks/nodejs/reference)
* [Handle Query](/sdks/nodejs/how-to/rpc/query-handle)
* [Query Group](/sdks/nodejs/how-to/rpc/query-group)
