@lcdev/api-service
v0.1.6
Published
Common structure for calling API endpoints
Downloads
7
Keywords
Readme
API Service
A tiny frontend library to help create a "service wrapper" over backend APIs. Helps track API tokens and boilerplate for API responses.
You write an 'AuthManager' class to keep track of the current logged in JWT token.
import { AuthManager, localStorage } from '@lcdev/api-service';
interface JWT { ... } // whatever your JWT contains
export class MyAuthManager extends AuthManager<JWT> {
static async create() {
const manager = new MyAuthManager(
localStorage(), // where to store the token
{
// this is the key that's used in the above functions
tokenKey: 'token-key',
// when to automatically call refresh, in keepAlive
refreshTokenWithinSeconds: 60 * 30,
},
{
async refreshToken(currentToken) {
// call an API, return back the jwt string
},
// optional - any errors trigger this callback
error(err) { ... }
// optional - any 401 errors trigger this callback
unauthorized() { ... }
// optional - when token has expired, this callback is triggered
expiry() { ... }
},
);
return manager.waitUntilReady();
}
}
Your API calling service would look like this.
import { api } from '@lcdev/fetch';
import { ApiResponse, unwrapApiResponse } from '@lcdev/api-service';
export const createCoreApi = (baseURL: string, auth: MyAuthManager) => {
const coreApi = api(baseURL)
.withBearerToken(auth)
// optional - logic to automatically keepAlive after every API request
.onResponse(res => {
if (!/\/auth\//.exec(res.url)) {
auth.keepAlive().catch(() => {});
}
});
// this is an object with calls to all endpoints of your API
return {
async login(username: string, password: string) {
type Response = ApiResponse<ApiData.Token>;
const response = await coreApi
.post('/api/auth/login')
.withBody({ username, password })
.json<Response>();
const { data } = unwrapApiResponse(response);
return data;
},
} as const;
};