5.0.1 • Published 4 months ago

@gruzf/request v5.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
4 months ago

GRUZF Request

Version Company

This library is designed to create HTTP requests.

GRUZF Request is written in typescript and support the NextJS library. Thanks to middleware, you can bypass cors and protect requests by XSRF.

Install

npm install @gruzf/request

or

yarn add @gruzf/request

Usage

DataSourse

import { Request, RequestGroup, Methods } from "@gruzf/request/RequestClass";

class City extends RequestGroup {
  constructor() {
    super({
      prefix: "city",
    });
  }

  async update({ put }: Methods<{ custom: string }>) {
    return await put("/update");
  }
}

const groups = { city: new City() };

export class MyAPI extends Request<typeof groups> {
  constructor() {
    super({
      baseURL: "https://myapi.com",
      groups,
    });
  }

  async getUser({ get }: Methods) {
    return await get("/get-user");
  }

  // the variables will be automatically passed to the query,
  // but you can still get them
  async addUser({ post }: Methods<{ name: string }>, variables, req) {
    return await post("/add-user");
  }
}

export default MyAPI;

RequestClass API

baseURL
  • Type: string
  • Default: undefined

Request URL

headers
  • Type: object
  • Default: undefined

Request headers

initData
  • Type: AxiosRequestConfig['params'] | AxiosRequestConfig['data']
  • Default: undefined

Initial data that is added to each request

proxy
  • Type: AxiosRequestConfig['proxy']
  • Default: undefined

Proxy settings

bodyToSearchParams
  • Type: boolean
  • Default: false

Transform body data to Search Params

refreshTokenEndpointUrl
  • Type: string
  • Default: undefined

If you are using refreshTokens, you can add an endpoint for auto-refresh when you get a 401 status code

:warning: Only available if you pass refreshTokens via cookies

refreshTokenEndpoint = "/auth/refresh";
refreshTokenEndpointUrlExclude
  • Type: [string]
  • Default: undefined

Use this to avoid unwanted triggers

refreshTokenEndpoint = ["/auth/login"];
refreshTokenEndpointMethod
  • Type: get | post
  • Default: post
refreshTokenRefresnName
  • Type: string
  • Default: refreshToken
refreshTokenAccessName
  • Type: string
  • Default: accessToken
encodeBody(variables)

You can write your own method to transform body

encodeBody(variables) {
    return variables;
}
setInstance(axios)

You can configure an axios instance yourself

setInstance(axios) {
  axios.interceptors.response.use((response) => {
    return response;
  });
}
...other

All other axios options

RequestGroupClass API

prefix

  • Type: string
  • Default: undefined

You can specify a prefix that will be inserted at the beginning of each request of this group

// without prefix
async update({ get }) {
  return await get("/id"); // -> https://myapi.com/id
}

// with prefix "city"
async update({ get }) {
  return await get("/id"); // -> https://myapi.com/city/id
}

Create api route (optional)

If you are using NextJS it is recommended to use middleware. Create new file pages/api/request.js. You can change the page name by REQUEST_PAGE environment variable.

import middleware from "@gruzf/request/middleware";
import MyAPI from "./datasourse/MyAPI";
import MyAPI2 from "./datasourse/MyAPI2";

export const config = {
  api: {
    bodyParser: false,
  },
};

const myApi = new MyAPI();
const myApi2 = new MyAPI2();

const handler = middleware({ myApi, myApi2 }, { withCredentials: true });

export default handler;

// if you are using TypeScript
// or "@gruzf/request"
// or "@gruzf/request/setup"
// or "@gruzf/request/hook"
declare module "@gruzf/request" {
  interface QueryOverrides {
    myApi: typeof myApi;
    myApi2: typeof myApi2;
  }
}

Create request

Using NestJS middleware

From @gruzf/request
import request from "@gruzf/request";

const users = await request("myApi")("getUser");
const response = await request("myApi")("addUser", { name: "Jhon", age: 23 });

// if you used groups, then the format looks like "group:method"
const cityResponse = await request("myApi")("city:update");
From @gruzf/request/setup

You can configure an axios instance yourself

import setup from "@gruzf/request/setup";

const request = setup({ withCredentials: true }, (axios) => {});

const users = await request("myApi")("getUser");
const response = await request("myApi")("addUser", { name: "Jhon", age: 23 });

// if you used groups, then the format looks like "group:method"
const cityResponse = await request("myApi")("city:update");
From @gruzf/request/hook

In addition to configuring your own axios instance, you can also get the loading status of your request.

import { setup } from "@gruzf/request/hook";
// or without global setting
// import { useRequest } from "@gruzf/request/hook";

const { useRequest } = setup({ withCredentials: true }, (axios) => {});

const [{ loading }, request] = useRequest();

const users = await request("myApi")("getUser");
const response = await request("myApi")("addUser", { name: "Jhon", age: 23 });

// if you used groups, then the format looks like "group:method"
const cityResponse = await request("myApi")("city:update");

Using direct request

import { setup } from "@gruzf/request/direct";
import MyAPI from "./datasourse/MyAPI";

const myApi = new MyAPI();

const request = setup({ myApi });

