Skip to main content
Version: 4.5

URL Patterns

Common REST urls resemble the following:

  • /static_root/
    • GET - retrieve list of resources
      • optionally include search params /static_root/?size=20&page=5
    • POST - create resource
  • /static_root/[id]/
    • GET - retrieve one entity matching 'id'
    • PUT - update entire entity
    • PATCH - update partial entity
    • DELETE - delete entity

Resource comes out of the box with support for these patterns simply by defining the static urlRoot property on a Resource.

export default ArticleResource extends Resource {  readonly id: string = '';  //...
  pk() { return this.id; }  static urlRoot = '/articles/';}

It does this by using that urlRoot static property in two static methods:

ArticleResource.listUrl();// "/articles/"ArticleResource.listUrl({ size: 20, page: 5 });// "/articles/?size=20&page=5"ArticleResource.url({ id: 5 });// "/articles/5/"

Customizing the url patterns is typically as easy as overriding either of these methods. However, in more extreme scenarios, getFetchKey() can be set in a custom FetchShape definition.

Example#

A somewhat common pattern is to hold 'sub' resources at nested paths to their 'master'.

We might see something like /articles/[articleId]/comments/ to get the comments for a given article.

export default class CommentResource extends Resource {  readonly id: string = '';
  pk() {    return this.id;  }
  // since we won't be using urlRoot to build our urls we  // still need to tell rest hooks how to uniquely identify this Resource  static get key() {    return 'CommentResource';  }
  /**   * Get the url for a Resource   */  static url<T extends typeof Resource>(    this: T,    urlParams: { articleId: string } & Partial<AbstractInstanceType<T>>,  ): string {    if (urlParams) {      if (this.pk(urlParams) !== undefined) {        return `/articles/${articleId}/comments/${this.pk(urlParams)}`;      }    }    // since we're overriding the url() function we must keep the type the    // same, which means we might not get urlParams    throw new Error('Comments require articleId to retrieve');  }
  /**   * Get the url for many Resources   */  static listUrl(searchParams: { articleId: string }): string {    if (searchParams && Object.keys(searchParams).length) {      const { articleId, ...realSearchParams } = searchParams;      const params = new URLSearchParams(realSearchParams as any);      // this is essential for consistent url strings      params.sort();      return `/articles/${articleId}/comments/?${params.toString()}`;    }    throw new Error('Comments require articleId to retrieve');  }}
CommentResource.listUrl();// error thrownCommentResource.listUrl({ articleId: '5' });// "/articles/5/comments/"CommentResource.listUrl({ articleId: '5', size: 20, page: 6 });// "/articles/5/comments/?size=20&page=6"CommentResource.url({ id: 5 });// error thrownCommentResource.url({ articleId: '5', id: '23' });// "/articles/5/comments/23/"