Upgrading from 4 to 5
Deprecation Removals
These previously deprecated members have been removed:
Resource.getKey() -> Resource.key
Simply rename this to get key()
Resource.getEntitySchema() -> Resource
This has been simplified to simply use the Resource itself:
class MyResource extends Resource {
static customEndpoint<T extends typeof MyResource>(this: T) {
return {
...super.listShape(),
// notice the next line
schema: { results: [this.getEntitySchema()], nextPage: '' },
};
}
}
class MyResource extends Resource {
static customEndpoint<T extends typeof MyResource>(this: T) {
return {
...super.listShape(),
// notice the next line
schema: { results: [this], nextPage: '' },
};
}
}
Other breaking changes
yarn add @rest-hooks/[email protected] @rest-hooks/[email protected]
Be sure to also upgrade these libraries if you use them:
@rest-hooks/[email protected]
@rest-hooks/[email protected]
These libraries don't have any breaking changes within themselves, but
they do require [email protected]
and (reflexively) [email protected]
requires
at least v2.
Network Definitions (Resource/FetchShape, etc)
FetchShape: {type: 'delete'} -> { type: 'mutate', schema: new schemas.Delete(this) }
Resource.deleteShape()
will continue to work as expected. However, if
you defined some custom shapes with type: 'delete'
class MyResource extends Resource {
static someOtherDeleteShape<T extends typeof SimpleResource>(
this: T,
): DeleteShape<any, Readonly<object>> {
const options = this.getFetchOptions();
return {
// changed
type: 'delete',
// changed
schema: this.asSchema(),
options,
getFetchKey: (params: object) => {
return 'DELETE ' + this.url(params);
},
fetch: (params: Readonly<object>) => {
return this.fetch('delete', this.url(params));
},
};
}
}
import { schemas } from 'rest-hooks';
class MyResource extends Resource {
static someOtherDeleteShape<T extends typeof SimpleResource>(
this: T,
): DeleteShape<any, Readonly<object>> {
const options = this.getFetchInit();
return {
// changed
type: 'mutate',
// changed
schema: new schemas.Delete(this),
options,
getFetchKey: (params: object) => {
return 'DELETE ' + this.url(params);
},
fetch: (params: Readonly<object>) => {
return this.fetch('delete', this.url(params));
},
};
}
}
Validation Errors:
This is likely due to a malformed response
To aid with common schema definition or networking errors, Rest Hooks will sometimes throw an error. This only occurs during development, to help users correctly define their schemas and endpoints.
While the heuristics have been heavily tuned, if you don't believe the errors reported are valid please report a bug.
When reporting, be sure to include
- The exact network response from the network inspector
- The full schema definition.
Alternatively, this can be disabled by adding static automaticValidation = 'silent' | 'warn'
class MyResource extends Resource {
static automaticValidation = 'silent' as const;
// ...
}
Warn will no longer throw an error, but still add a message to the browser console. Silent removes the check completely.
Managers
These only apply if you have a custom Manager
action.meta.url -> action.meta.key
It's recommend to now use the action creators
exported from @rest-hooks/core
getState()
This is very unlikely to make a difference, but the internal cache state
(accessible with getState()) might be slightly different. Mutations now
result in entries in meta
and results
. This brings them more in line with
reads, making the distinction simply about which hooks they are allowed
in. (To prevent unwanted side effects.)
Cache Lifetime Policy
useInvalidator() triggers suspense
You can likely remove invalidIfStale if used in conjunction with useInvalidator()
invalidIfStale is still useful to disable the stale-while-revalidate
policy.
delete
suspends instead of throwing 404
Delete marks an entity as deleted. Any response requiring that entity will suspend. Previously it throw a 404 error.
Missing entities suspend
Required entities missing from network response will now throw error in useResource() just like other unexpected deserializations.
Use SimpleRecord for optional entities.
const schema = {
data: MyEntity,
};
class OptionalSchema extends SimpleRecord {
readonly data: MyEntity | null = null;
static schema = {
data: MyEntity,
};
}
const schema = OptionalSchema;
invalidIfStale
When invalidIfStale is true, useCache() and useStatefulResource() will no longer return entities, even if they are in the cache.
This matches the expected behavior that any loading
data should not be usable.
Upgrading from beta versions to final
The last breaking changes introduced to rest-hook
were in delta.0
where TTL
and deletes were reworked. If you are on a more recent beta (i
, j
, k
, rc
),
upgrades should be as simple as updating the version.
If this is not the case, please report a bug.
Deprecations
After a successful upgrade, it is recommended to adopt the modern practices.
Resource.getFetchOptions() -> Resource.getFetchInit()
class AuthdResource extends Resource {
static getFetchOptions = (options: RequestInit) => ({
...options,
credentials: 'same-origin',
});
}
class AuthdResource extends Resource {
static getFetchInit = (init: RequestInit) => ({
...init,
credentials: 'same-origin',
});
}
(Resource.getFetchInit())../api/resource#static-getfetchinitinit-requestinit-requestinit)
Resource.asSchema() -> Resource
This has been simplified to simply use the Resource itself:
class MyResource extends Resource {
static customEndpoint<T extends typeof MyResource>(this: T) {
return {
...super.listShape(),
// notice the next line
schema: { results: [this.asSchema()], nextPage: '' },
};
}
}
class MyResource extends Resource {
static customEndpoint<T extends typeof MyResource>(this: T) {
return {
...super.listShape(),
// notice the next line
schema: { results: [this], nextPage: '' },
};
}
}
FetchShape -> Endpoint
@rest-hooks/rest
yarn add @rest-hooks/rest
Rest Hooks is protocol agnostic, so the REST/CRUD specific class Resource
will eventually be fully deprecated and removed. @rest-hooks/rest
is intended as its
replacement. Other supplementary libraries like @rest-hooks/graphql
could be
added in the future, for intance. This is also beneficial as these libraries
change more frequently than the core of rest hooks.
import { Resource } from 'rest-hooks';
class MyResource extends Resource {
}
import { Resource } from '@rest-hooks/rest';
class MyResource extends Resource {
}
Breaking change:
Nested entities
static schema
will return fromuseResource()
static schema
../guides/nested-response