Skip to content

pagopa/io-react-native-http-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

@pagopa/io-react-native-http-client

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.

Motivation

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.

Installation

npm install @pagopa/io-react-native-http-client
# or
yarn add @pagopa/io-react-native-http-client

API

nativeRequest(config)

Sends an HTTP request and returns a Promise<HttpClientResponse>.

Config

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

Response

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.

Non-HTTP error codes

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

setCookie(domain, path, name, value)

Injects a cookie into the native HTTP client's cookie storage for the given domain.

setCookie('https://example.com', '/', 'session', 'abc123');

removeAllCookiesForDomain(domain)

Removes all cookies stored for the given domain.

removeAllCookiesForDomain('https://example.com');

cancelRequestWithId(requestId)

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');

cancelAllRunningRequests()

Cancels all currently running requests.

cancelAllRunningRequests();

deallocate()

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();

Type guards and helpers

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

Usage example

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');

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT


Made with create-react-native-library

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors