Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/harryy2510/rehttp

Highly customizable http client library for react
https://github.com/harryy2510/rehttp

ajax hook http react rest

Last synced: about 20 hours ago
JSON representation

Highly customizable http client library for react

Awesome Lists containing this project

README

        

# React + HTTP = ReHttp
> A highly customizable http client library for react

[![npm (scoped)](https://badgen.net/npm/v/@harryy/rehttp)](https://npmjs.com/package/@harryy/rehttp)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
![GitHub](https://badgen.net/github/license/harryy2510/rehttp)
![npm bundle size (scoped)](https://badgen.net/bundlephobia/minzip/@harryy/rehttp)
![npm bundle size (scoped)](https://badgen.net/bundlephobia/min/@harryy/rehttp)
![GitHub top language](https://img.shields.io/github/languages/top/harryy2510/rehttp)
![David](https://img.shields.io/david/harryy2510/rehttp)

## Features

- [x] No bloated dependencies
- [x] Optional global configuration
- [x] Typescript support
- [x] Promise based
- [x] Hooks for function component
- [x] Lazy fetch support
- [x] Transforming request and response
- [x] Callbacks for request, response and error
- [x] Caching
- [x] Use outside of react context
- [x] Component (for class based component)

## Installation

Yarn:

```bash
yarn add @harryy/rehttp
```

NPM:

```bash
npm install @harryy/rehttp
```

## Usage

```tsx
import React from 'react'

import { useReHttp } from 'rehttp'

const Example: React.FC = () => {
const {data, refetch, loading} = useReHttp({
url: 'https://jsonplaceholder.typicode.com/posts/1'
})
if (loading) {
return <>Loading...>
}
return (
<>
{data.title}
refetch()}>Refetch
>
)
}
```

## API

##### `const {data, response, error, loading, execute, isRequestInFlight, cached} = useReHttp(request, options?)`

By default, request will be fired if `lazy: true` is not passed as an option.

`data` contains json serialized data

`response` contains the raw response from the server

`error` contains the error if any

`loading` is `true` only when there is no data or error

`isRequestInFlight` tells whether the request is in flight or not

`execute` can be called with optional `request` parameters to refetch data again

`cached` gives the cached object if the request was cached earlier

```tsx
import React from 'react'
import { useReHttp, ReHttpRequest, ReHttpResponse } from 'rehttp'

interface Post {
id: string,
title: string,
}
interface PostError {
message: string,
status: 'NOTOK',
}

useReHttp({
method: 'GET', // Optional, type: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT', default: 'GET'
url: 'https://jsonplaceholder.typicode.com/posts', // Optional, type: string, default: ''
headers: {
Accept: 'application/json'
}, // Optional, type: Record, default: undefined
params: {
page: 1,
per_page: 5,
tags: ['hello', 'world']
}, // Optional, type: Record>, default: undefined
body: undefined // Optional, type: any, default: undefined
}, {
transformError: async (e) => {
return {
status: 'NOTOK',
message: e.message
}
}, // Optional, type: (data: any) => Promise, default: undefined
transformResponse: async (data: any, response: ReHttpResponse) => {
if (data.id && response.status === 200) {
return {
id: data.id,
title: data.title.toUpperCase()
}
} else {
return Promise.reject(new Error('Post has no id'))
}
}, // Optional, type: (data: any, response: ReHttpResponse) => Promise, default: undefined
transformRequest: async (res: ReHttpRequest) => {
const token = await SomeAsyncStorageOrApiOrWhatever().token
return {
...res,
params: {
foo: 'bar',
},
headers: {
Authorization: `Bearer ${token}`
}
}
}, // Optional, type: (data: ReHttpRequest) => Promise, default: undefined
lazy: true, // Optional, type: boolean, default: false
noCache: true, // Optional, type: boolean, default: false
});
```

##### Need to use in class component? No Problem!

```tsx
import React from 'react'
import { ReHttp, ReHttpProps } from 'rehttp'

interface Post {
id: string,
title: string,
}
interface PostError {
message: string,
status: 'NOTOK',
}

class MyComponent extends React.Component {
reHttpProps: Omit, 'children'> = {
method: 'GET', // Optional, type: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT', default: 'GET'
url: 'https://jsonplaceholder.typicode.com/posts', // Optional, type: string, default: ''
headers: {
Accept: 'application/json'
}, // Optional, type: Record, default: { Accept: 'application/json', 'Content-Type': 'application/json' }
params: {
page: 1,
per_page: 5,
tags: ['hello', 'world']
}, // Optional, type: Record>, default: undefined
body: undefined, // Optional, type: any, default: undefined
onRequest: () => {
showLoader()
}, //Optional, type: (data: ReHttpRequest) => Promise
onResponse: () => {
showSuccess('request success')
}, //Optional, type: (data: Post, response: ReHttpResponse) => Promise
onError: (error) => {
showAlert(error.message)
}, // Optional, type: (error: PostError) => Promise

transformError: async (e) => {
return {
status: 'NOTOK',
message: e.message
}
}, // Optional, type: (data: any) => Promise, default: undefined
transformResponse: async (data: any, response: ReHttpResponse) => {
if (data.id && response.status === 200) {
return {
id: data.id,
title: data.title.toUpperCase()
}
} else {
return Promise.reject(new Error('Post has no id'))
}
}, // Optional, type: (data: any, response: ReHttpResponse) => Promise, default: undefined
transformRequest: async (res: ReHttpRequest) => {
const token = await SomeAsyncStorageOrApiOrWhatever().token
return {
...res,
params: {
foo: 'bar',
},
headers: {
Authorization: `Bearer ${token}`
}
}
}, // Optional, type: (data: ReHttpRequest) => Promise, default: undefined
lazy: true, // Optional, type: boolean, default: false
noCache: true, // Optional, type: boolean, default: false
}
render() {
{...this.reHttpProps}>
{
({data, refetch}) => (
<>
{data.title}
refetch()}>Refetch
>
)

}
}
```

##### Need to set options globally? No problem!

#### `ReHttpProvider`

```tsx
import React from 'react'

import { ReHttpProvider, ReHttpProviderProps, ReHttpRequest, ReHttpResponse, InMemoryAdapter } from 'rehttp'

const App: React.FC = () => {
const options: ReHttpProviderProps = {
cacheAdapter: new InMemoryAdapter({ttl: 5 * 60 * 1000, size: 50}), // Optional, type: CacheAdapter, params: {ttl?: 5 * 60* 1000, size?: 50}?, ttl is in milliseconds
cacheMethods: ['GET'], // Optional, type: Array, default: ['GET'], http methods that needs to be cached
baseUrl: 'https://jsonplaceholder.typicode.com', // Optional, type: string
method: 'GET', // Optional, type: 'DELETE' | 'GET' | 'PATCH' | 'POST' | 'PUT'
params: {}, // Optional, type: Record>
headers: {}, // Optional, type: Record
onRequest: () => {
showLoader()
}, //Optional, type: (data: ReHttpRequest) => Promise
onResponse: () => {
showSuccess('request success')
}, //Optional, type: (data: any, response: ReHttpResponse) => Promise
onError: (error) => {
showAlert(error.message)
}, // Optional, type: (error: any) => Promise
onComplete: (dataOrError, response) => {
hideLoader()
}, // Optional, type: (dataOrError: any, response?: ReHttpResponse) => Promise
transformError: async (e) => {
return {
status: 'NOTOK',
message: e.message
}
}, // Optional, type: (data: any) => Promise, default: undefined
transformResponse: async (data: any, response: ReHttpResponse) => {
if (data.id && response.status === 200) {
return {
id: data.id,
title: data.title.toUpperCase()
}
} else {
return Promise.reject(new Error('Post has no id'))
}
}, // Optional, type: (data: any, response: ReHttpResponse) => Promise, default: undefined
transformRequest: async (res: ReHttpRequest) => {
const token = await SomeAsyncStorageOrApiOrWhatever().token
return {
...res,
params: {
foo: 'bar',
},
headers: {
Authorization: `Bearer ${token}`
}
}
}, // Optional, type: (data: ReHttpRequest) => Promise, default: undefined
lazy: true, // Optional, type: boolean
}
return (



)
}
```

##### Need to use it outside of react context (like redux thunk etc.) and still use context values? No Problem!

#### `reHttpInstance`

```tsx
import React from 'react'

import { reHttpInstance } from 'rehttp'

reHttpInstance({
url: 'https://jsonplaceholder.typicode.com'
}).then(res => {
console.log('Response from ReHttp', res)
}) // option lazy: true will have no effect here

const MyComponent: React.FC = () => {
return

Hello World!

}
```

## License

MIT © [harryy2510](https://github.com/harryy2510)