const users = await request("myApi")("getUser");
const response = await request("myApi")("addUser", { name: "Jhon", age: 23 });

// if you used groups, then the format looks like "group:method"
const cityResponse = await request("myApi")("city:update");
Using useRequest hook
import { setup } from "@gruzf/request/direct/hook";
import MyAPI from "./datasourse/MyAPI";

const myApi = new MyAPI();

const { useRequest } = setup({ myApi });

const [{ loading }, request] = useRequest();

const users = await request("myApi")("getUser");
const response = await request("myApi")("addUser", { name: "Jhon", age: 23 });

// if you used groups, then the format looks like "group:method"
const cityResponse = await request("myApi")("city:update");

REST request

If you have a REST API, you can use just one "rest" instead of multiple methods, which will return get, getAll, put, patch and del ("delete" is reserved)

Using direct request

import { Request } from "@gruzf/request/RequestClass";

class MyAPI extends Request {

  ...

  users({ rest }, variables) {
    return rest("/users", variables);
  }

  ...

}

const myApi = new MyAPI();

const request = setup({ myApi });

await request("myApi")("users", params).get(id); // GET /users/{id}
await request("myApi")("users", params).getAll(); // GET /users
await request("myApi")("users", params).post(); // POST /users
await request("myApi")("users", params).put(id); // PUT /users/{id}
await request("myApi")("users", params).patch(id); // PATCH /users/{id}
await request("myApi")("users", params).del(id); // DELETE /users/{id}

Using NestJS middleware

import { Request } from "@gruzf/request/RequestClass";

class MyAPI extends Request {

  ...

  // it is very important to use the "_" prefix for rest methods via NestJS middleware
  _users({ rest }, variables) {
    return rest("/users");
  }

  ...

}

import request from '@gruzf/request'

await request("myApi")("_users", params)("get", id); // GET /users/{id}
await request("myApi")("_users", params)("getAll"); // GET /users
await request("myApi")("_users", params)("post"); // POST /users
await request("myApi")("_users", params)("put", id); // PUT /users/{id}
await request("myApi")("_users", params)("patch", id); // PATCH /users/{id}
await request("myApi")("_users", params)("del", id); // DELETE /users/{id}

XSRF Protection

To enable xsrf protection, set SECRET_KEY and REQUEST_KEY environment variables. After that, create a middleware file.

// pages/_middleware.ts

import { NextResponse } from "next/server";
import { setCookeis } from "@gruzf/request/cookies";

export async function middleware() {
  const res = NextResponse.next();

  return setCookeis(res);
}

withAuth (only NextJS)

If you have user authorization implemented, you can use the withAuth middleware to automatically redirect to the login page if the user is not authorized

Using middleware.ts

:warning: If you use refresh tokens, you need to implement Bearer authorization on the api side as well

// pages/_middleware.ts
// middleware.ts (NextJS v12.2)
import { NextRequest, NextResponse } from "next/server";
import { setup } from "@gruzf/request/withAuth";

// get request function from direct setup
const withAuth = setup(request("myApi"), options);

export const middleware = withAuth((req: NextRequest) => {
  return NextResponse.next();
});

// NextJS v12.2
// export const config = {
//   matcher: ["/", "/:path((?!.*\\.(?:\\w)+$|_next\\/image.*).*)"],
// };
Options
method
  • Type: string
  • Default: isAuth
filter
  • Type: (options: any) => boolean
  • Default: (opt) => opt.success
redirect

Use excludePages if you don't want these pages to be redirected

  • Type: { url?: string; status?: number; excludePages?: string[]; }
  • Default: { url: "${process.env.AUTH_APP_URL}/login" }
successRedirectUrl
  • Type: string
  • Default: process.env.NEXT_PUBLIC_APP_URL

Using getServerSideProps

// pages/home.ts
import { setupSsr } from "@gruzf/request/withAuth";

// get request function from direct setup
const withAuth = setupSsr(request("myApi"), options);

export const getServerSideProps = withAuth(async () => {
  return {
    props: {},
  };
});
Options
method
  • Type: string
  • Default: isAuth
filter
  • Type: (options: any) => boolean
  • Default: (opt) => opt.success
redirect

Use excludePages if you don't want these pages to be redirected

  • Type: NextJS Redirect & { excludePages?: string[] }
  • Default: { destination: "/login" }
successRedirectUrl
  • Type: string
  • Default: process.env.NEXT_PUBLIC_APP_URL

Fetch Adapter

Axios has the XMLHTTPRequest adapter installed by default, but you can use native Fetch and keep all the settings

import { Request } from "@gruzf/request/RequestClass";
import fetchAdapter from "@gruzf/request/fetch-adapter";

class MyAPI extends Request {

  ...

  // for any methods
  options = {
    adapter: fetchAdapter,
  };

  // for a specific method
  async getUser({ get }) {
    return await get("/get-user", {}, {
      adapter: fetchAdapter,
    });
  }

  ...

}
6.0.0-beta.30

4 months ago

6.0.0-beta.29

4 months ago

6.0.0-beta.28

4 months ago

6.0.0-beta.27

4 months ago

6.0.0-beta.26

