UNPKG

@casipe/react-service-provider

Version:
167 lines (132 loc) 4.25 kB
# react-lib-chat-front _aka react-service-provider_ Service Provider is an asynchronous resource to an application make requests to APIs, these providers also manage the requests, retrying failed requests, and also provide a local storage cache. The application will able to do any HTTP request and navigate to other resources without lose these request. - Retry failed request by number of retries - Retry failed request by timeout - Cache with TTL - Use Observables ## Installation `npm install --save-dev @casipe/react-service-provider@latest` ## Pipeline status by branch ### publish-legacy N/A ### publish [![Build Status](https://dev.azure.com/albatross-getnet/Libraries/_apis/build/status/react-lib-chat-front?repoName=react-lib-chat-front&branchName=publish)](https://dev.azure.com/albatross-getnet/Libraries/_build/latest?definitionId=1874&repoName=react-lib-chat-front&branchName=publish) ### publish-next N/A --- ## Usage Custom service class ```js import { Service } from '@casipe/react-service-provider' class FooService extends Service { // config service behavior public requestConfig = { retriesTimeout: 1000, retryDelay: 200 } observableBased() { return this.request({ url: this.params.API_URL_FOO, headers: { key: this.getProp('key') // prop of ServiceProvider } }) } promiseBased() { return this.requestAsync({ url: this.params.API_URL_FOO, headers: { key: this.getProp('key') // prop of ServiceProvider } }) } } ``` ```jsx // App.jsx import { ServiceProvider } from '@casipe/react-service-provider' import { useConfig } from '@casipe/react-app-context' const services = [FooService] => { const appContextConfig = getConfig() const token = '<TOKEN>' return ( <ServiceProvider services={services} authorizationToken={token} config={appContextConfig}> <Component /> </ServiceProvider> ) } ``` ```jsx import { useObservable, useServices } from '@casipe/react-service-provider' export const Component = () => { const [fooService] = useServices(FooService) const [foo, setFoo] = useRequest<FruitInterface[]>([]) useEffect(() => { const subscriber = fooService.observableBased().subscribe( response => { setFoo(response) }) return () => { subscriber.unsubscribe() } }, []) return ( <div> {foo.isCached && 'CACHED'} {foo.error && <h1>{list.error?.message}</h1>} {foo.isLoading && <div>...loading</div>} {!foo.isLoading && list.data && ( <div>{foo.data?.map(fruitItemComponent)}</div> )} </div> ) } ``` # Connect to web socket ## SocketIO Configuration ```tsx const App: FC = () => { const config = useConfig() const socketIo: SocketIOConfigInterface = { url: config.SOCKETIO_URL, namespaces: [USER_ID_FROM_TOKEN, MERCHANT_ID_FROM_TOKEN], socketIoOptions: { extraHeaders: { hello: 'message', Authorization: TOKEN_FROM_SESSION } } } return ( <ServiceProvider config={config} services={[ChatService]} socketIo={socketIo} // SocketIOConfigInterface authorizationToken={TOKEN_FROM_SESSION} >{...}</ServiceProvider> ) } ``` ## Usage - This example's about an incoming chat message from WebSocket - The WS service doesn't send messages through socket just receive - Send request through REST - Wait response through websocket ```ts // services/ChatService.ts export interface ChatPayloadInterface { message: string } export class ChatService extends Service<DemoAppParams> { private chatSubject = new ReplaySubject<string>(Infinity) public chat$ = this.chatSubject.asObservable() public init() { this.socket<ChatPayloadInterface>('chat') .pipe(map((message) => message.payload.message)) .subscribe(this.chatSubject) } } ``` ## Solutions 1. Messages to user and user groups, is posted to a namespace, configure these namespaces on SocketIOConfigInterface object. 2. Use action to identify behavior in service 3. Use payload to identify a document inside the application 4. When you expect a message for a specific job, use the jobId method to control this flow, see an example in the [demo](./demo/services/ImageService.ts)