npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

castelapi

v1.4.0

Published

a powerful and easy-to-use JavaScript library for managing HTTP requests in your web applications. Designed to simplify interactions with APIs, CastelAPI offers an intuitive interface and advanced features such as error handling, loading indicators, and

Downloads

26

Readme

Introduction

CastelAPI is a lightweight JavaScript library designed to simplify HTTP requests in web applications. It offers a clean and intuitive API for performing CRUD operations, handling loading states, caching responses, and managing retries. Whether you're building a small project or a large-scale application, CastelAPI helps streamline your API interactions. This library is framework-agnostic, so it can be used for both front-end and back-end projects. For front-end applications, it's SSR-friendly and can be used with Nuxt, Next, Nest, etc.

Breaking change in 1.4.0

If you configure your baseUrl, it would alway be apply to your endpoint:

//by default config.baseUrl = ''
const response = await get('https://api.example.com/endpoint') // Works because config.baseUrl is NOT set

//now we configure baseUrl
config.baseUrl = 'https://api.example.com'
const response = await get('https://api.example.com/endpoint')//Doesn't work anymore
const response = await get('/endpoint')//works. Use this instead

New Features

  • [Cache Management]: This version adds two new strategies. You can now change the cache management strategy and use localStorage or sessionStorage for a front-end application. These features include a parser to make life easier for you, and it's still SSR-friendly. If window is not available, this feature won't be enabled. The cache management section has been updated.
  • [TypeScript]: Better type tracking with TypeScript than in the previous version. Some changes in the build. You can now use the power of generic functions :smile: !

Table of Contents

Key Features

  • Simplified HTTP Requests: Easily perform GET, POST, PUT, DELETE, etc., requests.
  • Loading Indicators: Automatically display loading indicators during requests.
  • Caching: Cache request responses to improve your application's performance.
  • Global Configuration: Configure global parameters such as default headers, base URL, and error handlers.
  • Automatic Parser: Auto parser included to parse your data from JSON to plain JavaScript objects, text, boolean, etc.

Installation

You can install CastelAPI via NPM:

npm install castelapi

Usage

Configuration

Configuration is optional. The config object allows you to set global parameters for CastelAPI. Below are the available options:

  • baseUrl: The base URL for all API requests.
  • headers: Default headers to include with every request. Example:
import { apiInstance, config } from 'castelapi'

config.baseUrl = 'https://api.example.com'
config.headers = {
  'Content-Type': 'application/json',
}

Use TypeScript to Keep Track of Types

The following example demonstrates how to use TypeScript with generic functions:

// You can pass a type to the generic function
type User = { id: number; name: string }
const responseC: User = await get<User>('/endpoint')

Here how your IDE will describe this function :

(alias) get<User>(url: string, options?: Options): Promise<ResponseWrapper<User>>
import get
// Fetches data from the specified URL.
// @param url — The endpoint or URL to fetch data from.
// @param options — The request options.
// @returns — - A promise that resolves with the fetched data.
// @throws — {Error} - Throws an error if the request fails.

GET Requests

To make a GET request, use the get function:

import { get } from 'castelapi'

async function fetchData() {
  try {
    const response = await get('https://api.example.com/endpoint')
    console.log(response)
  } catch (error) {
    console.error('Error fetching data:', error)
  }
}

fetchData()

Details:


function get<T>(url: string, options?: Options): Promise<ResponseWrapper<T>>

const response = await get('https://api.example.com/endpoint') // Works
const responseB = await get('/endpoint') // Works if config.baseUrl is set
const { data, status } = await get('/endpoint') // Destructure response from ResponseWrapper type

POST Requests

To make a POST request, use the post function:

import { post } from 'castelapi'

async function createData() {
  try {
    const data = { name: 'John Doe', age: 30 }
    const response = await post('https://api.example.com/users', {
      body: data,
    })
    console.log(response)
  } catch (error) {
    console.error('Error creating data:', error)
  }
}

createData()

function post<T>(url: string, options?: PostOptions): Promise<ResponseWrapper<T>>

PUT Requests

To make a PUT request, use the put function:

async function updateData() {
  try {
    const data = { name: 'John Doe', age: 31 }
    const response = await put('https://api.example.com/users/1', {
      body: data,
    })
    console.log(response)
  } catch (error) {
    console.error('Error updating data:', error)
  }
}

updateData()

DELETE Requests

To make a DELETE request, use the remove function:

import { remove } from 'castelapi'

async function deleteData(id: string) {
  const parameters = new Map()
  parameters.set('id', id)
  try {
    const response = await remove('/endpoint', parameters)
    console.log(response)
  } catch (error) {
    console.error('Error deleting data:', error)
  }
}
const id = '1Ldhio1561dsfdsNUIsd'
deleteData(id)

