Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@airma/restful

Package Overview
Dependencies
Maintainers
0
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@airma/restful

A wrapper for asynchronous http requests with a restful style

  • 18.4.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
16
decreased by-85.96%
Maintainers
0
Weekly downloads
 
Created
Source

npm NPM downloads standard

@airma/restful

Basic usage

Provided a nice way to describe a restful http requests like:

import { client } from '@airma/restful';

const { rest } = client();

const root = rest('/path');

// GET http://host/path
root.get();

// GET http://host/path?param1=param1&param2=param2
root.setParams({ param1:'param1', param2:'param2' }).get();

// GET http://host/path/child-path
root.path('child-path').get();

// GET http://host/path/child-path?param1=param1&param2=param2
root.path('child-path').setParams({ param1:'param1', param2:'param2' }).get();

// POST http://host/path 
// payload: {data:'data'}
root.setBody({data:'data'}).post();

// POST http://host/path/child-path 
// payload: {data:'data'}
root.path('child-path').setBody({data:'data'}).post();

// POST http://host/path/child-path?param1=param1&param2=param2 
// payload: {data:'data'}
root.path('child-path').setParams({ param1:'param1', param2:'param2' }).setBody({data:'data'}).post();

With typescript

import { client, ResponseData } from '@airma/restful';

const { rest } = client();

const root = rest('/path');

type User = {
    id: string;
    name: string;
    username: string;
}

async function getUser(id: string): Promise<User>{
    try{
        return root.setParams({ id }).get<User>();
    } catch(e: any) {
        console.log(e)
    }
}

// if you need details from response, use `response` from `method promise`
async function getUserResponse(id: string): Promise<ResponseData<User>>{
    try{
        // with response
        // when error { isError: true; error: any, networkError: boolean, status: number, headers?: Record<string, any> }
        // when success { isError: false; data: User, status: number, headers: Record<string, any> }
        return root.setParams({ id }).get<User>().response();
    } catch(e: any) {
        console.log(e)
    }
}

Config

The @airma/restful contains a simple default config, it is not enough for you, you can config it:

import { client, ResponseData } from '@airma/restful';

const { rest } = client({
    // request headers
    headers: {...},
    // default params ex { sessionId: 12 } -> http://host/path?sessionId=12&xx=...
    defaultParams: {...},
    // intercept the response data
    responseInterceptor: ( data: ResponseData ) => {console.log(data)},
    // you can replace the default request with your own request method
    async request(url: string, requestConfig: RequestConfig){
        return Promise<ResponseData>;
    }
});

Headers

You can set a headers for the client, and the client always sends request with the headers you set.

client({
    headers:{
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest',
        ......
    }
})

DefaultParams

You can set default params for the requests send by you client. These params always exist in the url, unless you recover them with undefined in the specific request.

const {rest} = client({
    defaultParams:{
        sessionId: 12,
        private:true
    }
});

// http://host/path/child?sessionId=12&private=true&userId=1
rest('/path').path('child').setParams({userId:1}).get<User>();

// http://host/path/child?sessionId=12&userId=1
rest('/path').path('child').setParams({userId:1, private: undefined}).get<User>();

Request

The default request sender is a window.fetch adapter. If you want to replace it with some more good adapter, you can set request.

The Request is a callback, with a url and requestConfig as params, it should returns a promise with a ResponseData type result.

type Request = (
  // request url  
  url: string,
  // requset config
  requestConfig: RequestConfig
) => Promise<ResponseData>; // response data

The RequestConfig type:

type ResponseType =
  | 'json'
  | 'text'
  | 'formData'
  | 'blob'
  | 'arrayBuffer';

