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

@ltipton/useapi

v0.2.1

Published

React Hooks library for calling APIs

Downloads

6

Readme

Build Client API

  • Generates hooks to make API calls based on a passed in Api Options
  • Allows defining a simple model for a group of endpoints to generate the hooks

Api Options

  • The Options are split into two parts queries and mutations
  • With each, a route-model should be defined for each individual endpoint

Query Endpoints

  • All query endpoints should be defined under queries property
  • All endpoints defined within the queries property will make a get request
    • The get request is hard coded, and currently can not be changed

Mutation Endpoints

  • All mutation endpoints should be defined under mutations property
  • Mutation endpoints can make request of the following types
    • post, patch, put, delete
  • Other than the delete methods, each mutation hook accepts a payload object
    • The payload object should include the body content of the request

Route model

  • Both queries and mutations are defined by a route-model
  • A route-model is defined by the following properties
    • method - The HTTP verb to use when making the request
    • route - The request url path name, i.e. /strategies/23/pillars
      • Can be a string or function
      • As a function, it will be called with the Hook Options passed to the calling hook
    • payload - Used as the body of the request for mutations only
    • onError - Callback called when an error is thrown durning the request
    • onSuccess - Callback called when a request is successful
    • onBefore - Callback called before a request is made
      • Useful for validating the payload of a mutation
      • If this callback throws an error, it will be caught
      • All caught errors will skip the request and be passed to the onError callback as a NetworkError
      • If this callback returns false, a generic error will be throw
      • The callback should return anything other than false to not throw an error
    • onUnMount - Callback called when a get request is made and the calling Component unmounts
      • Useful for cleaning up local state when desired

Api Options Example

const endpointHooks = buildApiClient({
  queries: {
    getAll: {
      // Will use 'get' regardless of what is defined here
      method: `get`,
      route: `/api/endpoint/pathname`,
      // Called when the parent component is unmounted
      onUnMount: () => {},
      // Called when a error is thrown durning a request
      // This includes errors in the `onBefore` callback
      onError: (error: any) => {},
      // Called when a request is successful
      onSuccess: <T>(result: T) => {},
    },
    get: {
      method: `get`,
      // The route as a function
      route: (data: HookMethodOptions) => `/endpoint/${data.payload.id}`,
      // Callback methods are not required
    },
  },
  mutations: {
    create: {
      // Can be any mutation HTTP verb - post, put, patch, delete
      method: 'post',
      // Accepts all the same arguments as queries
      // The `onUnMount` callback is ignored for all mutations
    },
  },
})

Api Client Hooks

  • The buildApiClient method returns an object with properties matching the passed in Api Options object
  • It is split into two parts queries and mutations same as the Api Options object
  • Within both the queries and mutations properties are React Hook functions
    • These are real hooks and follow all the same rules as normal react hooks
    • They must be called within the body of a Function Component
    • They can NOT be called conditionally
  • These hooks use closures
    • This allows them to maintain access to the Api Options object originally passed when they were being built
    • This allows defining properties and logic for an API request in a single location, and then reusing it where needed
  • It is recommended to export the hooks built from the buildApiClient method using the use prefix
    • This is the same pattern used by react, let others know it is a hook, and not regular function
    • For example:
      • If I have a hook called getItem
      • I would export it as useItem

Hooks Example

  • Given the same endpointHooks as defined in the above example
  • The buildApiClient method would return the following object
const endpointHooks = {
  queries: {
    // Contains references to the queries.get route-model above
    get: useQuery,
    // Contains references to the queries.getAll route-model above
    getAll: useQuery,
  }
  mutations: {
    // Contains references to the mutations.create route-model above
    create: useMutation,
  }
}

Query Hooks

  • The useQuery hook is built internally when the buildApiClient method is called
  • All route-model defined in the queries property of the Api Options will be converted into a useQuery hook
  • These hooks can be access from the queries property of the response of the buildApiClient method call
    • For example:
      • Given I pass the following Api Options object => { queries: { get: { ...<route-model> }}}
      • I can access the hook for the get hook in the response from buildApiClient at response.queries.get
  • Unlike the mutation hooks, the request made by the useQuery hook are initiated immediately

Query Hook Options

  • This hook accepts an options object with the similar properties as in the initial Api Options object route-model
  • Properties in this object will impact original route-model properties in the following ways
    • payload => Is merged with the original payload
    • onBefore | onSuccess | onError | onUnMount => Will overwrite the original method
      • These methods can be defined inline without the need for memoization
      • The onUnMount callback exists for mutations only
    • route => When route is a function, the options object will be passed as the first argument
  • Aside from the above properties, the options object has the following
    • enabled - If false, the API call will be by-passed
    • cache - If true, the response will be cached. Future calls will use the cached response until cleared
      • Cache exists for queries only
    • apiOptions - Object passed on to the axios client
      • mapper? - (item: Record<string, any>[]) => any[]
      • config? - AxiosRequestConfig from the axios library

Query Hook Response

  • The hook response contains the following properties
    • loading - Is true when the API request is in flight
    • data - The API client response. Is undefined until a successful API call is made
    • error - Network Error response. Is undefined until an error is thrown, or the API call fails
    • clearCache - Clears the cache for the specific API call
    • getCache - Returns the cached response for the specific API call

Mutation Hooks

  • The useMutation hook is built internally when the buildApiClient method is called
  • All route-model defined in the mutations property of the Api Options will be converted into a useMutation hook
  • These hooks can be access from the mutations property of the response of the buildApiClient method call
    • For example:
      • Given I pass the following Api Options object => { mutations: { post: { ...<route-model> }}}
      • I can access the hook for the post hook in the response from buildApiClient at response.mutations.post
  • Unlike the query hooks, the request made by the mutation hook are NOT immediately initiated
    • Instead they return a useMutation hook that must be called to initiate the API call

Mutation Hook Options

  • This hook accepts an options object with the similar properties as in the initial Api Options object route-model
  • Properties in this object will impact original route-model properties in the following ways
    • payload => Is merged with the original payload
    • onBefore | onSuccess | onError | onUnMount => Will overwrite the original method
      • These methods can be defined inline without the need for memoization
      • The onUnMount callback exists for mutations only
    • route => When route is a function, the options object will be passed as the first argument
  • Aside from the above properties, the options object has the following
    • enabled - If false, the API call will be by-passed
    • apiOptions - Object passed on to the axios client
      • mapper? - (item: Record<string, any>[]) => any[]
      • config? - AxiosRequestConfig from the axios library

Mutation Hook Response

  • The hook response contains the following properties
    • loading - Is true when the API request is in flight
    • data - The API client response. Is undefined until a successful API call is made
    • error - Network Error response. Is undefined until an error is thrown, or the API call fails
    • useMutate - Hook that will make the actual API request
      • Mutation hooks are not called immediately in the way that query hooks are
      • Instead this useMutation hook is returned and that must be called to initiate the API call