0.2.2 • Published 2 years ago

@roland1993/api v0.2.2

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

A simple axios wrapper

The purpose of this package is to provide ease of defining and using REST APIs. If you structure backend APIs in a modular way, you might want to use this package.

Installation

Make sure you have axios installed

npm install @roland1993/api

How to use

I am going to describe how I use this package along with creating a modular structure for APIs.

Step1: api folder

Inside src directory of your project, create an api folder. Inside, create an index.js file with the following content:

import axios from 'axios'
import { api } from '@roland1993/api'

// Create your axios instance
const instance = axios.create({
  baseURL: "process.env.API_URL",
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
})

export const defineApi = (url) => api(url, instance)

api function is a factory function that returns an object with methods to make requests. Specifically it returns:

{
  get: (url: string | number = '', config?: AxiosRequestConfig): AxiosPromise,
  post: (data?: any, config?: AxiosRequestConfig): AxiosPromise,
  put: (url: string | number = '', data: any, config?: AxiosRequestConfig): AxiosPromise,
  patch: (url: string | number = '', data: any, config?: AxiosRequestConfig): AxiosPromise
  delete: (url: string | number, config?: AxiosRequestConfig): AxiosPromise
}

In the file above we export a defineApi function which will be used to define APIs. If you use multiple axios instances, it would be useful to name this function related to the instance.

Step2: Modules

Inside api folder, create a modules folder. In this folder we are going to create individual modules for each API.

Let's start by creating a module for /posts API.

modules/posts.js

import { defineApi } from '@api'

const posts = defineApi('/posts')

export const getPosts = () => posts.get()
export const getPost = id => posts.get(id)
export const putPost = (id, data) => posts.put(id, data)

Step3: How to use

You either import the APIs from each file:

import { getPosts } from '@api/modules/posts'

getPosts()
  .then()
  .catch()
  .finally()

or export them in @api/index.js file and import them from there:

@api/index.js

// ...

export * from './modules/posts'

Then you can use it in your app:

import * as request from '@api'

request.getPosts()
  .then()
  .catch()
  .finally()

Typing APIs

Typescript

Typing with typescript is easy. You just pass a generic type to the request method. So the modules/posts.ts will look like this:

import { defineApi } from '@api'

interface Post {
  id: number
  title: string
  body: string
  createdAt: string
}

interface NewPost {
  title: string
  body: string
}

const posts = defineApi('posts')

export const getPosts = () => posts.get<Post[]>()
export const getPost = (id: string) => posts.get<Post>(id)
export const putPost = (id: string, data: NewPost) => posts.put<Post>(id, data)

Javascript

Even if you don't use typescript, you can still type APIs by using JSDoc:

import { defineApi } from '@api'

const posts = defineApi('posts')

/**
 * @typedef Post
 * @property {number} id
 * @property {string} title
 * @property {string} body
 * @property {string} createdAt
 */

/**
 * @typedef NewPost
 * @property {string} title
 * @property {string} body
 */

/**
 * @description GET /posts
 * @returns {AxiosPromise<Post[]>}
 */
export const getPosts = () => posts.get()

/**
 * @description GET /posts/{param}
 * @param {string | number} id
 * @returns {AxiosPromise<Post>}
 */
export const getPost = (id) => posts.get(id)

/**
 * @description PUT /posts/id
 * @param {string | number} id
 * @param {NewPost} data
 * @returns {AxiosPromise<Post>}
 */
export const putPost = (id, data) => posts.put(id, data)

Cancel pending requests

If you want to cancel all pending requests, you can use cancelPendingRequests function:

import { cancelPendingRequests } from '@roland1993/api'

cancelPendingRequests()

Vue 3 usage

If you are using Vue 3, this library exports a useApi function which makes working with APIs easier.

Example:

<script>
import { getPosts } from '@api/modules/posts'
import { useApi } from '@roland1993/api'

export default {
 setup() {
   const { loading, data } = useApi(getPosts)

   return {
     loading,
     data
   }
 }
}
</script>

useApi returns:

  • loading: A boolean ref
  • data: A ref returned by the API from response.data
  • call: A function which will call the API

The first argument passed to useApi is the API function as you can see from the example above. useApi calls the API function immediately. If you don't the want API to be called immediately, you can use pass false as second argument:

<script>
import { getPosts } from '@api/modules/posts'
import { useApi } from '@roland1993/api'

export default {
 setup() {
   const { loading, data, call } = useApi(getPosts, false)

   return {
     loading,
     data,
     call
   }
 }
}
</script>

<template>
  /* ... */
  <button @click="call">Call the API</button>
</template>
0.2.1

2 years ago

0.2.0

2 years ago

0.2.2

2 years ago

0.1.0

3 years ago

0.0.2

3 years ago