// the config you can set to `client`
type RestConfig = {
    // just headers you set to client({headers:...})
  headers?: Record<string, any>;
  // the response data format: json, text, formData, blob, arrayBuffer
  responseType?: ResponseType;
  // just responseInterceptor you set to client({responseInterceptor})
  responseInterceptor?: (
    data: ResponseData
  ) => ResponseData | undefined;
  // just defaultParams you set to client({defaultParams...})
  defaultParams?: Record<string | number, any>;
  // you can provide a param processor to stringify and parse
  // params.
  // type ParamsProcessor = { 
  //   stringify(data:Record<string | number, any>): string,
  //   parse(data: string): Record<string | number, any>
  // }
  paramsProcessor?: () => ParamsProcessor;
  /** the rest config you can refer to window.fetch API **/
  credentials?: 'include' | 'omit' | 'same-origin';
  cache?:
    | 'default'
    | 'force-cache'
    | 'no-cache'
    | 'no-store'
    | 'only-if-cached'
    | 'reload';
  mode?: 'cors' | 'navigate' | 'no-cors' | 'same-origin';
  redirect?: 'error' | 'follow' | 'manual';
  integrity?: string;
  keepalive?: boolean;
  referrer?: string;
  referrerPolicy?:
    | ''
    | 'no-referrer'
    | 'no-referrer-when-downgrade'
    | 'origin'
    | 'origin-when-cross-origin'
    | 'same-origin'
    | 'strict-origin'
    | 'strict-origin-when-cross-origin'
    | 'unsafe-url';
  window?: null;
}

type RequestConfig = RestConfig & {
  // object style for ?param=xxx&more=xxx
  params?: Record<string, any>;
  // object style for post request payload
  body?: Record<string, any>;
  // GET, POST, PUT, DELETE
  method?: Method;
};

The ResponseData type:

export declare type SuccessResponse<T = any> = {
  status: number;
  headers?: Record<string, any>;
  // the final promise result
  data: T;
  // is error request
  isError: false;
};

export declare type ErrorResponse = {
  status: number | null;
  // error data
  error: any;
  // same value with `error`
  data: any;
  headers?: Record<string, any>;
  // is network error
  networkError: boolean;
  // is error request
  isError: true;
};

export declare type ResponseData<T = any> = SuccessResponse<T> | ErrorResponse;

You can replace request with the most popular request tool axios or other request API. And now you should know, that @airma/restful just provides a restful style for you.

ResponseInterceptor

ResponseInterceptor is a callback which helps you intercept a response. You can redefine if the request is an error request, and affect if the rest end should resolve or reject this result. You can also just make a log, and don't change result.

intercept response:

import {client, ResponseData} from '@airma/restful';

// for example we have to judge if the request is success 
// by the `data.success`
const redefinition = (response:ResponseData) :ResponseData =>{
    const {data, status, networkError} = response;
    if ( data && data.success ) {
        return {
            data: data.data,
            status,
            isError: false
        }
    }else {
        return {
            error: data.data,
            data: data.data,
            status,
            networkError,
            isError: true
        }
    }
}

const { rest } = client({
    responseInterceptor: redefinition
})

log response:

import {client, ResponseData} from '@airma/restful';

// the different with redefinition is we should return void,
// if we do not want to change result.
const log = (response:ResponseData): void =>{
    const {data, status} = response;
    console.log(status, data);
}

const { rest } = client({
    responseInterceptor: log
})

paramsProcessor

If you want to keep the default request, but replace a better params processor like qs, you can use this setting.

import { client } from '@airma/restful';
import qs from 'qs';

export default client({
    paramsProcessor(){
        return {
            stringify(data: Record<string | number, any>): string{
                return qs.stringify(data);
            },
            parse(query: string): Record<string | number, any>{
                return qs.parse(query);
            }
        }
    }
})

Change config

Sometimes you want to change rest config when the client has been built. You can use config method from client instance.

import {client} from '@airma/restful';

const {rest, config} = client();

async function test(){
    // http://host/path?id=1
    await rest('/path').setParams({id:1}).get();
    // set a sessionId as a default param
    config(
        c => ({...c, defaultParams: {sessionId: 12} })
    );
    // http://host/path?sessionId=12&id=1
    await rest('/path').setParams({id:1}).get();
}

You can set headers and other config too.

If you want to config a specific request, you should set config to a method.

rest('/path').get({headers:{...}, responseType:'text'});

Response

As we have known, the method get, post, put, delete provides a promise which has a result we need directly. But, sometimes, we need a more original response data with status, headers, networkError properties. So, we can use response from the method returns.

const res = await rest('/path').get<User>().response();
if(!res.isError){
    return res.data; // User type
}
// we can get details now
const {error, networkError, headers} = res;

The response method is a parasitic method in the get, post, put, delete method returning promise. It returns a promise which result is a ResponseData.

Keywords

FAQs

Package last updated on 31 Dec 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc