A React Native native module providing a custom HTTP client with controllable redirect behaviour, cookie management, and request cancellation. It wraps Alamofire on iOS and Ktor on Android.
The standard fetch API and most React Native networking solutions automatically follow HTTP redirects without giving the caller any control. This library exposes a followRedirects flag so you can stop redirect chains mid-flight — useful when a redirect destination carries security-relevant information (e.g. authorization codes appended to a redirect URL) that must be inspected before the client proceeds.
npm install @pagopa/io-react-native-http-client
# or
yarn add @pagopa/io-react-native-http-clientSends an HTTP request and returns a Promise<HttpClientResponse>.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
url |
string |
✅ | — | Full URL of the request |
verb |
'get' | 'post' |
✅ | — | HTTP method |
headers |
Record<string, string> |
— | {} |
Request headers |
body |
Record<string, string> |
— | — | Form-encoded body (POST only) |
followRedirects |
boolean |
— | true |
Whether to follow HTTP redirects |
timeoutMilliseconds |
number |
— | 60000 |
Request timeout in milliseconds |
requestId |
string |
— | random UUID | Identifier used to cancel the request later |
All outcomes — including network errors — resolve (never reject) the promise with an HttpClientResponse:
Success — HTTP status code < 400:
{
type: 'success';
status: number;
body: string;
headers: Record<string, string | undefined>;
}Failure — HTTP status code ≥ 400, or a non-HTTP error:
{
type: 'failure';
code: number; // HTTP status code, or 900 for non-HTTP errors
message: string;
headers: Record<string, string | undefined>;
}Response headers are always normalised to lowercase keys.
When a network-level failure occurs (not an HTTP error response), the code field is set to 900 (NonHttpErrorCode) and the message field identifies the cause:
message |
Cause |
|---|---|
'Timeout' |
Request exceeded timeoutMilliseconds |
'Cancelled' |
Request was cancelled via cancelRequestWithId / cancelAllRunningRequests |
'TLS Failure' |
SSL/TLS handshake error |
'Serialization Failure' |
Response body could not be decoded as UTF-8 |
Injects a cookie into the native HTTP client's cookie storage for the given domain.
setCookie('https://example.com', '/', 'session', 'abc123');Removes all cookies stored for the given domain.
removeAllCookiesForDomain('https://example.com');Cancels the in-flight request with the given requestId. The corresponding promise resolves with a failure response (code: 900, message: 'Cancelled').
cancelRequestWithId('my-request-id');Cancels all currently running requests.
cancelAllRunningRequests();Cancels all running requests and releases native resources (HTTP client instances, cookie storage). Call this when the component or screen that owns the client is unmounted.
deallocate();import {
isSuccessResponse,
isFailureResponse,
isCancelledFailure,
isTimeoutFailure,
isTLSFailure,
isSerializationFailure,
NonHttpErrorCode,
} from '@pagopa/io-react-native-http-client';| Helper | Description |
|---|---|
isSuccessResponse(r) |
true when r.type === 'success' |
isFailureResponse(r) |
true when r.type === 'failure' |
isCancelledFailure(r) |
true when the request was cancelled |
isTimeoutFailure(r) |
true when the request timed out |
isTLSFailure(r) |
true on a TLS/SSL error |
isSerializationFailure(r) |
true when the body could not be deserialized |
import {
nativeRequest,
cancelRequestWithId,
isSuccessResponse,
isTimeoutFailure,
isCancelledFailure,
} from '@pagopa/io-react-native-http-client';
// Simple GET
const response = await nativeRequest({
verb: 'get',
url: 'https://api.example.com/data',
headers: { Authorization: 'Bearer token' },
timeoutMilliseconds: 10_000,
requestId: 'fetch-data',
});
if (isSuccessResponse(response)) {
console.log(response.status, response.body);
} else if (isTimeoutFailure(response)) {
console.warn('Request timed out');
} else if (isCancelledFailure(response)) {
console.warn('Request was cancelled');
} else {
console.error('HTTP error', response.code, response.message);
}
// POST with form-encoded body
const loginResponse = await nativeRequest({
verb: 'post',
url: 'https://auth.example.com/login',
body: { username: 'user', password: 'secret' },
followRedirects: false, // inspect redirect URL manually
requestId: 'login',
});
// Cancel a specific request
cancelRequestWithId('fetch-data');See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
Made with create-react-native-library