Skip to content

Just a small collection of hooks that make it easy to integrate React Query into a REST API. Compatible with React Native.

License

Notifications You must be signed in to change notification settings

quasardd/react-query-restful

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

84 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

React Query RESTful

react-query-restful is just a small collection of hooks that make it easy to integrate React Query into a REST API.

For a better understanding of the library, it is recommended to understand how React Query works.

Compatible with React Native.

Installing

Install with npm or yarn

npm:

npm i --save react-query-restful

or with yarn:

yarn add react-query-restful

Initialization

Adding the provider

import { RestClientProvider } from "react-query-restful";

export default function App() {
  return (
    <RestClientProvider baseUrl="http://localhost:3000/api/">
      <Example />
    </RestClientProvider>
  );
}

Query usage

import { buildQuery } from "react-query-restful";

export const getUsersQuery = buildQuery({ path: "users" });

function Example() {
  // GET http://localhost:3000/api/users
  const { isLoading, error, data } = getUsersQuery();

  // OR GET http://localhost:3000/api/users/1/vehicles?page=1
  /* const { isLoading, error, data } = getUsersQuery({
    appendToUrl: "/1/vehicles",
    params: {
      page: 1,
    },
    options: {
      // Options from react-query
      retry: 2,
    },
  }); */

  if (isLoading) return "Loading...";

  if (error) return "An error has occurred: " + error.message;

  return (
    <div>
      <h1>{data.name}</h1>
      <p>{data.description}</p>
      <strong>πŸ‘€ {data.subscribers_count}</strong>{" "}
      <strong>✨ {data.stargazers_count}</strong>{" "}
      <strong>🍴 {data.forks_count}</strong>
    </div>
  );
}

Mutation usage

The buildMutation method will return a few functions, each one representing a different HTTP method.

Example:

  • createMutation (for POST request)
  • updateMutation (for PATCH request)
  • deleteMutation (for DELETE request)
  • replaceMutation (for PUT request)

All will share the same path & configuration.

NOTE: The mutation prefix (create update delete replace) are only references to the http method.

import { buildMutation } from "react-query-restful";

export const {
  createMutation,
  updateMutation,
  deleteMutation,
  replaceMutation,
} = buildMutation({
  path: "users",
});

/** You don't need to destruct all of them, it can also be done like so
 * export const { createMutation } = buildMutation({ path: 'users' });
 */

function Example() {
  const createUser = createMutation();

  /* OR
  const createUser = createUserMutation({
    invalidatePaths: ["products"],
    options: {
      // Options from react-query
      retry: 2,
    },
  }); */

  async function handleSubmit() {
    /**
     * POST /users {
     *  name: "John Doe"
     * }
     */
    await createUser.mutateAsync({
      data: {
        name: "John Doe",
      },
    });

    /**
     * POST /users/1/vehicles {
     *  plate: "XXXXX"
     * }
     */
    await createUser.mutateAsync({
      appendToUrl: "/1/vehicles",
      data: {
        plate: "XXXXX",
      },
    });
  }

  return (
    <div>
      <h1>Hello there!</h1>
    </div>
  );
}

Wildcards

When building a mutation or a query, you can use wildcards in the path. The wildcart must be surrounded by square brackets ([]) and the name of the wildcard must be the same as the name of the query property.

import { buildQuery } from "react-query-restful";

export const getUserQuery = buildQuery({ path: "users/[id]" });
export const { createMutation: createUserMutation } = buildMutation({ path: "users/[id]" });

function Example() {
  // GET http://localhost:3000/api/users/1
  const { isLoading, error, data } = getUserQuery({
    query: {
      id: 1,
    },
  });

  // POST http://localhost:3000/api/users/1
  const { mutateAsync } = createUserMutation({ query: { id: 1 } });

  {...}
}

Caching and Authentication

You can cache the mutation / query result using the cacheResponse property.

Example:

export const { createSignInMutation } = createMutation({
  path: ["auth", "sign-in"], // Same as `baseUrl/auth/sign-in`
  cacheResponse: {
    key: "user",
  },
});

Assuming that the response contains the user data with the accessToken property, you can use the getSimpleJwtAuth function to set the Authorization header with the Bearer prefix. You must specify the key where it's stored in the cache, and the path until the token.

This is just a shorthand and is not required.

const App = ({ children }) => {
  return (
    <RestClientProvider
      baseUrl="http://localhost:3000/api/"
      {...getSimpleJwtAuth({ key: "user", path: "data.user.accessToken" })}
    >
      {children}
    </RestClientProvider>
  );
};

You can make your own custom authentication logic, example:

import { AsyncStorage } from "react-query-restful";

export const myOwnLogic = () => ({
  interceptors: {
    onRequest: async (config: any) => {
      const cachedToken = await AsyncStorage.getItem("token");

      if (cachedToken && config.headers) {
        const parsedToken = JSON.parse(cachedToken);

        config.headers.Authorization = `Bearer ${token}`;
      }

      return config;
    },
  },
});

And then pass it to the provider:

const App = ({ children }) => {
  return (
    <RestClientProvider baseUrl="http://localhost:3000/api/" {...myOwnLogic()}>
      {children}
    </RestClientProvider>
  );
};

Auto invalidation feature

Mutations are automatically invalidating the queries that shared the same path, to disable this, pass a falsy autoInvalidation in the RestClientProvider.

Mutation properties

Property Description Required
path A string or a array of string that will be appended to the baseUrl. true
invalidatePaths A array of strings that will be used to invalidate the queries after a successful mutation call. false
cacheResponse A object with the key that will be used to cache the response. false
options A object with the options from react-query. false
appendToUrl A string that will be appended to the baseUrl. false

When calling the result of the build at component level, you can pass again theses properties, but all now will be optional.

And when calling the methods mutateAsync or mutate from mutation, you can pass the following properties:

Property Description Required
data A object with the data to be sent in the request body. false
appendToUrl A string that will be appended to the baseUrl. false
query A object that will fulfill the wildcards. false

Query properties

Property Description Required
path A string or a array of string that will be appended to the baseUrl. true
invalidatePaths A array of strings that will be used to invalidate the queries after a successful mutation call. false
cacheResponse A object with the key that will be used to cache the response. false
options A object with the options from react-query. false
appendToUrl A string that will be appended to the baseUrl. false
params A object with the params that will be appended to the url. false
query A object that will fulfill the wildcards. false

When calling the result of the build at component level, you can pass again theses properties, but all now will be optional.

Provider properties

Property Description Required
baseUrl A string with the base url. true
axiosConfig A object with the axios config. false
clientConfig A object with the React-Query Client config. false
autoInvalidation A boolean that will enable or disable auto invalidation. false
interceptors A object with a few interceptors that will be attached to axios. false

Running the tests

yarn && yarn test

Contributing

Feel free to submit a PR.

Authors

See also the list of contributors who participated in this project.

License

This project is licensed under the MIT License - see the LICENSE file for details

About

Just a small collection of hooks that make it easy to integrate React Query into a REST API. Compatible with React Native.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published