Skip to main content

REST

npm install --save @rest-hooks/rest

Define the API

api/Article.ts
import { Entity, createResource } from '@rest-hooks/rest';

export class Article extends Entity {
id: number | undefined = undefined;
title = '';
content = '';
author: number | null = null;
tags: string[] = [];

pk() {
return this.id?.toString();
}
}

export const ArticleResource = createResource({
urlPrefix: 'http://test.com',
path: '/article/:id',
schema: Article,
});

Our definitions are composed of two pieces. Our data model defined by Schema and the networking endpoints defined by RestEndpoint.

Bind the data with Suspense

import { useSuspense } from 'rest-hooks';
import { ArticleResource } from 'api/article';

export default function ArticleDetail({ id }: { id: number }) {
const article = useSuspense(ArticleResource.get, { id });
return (
<article>
<h2>{article.title}</h2>
<div>{article.content}</div>
</article>
);
}

useSuspense() guarantees access to data with sufficient freshness. This means it may issue network calls, and it may suspend until the fetch completes. Param changes will result in accessing the appropriate data, which also sometimes results in new network calls and/or suspends.

  • Fetches are centrally controlled, and thus automatically deduplicated
  • Data is centralized and normalized guaranteeing consistency across uses, even with different endpoints.
    • (For example: navigating to a detail page with a single entry from a list view will instantly show the same data as the list without requiring a refetch.)

Mutate the data

article.tsx
import { useController } from 'rest-hooks';
import { ArticleResource } from 'api/article';

export default function NewArticleForm() {
const controller = useController();
return (
<Form
onSubmit={e =>
controller.fetch(ArticleResource.create, new FormData(e.target))
}
>
<FormField name="title" />
<FormField name="content" type="textarea" />
<FormField name="tags" type="tag" />
</Form>
);
}

create then takes any keyable body to send as the payload and then returns a promise that resolves to the new Resource created by the API. It will automatically be added in the cache for any consumers to display.

We use FormData in the example since it doesn't require any opinionated form state management solution. Feel free to use whichever one you prefer.

Mutations automatically update the normalized cache, resulting in consistent and fresh data.