JavaScript Client
When quarkus.json-rpc.js-client.enabled is set to true, the extension generates a JavaScript client library and a typed proxy module as web resources. These can be imported directly from frameworks like Quarkus Web Bundler or Web Dependency Locator via the standard import map convention.
Enabling the Client
Add to application.properties:
quarkus.json-rpc.js-client.enabled=true
This generates two resources at build time and registers import mappings so that frameworks like Web Bundler and Web Dependency Locator can resolve bare import specifiers automatically:
| Resource | Import specifier | Purpose |
|---|---|---|
|
|
Reusable WebSocket client library |
|
|
Typed proxy with exports for each |
Using the Typed Proxy
The generated proxy is the easiest way to call your JSON-RPC methods. It exports one object per @JsonRPCApi scope, plus the underlying client instance:
import { client, GreetingService } from '@quarkiverse/json-rpc-api';
// Simple call
const greeting = await GreetingService.hello({ name: 'World' });
console.log(greeting); // "Hello World"
// With multiple parameters
const full = await GreetingService.greet({ name: 'Jane', surname: 'Doe' });
Each method on the proxy accepts a params object (named parameters) or an array (positional parameters), matching the server-side Java method signature.
Void Methods (Fire-and-Forget)
Methods returning void on the server are exposed as fire-and-forget notifications. The proxy uses client.notify() instead of client.call(), so no response is sent back:
import { EventService } from '@quarkiverse/json-rpc-api';
// Fire-and-forget — no response, no Promise
EventService.trackEvent({ name: 'page_view' });
EventService.ping();
Under the hood, the proxy sends a JSON-RPC notification (a request without an id field). The server executes the method but sends no response.
Streaming Methods
Methods that return Multi<T> or Flow.Publisher<T> on the server are automatically exposed as subscriptions:
import { TickerService } from '@quarkiverse/json-rpc-api';
const sub = TickerService.ticker()
.onItem(item => console.log('Received:', item))
.onError(err => console.error('Error:', err))
.onComplete(() => console.log('Stream completed'));
// Cancel the subscription later
await sub.cancel();
Custom Path APIs
When @JsonRPCApi(path = "…") is used, the generated proxy creates a separate JsonRPCClient for each unique custom path. Scopes without a custom path use the default client:
@JsonRPCApi(path = "/admin-rpc")
public class AdminService { ... }
@JsonRPCApi
public class PublicService { ... }
import { client, AdminService, PublicService } from '@quarkiverse/json-rpc-api';
// PublicService calls go through the default client at /json-rpc
const info = await PublicService.getInfo();
// AdminService calls go through a separate client at /admin-rpc
const status = await AdminService.getStatus();
Each custom-path client is created internally and used automatically by the proxy. If you need to configure authentication or connection settings for a custom-path client, use JsonRPCClient.configure() to set global defaults that apply to all client instances:
import { JsonRPCClient } from '@quarkiverse/json-rpc';
// Applies to all clients (default and custom-path)
JsonRPCClient.configure({ token: 'Bearer my-jwt-token' });
Configuring the Connection
The typed proxy exports the client instance so you can reconfigure the WebSocket URL at runtime — for example, when behind a reverse proxy or gateway:
import { client, GreetingService } from '@quarkiverse/json-rpc-api';
// Override the full URL
client.url = 'wss://gateway.example.com/json-rpc';
// Or just change the path
client.path = '/api/json-rpc';
// Calls now go through the new URL
const result = await GreetingService.hello({ name: 'World' });
Using the Client Library Directly
If you prefer more control, import the JsonRPCClient class directly:
import { JsonRPCClient } from '@quarkiverse/json-rpc';
const client = new JsonRPCClient({
path: '/json-rpc', // WebSocket path (default)
autoReconnect: true, // Reconnect on disconnect (default)
maxReconnectDelay: 30000 // Max backoff in ms (default)
});
Making Calls
// Named parameters
const result = await client.call('GreetingService#hello', { name: 'World' });
// Positional parameters
const result2 = await client.call('GreetingService#hello', ['World']);
// No parameters
const result3 = await client.call('GreetingService#hello');
Notifications (Fire-and-Forget)
// Fire-and-forget — no response expected
client.notify('EventService#trackEvent', { name: 'page_view' });
// With positional parameters
client.notify('EventService#trackEvent', ['page_view']);
// No parameters
client.notify('EventService#ping');
notify() sends a JSON-RPC notification (no id field). The server executes the method but sends no response. Throws if the WebSocket is not connected.
Subscriptions
const sub = client.subscribe('TickerService#ticker');
sub.onItem(item => console.log(item));
sub.onComplete(() => console.log('done'));
sub.onError(err => console.error(err));
// Cancel
await sub.cancel();
Server Push Notifications
Listen for notifications sent by JsonRPCBroadcaster:
// Register a listener
const off = client.on('update', data => {
console.log('Server push:', data);
});
// Remove the listener later
off();
Connection Lifecycle
const client = new JsonRPCClient({
autoConnect: false, // Don't connect immediately
onOpen: () => console.log('Connected'),
onClose: () => console.log('Disconnected'),
onError: (err) => console.error('Error:', err)
});
// Connect manually
client.connect();
// Check connection state
console.log(client.connected); // true or false
// Disconnect (a subsequent connect() restores auto-reconnect)
client.disconnect();
Authentication
See the Security guide — Browser Authentication for full details on authenticating from the browser.
Constructor Options
| Option | Type | Default | Description |
|---|---|---|---|
|
|
|
WebSocket endpoint path |
|
|
derived from `location` |
Full WebSocket URL (overrides |
|
|
|
Connect immediately on construction |
|
|
|
Reconnect automatically when the connection drops |
|
|
|
Maximum reconnect backoff delay in milliseconds |
|
|
Auth token sent via |
|
|
|
Callback returning a token string (sync or async). Called on each |
|
|
|
Called when the connection opens |
|
|
|
Called when the connection closes |
|
|
|
Called on connection errors |