Skip to main content

Client

OPRA provides a typed HTTP client layer that sits between your frontend code and an OPRA-powered API. It handles request building, body serialization, response parsing, interceptor chaining, and error normalization — so your application code only deals with typed inputs and outputs.

All client methods return an HttpRequestObservable, which supports both Promise and Observable usage. You can await a single response or pipe it through RxJS operators — whichever fits your stack.


Packages

PackageUse when
@opra/clientReact, Vue, Node.js, or any non-Angular environment
@opra/angularAngular applications — uses Angular's HttpClient as the transport

Both packages share the same API surface. The difference is the backend: @opra/client uses the browser/Node fetch API by default, while @opra/angular delegates to Angular's HttpClient so that Angular's interceptors, HttpContext, and DI system remain fully active.


Key capabilities

Type-safe requests — Generic type parameters flow from the method call through to the resolved value. No manual casting.

const order = await client.get<Order>('orders/123').getBody();
// order is typed as Order

Promise and Observable in one — Every request is an Observable you can subscribe to, or a Promise you can await. No need to choose upfront.

// Promise
const orders = await client.get<Order[]>('orders').getBody();

// Observable — combine, cancel, pipe
userId$.pipe(switchMap(id => client.get<User>(`users/${id}`))).subscribe(...);

Pluggable backend — The transport layer is swappable. FetchBackend ships by default; AngularBackend integrates with Angular's HTTP stack; you can build your own for testing or custom environments.

Interceptors — Add auth tokens, retry logic, logging, or correlation IDs once and have them apply to every request automatically.

Structured errorsClientError exposes the HTTP status and the structured issues array from the OPRA response body, so error handling is consistent across the application.


Quick example

import { OpraHttpClient } from '@opra/client';

const client = new OpraHttpClient('https://api.example.com');

const order = await client.get<Order>('orders/123').getBody();
const created = await client.post<Order>('orders', { item: 'book' }).getBody();