v0.10: Consistent Null Handling, URL Utilities
This release focuses on consistency and extensibility. Null handling is now uniform across all schema types, making data transformations more predictable. New URL utilities enable custom URL construction and search parameter encoding.
class MyEndpoint<O extends RestGenerics = any> extends RestEndpoint<O> {
searchToString(searchParams) {
// Use qs library for complex nested object encoding
return qs.stringify(searchParams);
}
}
Breaking Changes:
Other Improvements:
- RestEndpoint.searchToString() for custom search param encoding
- getUrlBase, getUrlTokens exports for custom URL construction
- DevToolsManager memory leak fix
Consistent null handling
null values are now consistently retained across all schema types. Previously, [] shorthand and schema.Array
behaved differently when encountering null values. #2912
[]and schema.Array now behave identicallynullvalues are retained everywhere (they were already retained in nested Entities)undefinedvalues are still filtered out
This change ensures more predictable behavior when working with APIs that explicitly return null to indicate
absence of data versus undefined for missing fields.
URL Utilities
RestEndpoint.searchToString()
RestEndpoint.searchToString() enables custom encoding of search parameters. This is particularly useful for APIs that expect complex nested objects in query strings. #2919
For example, to encode complex objects using the qs library:
import { RestEndpoint, RestGenerics } from '@data-client/rest';
import qs from 'qs';
class MyEndpoint<O extends RestGenerics = any> extends RestEndpoint<O> {
searchToString(searchParams) {
return qs.stringify(searchParams);
}
}
getUrlBase, getUrlTokens
New exports getUrlBase and getUrlTokens provide the building blocks for custom
RestEndpoint.url() implementations.
#2919
import { getUrlBase, getUrlTokens } from '@data-client/rest';
// Parse path tokens for custom URL logic
const tokens = getUrlTokens('/users/:id/posts/:postId');
// => ['id', 'postId']
// Get base URL without path parameters
const base = getUrlBase('/users/:id');
// => '/users/'
DevToolsManager memory fix
The DevToolsManager action buffer is now limited to 100 entries, preventing memory leaks in long-running
applications or those with frequent updates. 4e6a39e
Migration Guide
This upgrade requires updating all package versions simultaneously.
- NPM
- Yarn
- pnpm
- esm.sh
yarn add @data-client/react@^0.10.0 @data-client/rest@^0.10.0 @data-client/test@^0.10.0 @data-client/img@^0.10.0
npm install --save @data-client/react@^0.10.0 @data-client/rest@^0.10.0 @data-client/test@^0.10.0 @data-client/img@^0.10.0
pnpm add @data-client/react@^0.10.0 @data-client/rest@^0.10.0 @data-client/test@^0.10.0 @data-client/img@^0.10.0
<script type="module">
import * from 'https://esm.sh/@data-client/react@^0.10.0';
import * from 'https://esm.sh/@data-client/rest@^0.10.0';
import * from 'https://esm.sh/@data-client/test@^0.10.0';
import * from 'https://esm.sh/@data-client/img@^0.10.0';
</script>
Null values in arrays
If your code relied on null values being filtered out of arrays, you'll need to handle this explicitly:
import { Entity, schema, RestEndpoint } from '@data-client/rest';
class User extends Entity {
id = '';
name = '';
pk() { return this.id; }
}
const getUsers = new RestEndpoint({
path: '/users',
schema: new schema.Array(User),
});
// API response: [{ id: '1' }, null, { id: '2' }]
const usersWithoutNull = useSuspense(getUsers);
import { Entity, schema, RestEndpoint } from '@data-client/rest';
class User extends Entity {
id = '';
name = '';
pk() { return this.id; }
}
const getUsers = new RestEndpoint({
path: '/users',
schema: new schema.Array(User),
});
// API response: [{ id: '1' }, null, { id: '2' }]
const usersWithoutNull = useSuspense(getUsers).filter(Boolean);
This change aligns with how nested Entities already handled null values,
making the behavior consistent across all schema types.
Upgrade support
As usual, if you have any troubles or questions, feel free to join our or file a bug
