Skip to main content
Version: 6.0

createResource

Resources are a collection of RestEndpoints that operate on a common data by sharing a schema

Usage​

api/TodoResource.ts
export class Todo extends Entity {
id = '';
title = '';
completed = false;
pk() {
return this.id;
}
}

const TodoResource = createResource({
urlPrefix: 'https://jsonplaceholder.typicode.com',
path: '/todos/:id',
schema: Todo,
});
const todo = useSuspense(TodoResource.get, { id: '5' });
const todos = useSuspense(TodoResource.getList);
controller.fetch(TodoResource.create, {
title: 'finish installing rest hooks',
});
controller.fetch(
TodoResource.update,
{ id: '5' },
{ ...todo, completed: true },
);
controller.fetch(TodoResource.partialUpdate, { id: '5' }, { completed: true });
controller.fetch(TodoResource.delete, { id: '5' });

Arguments​

{
path: string;
schema: Schema;
Endpoint?: typeof RestEndpoint;
urlPrefix?: string;
} & EndpointExtraOptions

path​

Passed to RestEndpoint.path

schema​

Passed to RestEndpoint.schema

urlPrefix​

Passed to RestEndpoint.urlPrefix

Endpoint​

Class used to construct the members.

EndpointExtraOptions​

Members​

These provide the standard CRUD endpointss common in REST APIs. Feel free to customize or add new endpoints based to match your API.

get​

  • method: 'GET'
  • path: path
  • schema: schema

Commonly used with useSuspense(), Controller.invalidate

getList​

  • method: 'GET'
  • path: shortenPath(path)
    • Removes the last argument:
      createResource({ path: '/:first/:second' }).getList.path === '/:first';
      createResource({ path: '/:first' }).getList.path === '/';
  • schema: [schema]

Commonly used with useSuspense(), Controller.invalidate

create​

  • method: 'POST'
  • path: shortenPath(path)
    • Removes the last argument:
      createResource({ path: '/:first/:second' }).getList.path === '/:first';
      createResource({ path: '/:first' }).create.path === '/';
  • schema: schema

Commonly used with Controller.fetch

update​

  • method: 'PUT'
  • path: path
  • schema: schema

Commonly used with Controller.fetch

partialUpdate​

  • method: 'PATCH'
  • path: path
  • schema: schema

Commonly used with Controller.fetch

delete​

  • method: 'DELETE'
  • path: path
  • schema: new schema.Delete(schema)
  • process:
    (value, params) {
    return value && Object.keys(value).length ? value : params;
    },

Commonly used with Controller.fetch

Function Inheritance Patterns​

To reuse code around Resource design, you can create your own function that calls createResource(). This has similar effects as class-based inheritance.

import {
createResource,
RestEndpoint,
type EndpointExtraOptions,
type RestGenerics,
} from '@rest-hooks/rest';

export class AuthdEndpoint<
O extends RestGenerics = any,
> extends RestEndpoint<O> {
getRequestInit(body: any): RequestInit {
return {
...super.getRequestInit(body),
credentials: 'same-origin',
};
}
}

export function createMyResource<U extends string, S extends Schema>({
path,
schema,
Endpoint = AuthdEndpoint,
...extraOptions
}: {
// `readonly` is critical for the argument types to be inferred correctly
readonly path: U;
readonly schema: S;
readonly Endpoint?: typeof RestEndpoint;
urlPrefix?: string;
} & EndpointExtraOptions) {
const BaseResource = createResource({
path,
Endpoint,
schema,
...extraOptions,
});

return {
...BaseResource,
getList: BaseResource.getList.extend({
schema: { results: [schema], total: 0, limit: 0, skip: 0 },
}),
};
}

The Github Example App uses this pattern as well.