Skip to content

Repository files navigation

@edgefirst-dev/api-client

The APIClient class provides a flexible and extensible HTTP client for making API requests. It supports common HTTP methods (GET, POST, PUT, PATCH, DELETE) and allows customization of the request and response handling through the before and after interceptor hooks.

Installation

bun add @edgefirst-dev/api-client

Usage

Import the APIClient and create a new instance to make API requests.

import{APIClient}from"@edgefirst-dev/api-client";letclient=newAPIClient("https://api.example.com");letresponse=awaitclient.get("/users/1");

Customization

You can customize the request and response handling by extending the APIClient class and overriding the before and after methods.

classCustomAPIClientextendsAPIClient{asyncbefore(request: Request){// Add a custom header to the requestrequest.headers.set("X-Custom-Header","value");returnrequest;}asyncafter(request: Request,response: Response){if(response.status===401){// Handle unauthorized errorthrownewError("Unauthorized");}returnresponse;}}letclient=newCustomAPIClient("https://api.example.com");letresponse=awaitclient.get("/users/1");

You can also define custom methods in the subclass to encapsulate common API calls.

import{ObjectParser}from"@edgefirst-dev/data/parser";classCustomAPIClientextendsAPIClient{asyncfetchUserData(id: number){letresponse=awaitthis.get(`/users/${id}`);letdata=awaitresponse.json();returnnewObjectParser(data);}}letclient=newCustomAPIClient("https://api.example.com");letuser=awaitclient.fetchUserData(1);letuserName=user.string("name");

By overriding the constructor, you can provide a default base URL.

classCustomAPIClientextendsAPIClient{constructor(){super("https://api.example.com");}}letclient=newCustomAPIClient();

Interceptos

You can add interceptors to the APIClient instance to customize the request and response handling.

letclient=newAPIClient("https://api.example.com");client.interceptors.before.on(async(request)=>{// Add a custom header to the requestrequest.headers.set("X-Custom-Header","value");returnrequest;});client.interceptors.after.on(async(request,response)=>{if(response.status===401){// Handle unauthorized errorthrownewError("Unauthorized");}returnresponse;});

You can also remove interceptors using the off method.

asyncfunctionbeforeInterceptor(request){// Add a custom header to the requestrequest.headers.set("X-Custom-Header","value");returnrequest;}letclient=newAPIClient("https://api.example.com");client.interceptors.before.on(beforeInterceptor);// Add the interceptorclient.interceptors.before.off(beforeInterceptor);// Remove the interceptor

The sub-class interceptors run before the instance interceptors.

classCustomAPIClientextendsAPIClient{asyncbefore(request: Request){// Add a custom header to the requestrequest.headers.set("X-Custom-Header","1");returnrequest;}}letclient=newCustomAPIClient("https://api.example.com");client.interceptors.before.on(async(request)=>{// Add a custom header to the requestrequest.headers.set("X-Custom-Header","2");returnrequest;});

Here the X-Custom-Header will be set to 2 in the request because the instance interceptor overrides the header set by the sub-class interceptor.

Testing

You can easily test your API calls using the APIClient with msw to mock the API responses.

import{http,HttpResponse}from"msw";import{setupServer}from"msw/native";// or "msw/node" or "msw/browser"letserver=setupServer(http.get("https://api.example.com/users/1",(req,res,ctx)=>{returnres(ctx.json({id: 1,name: "John Doe"}));}));server.listen();letclient=newAPIClient("https://api.example.com");letresponse=awaitclient.get("/users/1");letdata=awaitresponse.json();// { id: 1, name: "John Doe" }

Error Handling

The APIClient class never throws an error except for network errors. You can handle API errors by checking the response status code.

letclient=newAPIClient("https://api.example.com");try{letresponse=awaitclient.get("/users/1");if(response.status===401){// Handle unauthorized errorthrownewError("Unauthorized");}// Handle other errors or success}catch(error){// Handle network errorconsole.error(error);}

Alternatively, you can use the after interceptor to handle common API errors.

classCustomAPIClientextendsAPIClient{asyncafter(request: Request,response: Response){if(response.status===401){// Handle unauthorized errorthrownewError("Unauthorized");}returnresponse;}}

Or you can use the on method to add an interceptor to handle common API errors.

letclient=newAPIClient("https://api.example.com");client.interceptors.after.on(async(_,response)=>{if(response.status===401){// Handle unauthorized errorthrownewError("Unauthorized");}returnresponse;});

Timeout

You can set a timeout for the API requests using the signal option.

letclient=newAPIClient("https://api.example.com");awaitclient.get("/users/1",{signal: AbortSignal.timeout(5000)});

License

See LICENSE

Author

About

A basic HTTP client for making API requests

Resources

Contributing

Stars

8 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages

Generated from edgefirst-dev/package