Balena HTTP Client
balena-request is a low-level HTTP client specifically designed for making requests to Balena servers. It is not intended for direct use by end-users, but rather as an internal dependency for other Balena-io modules, such as the balena SDK. The current stable version is 14.2.0, with frequent patch and minor releases, indicating active development. Key differentiators include its tight integration with the Balena ecosystem, requiring an instantiated `balena-auth` instance for authentication, and providing features like request interceptors, streaming capabilities, and automatic handling of authorization. It supports both Node.js (requiring `>=18.0.0`) and browser environments, though the `isBrowser` option has been deprecated in recent versions. The module exposes a factory function to create a request instance, enabling configurable behavior like debug logging and retries.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'auth')
cause The `auth` option was not provided or was `undefined` when initializing the `balenaRequest` factory function.fixEnsure an instantiated `balena-auth` instance is passed as the `auth` option: `balenaRequest({ auth: myAuthInstance, ... })`. -
Error: (0 , h.requestMetadata) is not a function
cause This error often occurs when `balena-request` or a related Balena module is incorrectly bundled or used in an environment where its internal dependencies or module resolution fails, frequently seen with tools like Etcher or custom bundlers.fixVerify your bundling configuration (e.g., Webpack, Rollup) for Balena modules, ensuring proper resolution and transpilation. For Balena Etcher specific issues, try running the application as an administrator or using an alternative flashing tool if the issue persists. -
TS2345: Argument of type '{ debug: boolean; isBrowser: boolean; }' is not assignable to parameter of type 'BalenaRequestOptions'. Property 'auth' is missing in type '{ debug: boolean; isBrowser: boolean; }' but required in type 'BalenaRequestOptions'.cause In TypeScript, the `auth` property is a required part of `BalenaRequestOptions` when initializing the client.fixProvide an `auth` instance of `balena-auth` in the options object: `balenaRequest({ auth: balenaAuthInstance, debug: false })`.
Warnings
- breaking This module is explicitly designed as a low-level client for internal Balena-io modules and is NOT meant for direct use by end-users. Using it directly may lead to unexpected behavior or require a deep understanding of Balena's internal HTTP client logic. The official `balena-sdk` should be used instead for most applications.
- deprecated The `isBrowser` option passed to the `balenaRequest` factory function was deprecated in v14.0.8. The module now generally handles environment detection automatically or relies on native Fetch API and `node-fetch` for streaming.
- breaking Internal uses of the deprecated `url.parse` and `url.resolve` Node.js API were replaced with the WHATWG URL API in v14.1.6. While this is an internal change, it could potentially affect applications that rely on specific parsing behaviors or error handling of the older `url` module if custom interceptors or deeply integrated logic are used.
- breaking The internal `fetch-ponyfill` dependency was dropped in favor of native `fetch` (in browsers) and `node-fetch` (in Node.js) for streaming downloads in v14.0.8. This change could subtly alter behavior or require new polyfills if the `fetch-ponyfill` was providing specific browser compatibility or older Node.js `fetch` polyfills.
Install
-
npm install balena-request -
yarn add balena-request -
pnpm add balena-request
Imports
- balenaRequest
import { balenaRequest } from 'balena-request';import balenaRequest from 'balena-request';
- Interceptor
import { Interceptor } from 'balena-request';import type { Interceptor } from 'balena-request'; - BalenaRequestError
import BalenaRequestError from 'balena-request';
import { BalenaRequestError } from 'balena-request';
Quickstart
import balenaRequest from 'balena-request';
import balenaAuth from 'balena-auth';
// Mock balenaAuth for demonstration purposes.
// In a real application, you would instantiate and configure balenaAuth.
const auth = balenaAuth.createInstance({
dataDirectory: process.env.BALENA_DATA_DIR ?? false, // Use false for in-memory in tests/examples
// apiKey: process.env.BALENA_API_KEY ?? '', // Or use an API key
});
async function makeRequest() {
const request = balenaRequest({
auth: auth,
debug: process.env.DEBUG_BALENA_REQUEST === 'true',
// The `isBrowser` option is deprecated and no longer needed for modern environments.
// isBrowser: false,
});
try {
console.log('Making a request to Balena API...');
const result = await request.send({
method: 'GET',
url: 'https://api.balena-cloud.com/ping',
headers: {
'Content-Type': 'application/json',
},
// Note: balena-request automatically handles authorization if auth is provided
});
console.log('Request successful! Status:', result.statusCode);
// console.log('Response body:', result.body);
} catch (error) {
console.error('Request failed:', error);
if (error instanceof balenaRequest.BalenaRequestError) {
console.error('This is a specific BalenaRequestError.');
}
}
}
makeRequest();