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 errors — ClientError 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();