Loading Management

To monitor the loading state of requests, use the loading function:

import { loading } from 'castelapi'

if (loading()) {
  console.log('Request is loading...')
} else {
  console.log('Request is not loading.')
}

Cache Management

You can use cache to prevent outgoing requests.

import { get } from 'castelapi'

const result = await get('/endpoint', {
  cache: { enabled: true, cacheTime: 3000 },
})
const cachedResult = await get('/endpoint')
setTimeout(async () => {
  // if cache value is expired, the request is made again
  const resultWithoutCache = await get('/endpoint')
}, 4000)

New features: cache strategy management. You can now choose what type of cache to use.

  • instanceCache (Default): It should be used for SPA and back-end apps.
  • localStorageCache: It should be used for front-end applications without SSR like Vue, React. If you want to keep your cache across multiple windows, see: localStorage documentation
  • sessionStorageCache: It should be used for front-end applications without SSR like Vue, React. See: sessionStorage documentation
setCacheStrategy(cacheStrategy: InstanceCache | LocalStorageCache | SessionStorageCache): void
import { get, setCacheStrategy, localStorageCache } from 'castelapi'

setCacheStrategy(localStorageCache)
// Now cache used is localStorage with parser
const result = await get('/endpoint', {
  cache: { enabled: true, cacheTime: 3000 },
})
const cachedResult = await get('/endpoint')
setTimeout(async () => {
  // if cache value is expired, the request is made again
  const resultWithoutCache = await get('/endpoint')
}, 4000)

You can even use one of the three instances if you wish; they implement the cache interface with a parser included. This could be useful if you use localStorage or sessionStorage in your app:

type ResponseWrapper<T> = {
  data: T
  status: number
  url: string
}
type CachedValue<T> = ResponseWrapper<T> && {
  timeStamp: number
}

interface Cache {
  get<T>(key: string): CachedValue<T> | null
  set<T>(key: string, value: T, cacheTime: number): void
  isExpired(cachedResponse: CachedValue): boolean
  clear(): void
  delete(key: string): void
}
import { sessionStorageCache } from 'castelapi'

sessionStorageCache.set('id', { myId: 123 }, 1000)
const cachedValue = sessionStorageCache.get('id')

Retry Management

You can set an option to retry.

import { get } from 'castelapi'

// If the GET request to /endpoint fails, CastelAPI will retry 3 times.
const result = await get('/endpoint', {
  retry: 3,
})

Transforming Responses

You can transform responses before they are returned to your application.

import { config } from 'castelapi'

config.responseInterceptor = function <T>(response: ResponseWrapper<T>): ResponseWrapper<T> {
  response.data = transformData(response.data)
  return response
}

function transformData(data) {
  // Custom transformation logic
  return data
}

Options Type

Here the type option you can pass on:

type Options = {
  retry?: number
  headers?: Partial<Headers> | Record<string, string> | null | undefined
  method?: string
  parameters?: Map<string, any>
  cache?: { enabled: boolean; cacheTime: number }
}

type PostOptions = Options & {
  body?: Record<string, any>
}

Error Handling

CastelAPI throws errors for network issues, server errors, and other request failures. You can catch these errors using try-catch blocks.

Example:

import { get } from 'castelapi'

async function fetchData() {
  try {
    const response = await get('https://api.example.com/endpoint')
    console.log(response)
  } catch (error) {
    if (error instanceof NetworkError) {
      console.error('Network error:', error.message)
    } else if (error instanceof ServerError) {
      console.error('Server error:', error.message)
    } else {
      console.error('Unexpected error:', error)
    }
  }
}

fetchData()

FAQ

How do I handle authentication?

You can set authentication headers in the global configuration.

import { config } from 'castelapi'

config.headers = {
  Authorization: 'Bearer YOUR_API_KEY',
}

Can I use CastelAPI with other libraries like Axios?

yes, but CastelAPI is a standalone library for managing HTTP requests, and it does not depend on Axios or other libraries.

How do I enable CORS?

CORS must be enabled on the server-side. CastelAPI does not handle CORS directly.

For any other questions, feel free to open an issue on GitHub.

Features in progress

-Custom Request Interceptors -timeout config -disable parser with config -disable parser with option -expose parser

Contributions

Contributions are welcome! Here's how you can contribute:

  1. Report Issues: If you find a bug, please open an issue on GitHub.
  2. Suggest Features: If you have an idea for a new feature, please suggest it in the issues section.
  3. Submit Pull Requests: If you'd like to contribute code, please fork the repository and submit a pull request.
  4. Improve Documentation: Help us improve this documentation by suggesting changes or adding more examples.

License

This project is licensed under the MIT License - see the LICENSE file for details.