From fd40ad9d7f2592b9b1df9559bc4a5ff2b8d84f67 Mon Sep 17 00:00:00 2001 From: Christian Capeans Date: Thu, 29 Dec 2022 16:43:02 +0100 Subject: [PATCH 1/4] Document the useFetchClient hook --- docs/docs/core/hooks/use-fetch-client.mdx | 100 ++++++++++++++++++++++ docs/sidebars.js | 11 +++ 2 files changed, 111 insertions(+) create mode 100644 docs/docs/core/hooks/use-fetch-client.mdx diff --git a/docs/docs/core/hooks/use-fetch-client.mdx b/docs/docs/core/hooks/use-fetch-client.mdx new file mode 100644 index 0000000000..41c28aeeda --- /dev/null +++ b/docs/docs/core/hooks/use-fetch-client.mdx @@ -0,0 +1,100 @@ +--- +title: useFetchClient +slug: /hooks/use-fetch-client +description: API reference for the useFetchClient hook in Strapi +tags: + - hooks + - fetch-client +--- + +An abstraction around the axios instance wrapped in a hook. It provides a simple interface to handle API calls to the Strapi backend. +It handles request cancellation under the hook with `AbortController`, and when the component gets unmounted all the reqeusts that it has made are aborted. + +The hook exposes four methods: + +- **get(url, config)**: which is a method that given a relative url, will make a GET request to the Strapi backend with the configuration passed as second parameter, if needed. +- **post(url, data, config)**: which is a method that given a relative url, will make a POST request with the data provided to the Strapi backend with the configuration passed as third parameter, if needed. +- **put(url, data, config)**: which is a method that given a relative url, will make a PUT request with the data provided to the Strapi backend with the configuration passed as third parameter, if needed. +- **del(url, config)**: which is a method that given a relative url, will make a DELETE request to the Strapi backend with the configuration passed as second parameter, if needed. + +## Implementation details + +The fetch instance is running axios under the hook with two request interceptors. + +### Base URL + +The default URL will be the one defined in the environment variable: `STRAPI_ADMIN_BACKEND_URL`. + +### Interceptors + +#### Request + +The request interceptor adds the following parameters to the header: + +```js +{ + Authorization: `Bearer `, + Accept: 'application/json', + 'Content-Type': 'application/json', +} +``` + +#### Response + +If everything has gone correctly, the response is returned as it comes from the backend. However, if it cointains a **status code of 401**, the authentication details will be removed from +the application storage and the window will be reload + +:::caution +Have this in mind if using this hook in pages where the auth token is not available, such as login, because it will create an infinite loop if not treating the error correctly. See section [Troubleshooting](#troubleshooting) +::: + +### Basic usage + +Below is a basic example usage where we fetch the Strapi backend content types + +```jsx +import {useState} from "react" +import useFetchClient from '@strapi/admin/admin/src/hooks/useFetchClient'; + +const Component () => { + const [items, setItems] = useState([]); + const { get } = useFetchClient(); + const requestURL = "/some-endpoint"; + + const handleGetData = () => { + const { data } = await get(requestURL); + setItems(data.items); + } + + return( +
+
+ { + items && items.map(item =>

{item.name}

) + } +
+ +
+ ) +} +``` + +## Further Reading + +- [axios instance API](https://axios-http.com/docs/instance) +- [AbortController](https://axios-http.com/docs/cancellation) + +## Troubleshooting + +### Authentication problems + +Trying to access a protected route from a context where the auth token is not available may lead to an infinite loop, because of the response interceptor that +reloads the page when obtaining a 401 response. One option available to avoid this from happening is to not considering a 401 response as an error, as follows: + +```js +const { + data: { data: properties }, +} = await get(`/protected-endpoint`, { + validateStatus: (status) => status < 500, +}); +``` diff --git a/docs/sidebars.js b/docs/sidebars.js index c64e6f077a..6154e8ff2a 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -39,6 +39,17 @@ const sidebars = { }, ], }, + { + type: 'category', + label: 'Hooks', + items: [ + { + type: 'doc', + label: 'useFetchClient', + id: 'core/hooks/use-fetch-client', + }, + ], + }, { type: 'category', label: 'Content Type Builder', From fd3475965bebb53db667c8014dccdd1e661cbecc Mon Sep 17 00:00:00 2001 From: Christian Capeans Date: Tue, 3 Jan 2023 13:28:23 +0100 Subject: [PATCH 2/4] Reorganize document --- docs/docs/core/hooks/use-fetch-client.mdx | 76 ++++++++++++----------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/docs/docs/core/hooks/use-fetch-client.mdx b/docs/docs/core/hooks/use-fetch-client.mdx index 41c28aeeda..ccd26a9ac5 100644 --- a/docs/docs/core/hooks/use-fetch-client.mdx +++ b/docs/docs/core/hooks/use-fetch-client.mdx @@ -7,15 +7,48 @@ tags: - fetch-client --- -An abstraction around the axios instance wrapped in a hook. It provides a simple interface to handle API calls to the Strapi backend. -It handles request cancellation under the hook with `AbortController`, and when the component gets unmounted all the reqeusts that it has made are aborted. +## Usage + +The following examples shows a basic way to use the `useFetchClient` hook to make a get request to a strapi backend endpoint: + +```jsx +import {useState} from "react" +import useFetchClient from '@strapi/admin/admin/src/hooks/useFetchClient'; + +const Component () => { + const [items, setItems] = useState([]); + const { get } = useFetchClient(); + const requestURL = "/some-endpoint"; + + const handleGetData = () => { + const { data } = await get(requestURL); + setItems(data.items); + } + + return( +
+
+ { + items && items.map(item =>

{item.name}

) + } +
+ +
+ ) +} +``` + +## Methods + +Essentially, this is an abstraction around the axios instance wrapped in a hook. It provides a simple interface to handle API calls to the Strapi backend. +It handles request cancellation under the hook with [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController), and when the component gets unmounted all the reqeusts that it has made are aborted. The hook exposes four methods: -- **get(url, config)**: which is a method that given a relative url, will make a GET request to the Strapi backend with the configuration passed as second parameter, if needed. -- **post(url, data, config)**: which is a method that given a relative url, will make a POST request with the data provided to the Strapi backend with the configuration passed as third parameter, if needed. -- **put(url, data, config)**: which is a method that given a relative url, will make a PUT request with the data provided to the Strapi backend with the configuration passed as third parameter, if needed. -- **del(url, config)**: which is a method that given a relative url, will make a DELETE request to the Strapi backend with the configuration passed as second parameter, if needed. +- **get(url, config)**: which is a method that given a relative url (string), will make a GET request to the Strapi backend with the configuration (object) passed as second parameter, if needed. +- **post(url, data, config)**: which is a method that given a relative url (string), will make a POST request with the data (object) provided to the Strapi backend with the configuration passed as third parameter (object), if needed. +- **put(url, data, config)**: which is a method that given a relative url (string), will make a PUT request with the data (object) provided to the Strapi backend with the configuration passed as third parameter (object), if needed. +- **del(url, config)**: which is a method that given a relative url (string), will make a DELETE request to the Strapi backend with the configuration passed as second parameter (object), if needed. ## Implementation details @@ -48,37 +81,6 @@ the application storage and the window will be reload Have this in mind if using this hook in pages where the auth token is not available, such as login, because it will create an infinite loop if not treating the error correctly. See section [Troubleshooting](#troubleshooting) ::: -### Basic usage - -Below is a basic example usage where we fetch the Strapi backend content types - -```jsx -import {useState} from "react" -import useFetchClient from '@strapi/admin/admin/src/hooks/useFetchClient'; - -const Component () => { - const [items, setItems] = useState([]); - const { get } = useFetchClient(); - const requestURL = "/some-endpoint"; - - const handleGetData = () => { - const { data } = await get(requestURL); - setItems(data.items); - } - - return( -
-
- { - items && items.map(item =>

{item.name}

) - } -
- -
- ) -} -``` - ## Further Reading - [axios instance API](https://axios-http.com/docs/instance) From 7300e336c1d0e027cc8452125aac543605bcf748 Mon Sep 17 00:00:00 2001 From: Christian Capeans Date: Thu, 5 Jan 2023 11:11:38 +0100 Subject: [PATCH 3/4] Fix grammatical mistakes --- docs/docs/core/hooks/use-fetch-client.mdx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/docs/core/hooks/use-fetch-client.mdx b/docs/docs/core/hooks/use-fetch-client.mdx index ccd26a9ac5..defb0fe0cb 100644 --- a/docs/docs/core/hooks/use-fetch-client.mdx +++ b/docs/docs/core/hooks/use-fetch-client.mdx @@ -4,23 +4,24 @@ slug: /hooks/use-fetch-client description: API reference for the useFetchClient hook in Strapi tags: - hooks - - fetch-client + - axios + - data --- ## Usage -The following examples shows a basic way to use the `useFetchClient` hook to make a get request to a strapi backend endpoint: +The following example shows a basic way to use the `useFetchClient` hook to make a get request to a Strapi backend endpoint: ```jsx import {useState} from "react" import useFetchClient from '@strapi/admin/admin/src/hooks/useFetchClient'; -const Component () => { +const Component = () => { const [items, setItems] = useState([]); const { get } = useFetchClient(); const requestURL = "/some-endpoint"; - const handleGetData = () => { + const handleGetData = async () => { const { data } = await get(requestURL); setItems(data.items); } @@ -29,7 +30,7 @@ const Component () => {
{ - items && items.map(item =>

{item.name}

) + items && items.map(item =>

{item.name}

)) }
@@ -40,15 +41,15 @@ const Component () => { ## Methods -Essentially, this is an abstraction around the axios instance wrapped in a hook. It provides a simple interface to handle API calls to the Strapi backend. -It handles request cancellation under the hook with [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController), and when the component gets unmounted all the reqeusts that it has made are aborted. +Essentially, this is an abstraction around the axios instance exposed by a hook. It provides a simple interface to handle API calls to the Strapi backend. +It handles request cancellations inside the hook with an [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). This is typically triggered when the component is unmounted so all the requests that it is currently making are aborted. The hook exposes four methods: -- **get(url, config)**: which is a method that given a relative url (string), will make a GET request to the Strapi backend with the configuration (object) passed as second parameter, if needed. -- **post(url, data, config)**: which is a method that given a relative url (string), will make a POST request with the data (object) provided to the Strapi backend with the configuration passed as third parameter (object), if needed. -- **put(url, data, config)**: which is a method that given a relative url (string), will make a PUT request with the data (object) provided to the Strapi backend with the configuration passed as third parameter (object), if needed. -- **del(url, config)**: which is a method that given a relative url (string), will make a DELETE request to the Strapi backend with the configuration passed as second parameter (object), if needed. +- **get(url, config)**: requires a relative url (`string`) and makes a `GET` request to the Strapi backend with an optional configuration `object` passed as second parameter. +- **post(url, data, config)**: requires a relative url (`string`) and makes a `POST` request with the required data `object` to the Strapi backend with the optional configuration `object` passed as third parameter. +- **put(url, data, config)**: requires a relative url (`string`) and makes a `PUT` request with the required data `object` to the Strapi backend with the optional configuration `object` passed as third parameter. +- **del(url, config)**: requires a relative url (`string`) and makes a `DELETE` request to the Strapi backend with an optional configuration `object` passed as second parameter. ## Implementation details From 5b649a345a6f67a03daa96d4897cb4444d5c44a7 Mon Sep 17 00:00:00 2001 From: Christian Capeans Date: Thu, 5 Jan 2023 13:39:53 +0100 Subject: [PATCH 4/4] Fix grammatical mistakes --- docs/docs/core/hooks/use-fetch-client.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/docs/core/hooks/use-fetch-client.mdx b/docs/docs/core/hooks/use-fetch-client.mdx index defb0fe0cb..83d28fe201 100644 --- a/docs/docs/core/hooks/use-fetch-client.mdx +++ b/docs/docs/core/hooks/use-fetch-client.mdx @@ -53,7 +53,7 @@ The hook exposes four methods: ## Implementation details -The fetch instance is running axios under the hook with two request interceptors. +The following information is the internal additions we've added to the axios instance via two request interceptors. As well as an explanation of the `baseUrl`. ### Base URL @@ -75,11 +75,11 @@ The request interceptor adds the following parameters to the header: #### Response -If everything has gone correctly, the response is returned as it comes from the backend. However, if it cointains a **status code of 401**, the authentication details will be removed from -the application storage and the window will be reload +If everything works correctly, the response is returned as it comes from the backend. However, if it contains a **status code of 401** the authentication details will be removed from +the application storage and the window will be reloaded. :::caution -Have this in mind if using this hook in pages where the auth token is not available, such as login, because it will create an infinite loop if not treating the error correctly. See section [Troubleshooting](#troubleshooting) +Have this in mind if using this hook in pages where the auth token is not available, such as `login`, because it will create an infinite loop. See the [Troubleshooting](#troubleshooting) section for more information. ::: ## Further Reading @@ -91,8 +91,8 @@ Have this in mind if using this hook in pages where the auth token is not availa ### Authentication problems -Trying to access a protected route from a context where the auth token is not available may lead to an infinite loop, because of the response interceptor that -reloads the page when obtaining a 401 response. One option available to avoid this from happening is to not considering a 401 response as an error, as follows: +Trying to access a protected route from a context where the auth token is not available may lead to an infinite loop due to the response interceptor that +reloads the page when obtaining a 401 response. One option to avoid this from happening is to not consider a 401 response as an error, see below: ```js const {