react-query-restful v1.1.0
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-restfulor with yarn:
yarn add react-query-restfulInitialization
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 testContributing
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