T8 SDK Factory

Custom request handler

As shown above, the RequestService constructor takes a custom request handler as a parameter. Internal independence of RequestService from a fixed built-in request handler allows to handle requests of all sorts and environments (the browser or node) without locking in with a certain approach to handling requests.

Here's an example of a basic JSON request handler that can be passed to RequestService:

import {
  RequestHandler,
  RequestError,
  RequestService,
  getRequestAction,
  toStringValueMap,
} from "@t8/sdk-factory";
import type { APISchema } from "./APISchema";

const getRequestHandler(endpoint: string): RequestHandler {
  return function(target, request) {
    let { method, url } = getRequestAction({ request, target, endpoint });

    let response = await fetch(url, {
      method,
      headers: toStringValueMap(request?.headers),
      body: request?.body ? JSON.stringify(request?.body) : null,
    });

    let { ok, status, statusText } = response;

    if (!ok) {
      throw new RequestError({
        status,
        statusText,
      });
    }

    try {
      return {
        ok,
        status,
        statusText,
        body: await response.json(),
      };
    }
    catch (error) {
      throw new RequestError(error);
    }
  };
}

export const serverService = new RequestService<APISchema>(
  getRequestHandler("https://api.example.com")
);

// Assuming that the given API is proxied by the server to
// the browser via `/api`
export const browserService = new RequestService<APISchema>(
  getRequestHandler("/api")
);

To meet the needs of a specific use case, the request handler's code can certainly depart from the example above (which is the primary reason why it's not hardwired into the package).