5 months ago

6.0.0-beta.25

5 months ago

6.0.0-beta.24

6 months ago

6.0.0-beta.23

7 months ago

6.0.0-beta.22

10 months ago

6.0.0-beta.21

10 months ago

6.0.0-beta.20

10 months ago

6.0.0-beta.19

11 months ago

6.0.0-beta.15

11 months ago

6.0.0-beta.14

11 months ago

6.0.0-beta.13

11 months ago

6.0.0-beta.12

11 months ago

6.0.0-beta.11

1 year ago

6.0.0-beta.10

1 year ago

6.0.0-beta.18

11 months ago

6.0.0-beta.17

11 months ago

6.0.0-beta.16

11 months ago

6.0.0-beta.7

1 year ago

6.0.0-beta.8

1 year ago

6.0.0-beta.9

1 year ago

6.0.0-beta.3

1 year ago

6.0.0-beta.4

1 year ago

6.0.0-beta.5

1 year ago

6.0.0-beta.6

1 year ago

6.0.0-beta.1

1 year ago

6.0.0-beta.2

1 year ago

5.0.1

1 year ago

5.0.0

1 year ago

5.0.0-beta.8

1 year ago

5.0.0-beta.9

1 year ago

5.0.0-beta.7

1 year ago

5.0.0-beta.11

1 year ago

5.0.0-beta.12

1 year ago

5.0.0-beta.10

1 year ago

5.0.0-beta.15

1 year ago

5.0.0-beta.16

1 year ago

5.0.0-beta.13

1 year ago

5.0.0-beta.14

1 year ago

5.0.0-beta.6

1 year ago

5.0.0-beta.4

1 year ago

5.0.0-beta.5

1 year ago

5.0.0-beta.2

1 year ago

5.0.0-beta.3

1 year ago

5.0.0-beta.1

1 year ago

4.0.5

2 years ago

4.0.4

2 years ago

4.0.6

2 years ago

4.0.1

2 years ago

4.0.0

2 years ago

4.0.3

2 years ago

4.0.2

2 years ago

3.6.15

2 years ago

3.6.14

2 years ago

3.6.13

2 years ago

3.6.12

2 years ago

3.6.17

2 years ago

3.6.16

2 years ago

3.6.2

2 years ago

3.6.1

2 years ago

3.6.0

2 years ago

3.6.6

2 years ago

3.6.5

2 years ago

3.6.4

2 years ago

3.6.3

2 years ago

3.6.9

2 years ago

3.6.8

2 years ago

3.6.7

2 years ago

3.5.36

2 years ago

3.5.35

2 years ago

3.5.34

2 years ago

3.5.33

2 years ago

3.5.39

2 years ago

3.5.38

2 years ago

3.5.37

2 years ago

3.6.11

2 years ago

3.6.10

2 years ago

3.5.40

2 years ago

3.5.14

2 years ago

3.5.19

2 years ago

3.5.18

2 years ago

3.5.17

2 years ago

3.5.16

2 years ago

3.5.15

2 years ago

3.5.25

2 years ago

3.5.24

2 years ago

3.5.23

2 years ago

3.5.22

2 years ago

3.5.21

2 years ago

3.5.20

2 years ago

3.5.29

2 years ago

3.5.28

2 years ago

3.5.27

2 years ago

3.5.26

2 years ago

3.5.32

2 years ago

3.5.31

2 years ago

3.5.30

2 years ago

3.5.13

2 years ago

3.5.12

2 years ago

3.5.11

2 years ago

3.5.10

2 years ago

3.5.7

2 years ago

3.3.9

2 years ago

3.5.6

2 years ago

3.3.8

2 years ago

3.5.5

2 years ago

3.3.7

2 years ago

3.5.4

2 years ago

3.3.6

2 years ago

3.5.9

2 years ago

3.5.8

2 years ago

3.4.0

2 years ago

3.3.10

2 years ago

3.3.11

2 years ago

3.5.3

2 years ago

3.3.5

2 years ago

3.5.2

2 years ago

3.3.4

2 years ago

3.5.1

2 years ago

3.5.0

2 years ago

3.2.9

2 years ago

3.2.8

2 years ago

3.2.7

2 years ago

3.3.1

2 years ago

3.2.2

2 years ago

3.3.0

2 years ago

3.2.1

2 years ago

3.2.0

2 years ago

3.0.2

2 years ago

3.1.0

2 years ago

3.0.1

2 years ago

3.2.6

2 years ago

3.2.5

2 years ago

3.3.3

2 years ago

3.2.4

2 years ago

3.3.2

2 years ago

3.2.3

2 years ago

3.0.0

2 years ago

2.1.6

2 years ago

2.1.2

3 years ago

2.0.3

3 years ago

2.1.1

3 years ago

2.0.2

3 years ago

2.1.4

3 years ago

2.1.3

3 years ago

2.0.4

3 years ago

2.1.5

3 years ago

2.1.0

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.5.0

3 years ago

1.4.0

3 years ago

1.3.5

3 years ago

1.3.4

3 years ago

1.3.3

3 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.3.0

3 years ago

1.2.0

3 years ago

1.1.0

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago