Refetty is a set of tools to help on REST API consume challenge, like promise cancelable handler, sdk creation ands promise state manager
- 🎉 Generic promise state handlers
- 🔌 Framework agnostic
- 🔮 AbortController friendly
- 🏆 State management on sdk, (stop passing access token to all requests manually 🙏)
- 🔥 Some more awesome utilities
This repository is a monorepo that we manage using Lerna. That means that we actually publish several packages to npm from the same codebase, including:
Package | Version | Description |
---|---|---|
sdk | State handler with AbortController support | |
async | Promises handle methods | |
react | Hooks to work with promises (using async package under the hood) |
Install
yarn add @refetty/sdk @refetty/axios @refetty/react
Create an api.js
file to create your basic sdk
import { createSDK } from '@refetty/sdk'
import { AxiosAbortController } from '@refetty/axios'
import { axios } from 'axios'
const request = axios.create({
baseURL: 'http://api.example.com',
headers: {
'Content-Type': 'application/json',
},
})
const handler = options => state => request({
...options,
headers: {
...options.headers,
...(state.token && { Authorization: `Bearer ${state.token}` }),
}
})
const sdk = createSDK(handler, {
initialState: {},
AbortController: AxiosAbortController
})
export const login = sdk.add(auth => ({
method: 'get',
url: '/login',
auth,
transformResponse: axios.defaults.transformResponse.concat(data => {
sdk.setState(prevState => ({ ...prevState, token: data.token }))
return data
})
}))
export const getUsers = sdk.add(params => ({
method: 'get',
url: '/users',
params
}))
Now, in your react components:
import { useFetch } from '@refetty/react'
import { login, getUsers } from './api.js'
const Login = () => {
const onSubmit = async formValues => {
try {
const { data } = await login(formValues)
// do anything on success
} catch (error) {
//...
}
}
return (
<Form onSubmit={onSubmit}>
...
</Form>
)
}
const List = () => {
const [data, { loading }, fetch] = useFetch(getUsers)
// if you don't want fetch data in onMount, use useFetch(getUsers, { lazy: true }),
// and do trigger "fetch" function to dispatch request when you want
return loading ? <Loading /> : data.map(user => <UserCard {...user} />)
}
For more detailed explanations and examples, see the packages docs.
You can help improving this project sending PRs and helping with issues.