Verified Commit b36cc236 authored by Florent Chehab's avatar Florent Chehab
Browse files

docs(frontend): how to interact with the REST API

Closes #180
parent a897a98f
Pipeline #59739 canceled with stages
in 2 minutes
# Interacting with the backend REST API
REX-DRI is a _one page application_ that access all its data from the backend REST API.
There are no Js library to easily handle interactions with a REST API (and all REST API are different). So, all these interactions are custom made.
## General idea
!> All the interactions with the backend API are handle in a state-full manner.
Each endpoint can be queried either regarding _one_ (for reading, updating or deleting) or _all_ (for reading or deleting) elements.
> In dev, after the app is loaded, you can have an idea of the state of each "endpoint" by doing:
```js
globalRexDriState.get("api-countries-all");
```
_example output ("one" endpoints are more complex)_:
```json
{
"isReading": false,
"readSucceeded": {
"data": [
{
"obj_info": {
"user_can_edit": false,
"user_can_moderate": false,
"versioned": false
},
"id": "DZ",
"name": "Algérie",
"iso_alpha2_code": "DZ",
"iso_alpha3_code": "DZA",
"region_name": "Afrique",
"region_un_code": "002",
"sub_region_name": "Afrique septentrionale",
"intermediate_region_name": "",
"intermediate_region_un_code": ""
},
...
],
"requestParams": {
"_data": {},
"_queryParams": {},
"_endPointAttrs": []
},
"readAt": 1586890565592
},
"readFailed": {
"failed": false,
"error": null
},
"isInvalidated": false
}
```
So everything about the query and its status is stored in a global shared state. That's how for instance we know that some data is currently loading and we can show the corresponding indicator, etc.
## Developer experience
As a developer, you fortunately don't have to bother a lot with it for simple things.
### Reading data from the API
The simplest case is when you have a component that only needs to read data from an endpoint.
In this case you have the `withNetworkWrapper` HOC that will do everything for you:
```js
import withNetworkWrapper, { NetWrapParam } from ".../withNetworkWrapper";
export default withNetworkWrapper([
new NetWrapParam("userData", "one", {
addDataToProp: "userData",
params: RequestParams.Builder.withId(CURRENT_USER_ID).build()
})
])(ThemeProvider);
```
Using this HOC this way:
- You will be sure to have the latest stored in the browser state data displayed,
- A loading indicator will be displayed if the data is not ready,
- The request to the backend will be magically made; you don't have to worry about them.
- The resulting data of the request is added to the `addDataToProp` prop (or by default the `routeName`).
As you can see, you can change the request "`GET` parameters".
You will see that those parameters can also depend on your component `props`.
```js
import withNetworkWrapper, { NetWrapParam } from ".../withNetworkWrapper";
const buildParams = univId =>
RequestParams.Builder.withQueryParam("university", univId).build();
export default compose(
withUnivInfo(),
withNetworkWrapper([
new NetWrapParam("sharedUnivFeedbacks", "all", {
addDataToProp: "feedback",
params: props => buildParams(props.univId),
propTypes: {
univId: PropTypes.number.isRequired
}
})
])
)(SharedUnivFeedback);
```
Using the HOC this way:
- You have the same guaranties as above,
- And you are guaranteed to displayed the latest data that matches the props at any given time (there is nothing else to do).
!> Don't forget to specify the `propTypes` of the props you want to access; otherwise it won't work.
### Other interactions with the API
?> All interactions with the API are handled with the global hooks we have described [here](Application/Frontend/global_state.md).
The master of all hooks is the `useApi` hook: it gives you access to all the possible interactions; you shouldn't really use it.
Then you have `useApiRead`, `useApiDelete`, `useApiCreate`, `useApiUpdate` to handle the different type of requests.
Finally you have the `useSingleApiData` (that `withNetworkWrapper` is using under the hood); that will handle some of the auto-reloading of data, etc.
With those hooks and the numerous examples in the code base you should be good to go for any challenge :smile:.
## Under the hood
So we have a HOC using some cool hooks that are using the awesome `useGlobalReducer` hook.
If you are curious, check them out.
If you are really curious, you can also check the `CrudActions` and `CrudReducers` used to understand how the "state-full" characteristic is obtained.
......@@ -24,8 +24,9 @@
- [React basics](Application/Frontend/react.md)
- [Global State Handling](Application/Frontend/global_state.md)
- [Tests](Application/Frontend/tests.md)
- [Interacting with the backend API](Application/Frontend/interacting_with_backend.md)
- [Services](Application/Frontend/services.md)
- [Tests](Application/Frontend/tests.md)
- [Map](Application/Frontend/map.md)
- [Troubleshooting](Application/Frontend/troubleshooting.md)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment