Skip to content

API improvements

Michał Grabowski edited this page Mar 28, 2022 · 5 revisions

Problems

  • no TypeScript types available
  • makeUrl does not handle :args inside URL
  • sessionPreconditioner / sessionPostconditioner must be included in the configuration, thus creating coupling between ORM and API layers
  • raw adapter does not work in an intuitive way
  • there's no way of specifying required / optional parameters (path / query)
  • coalescing multiple identical requests
  • snakeCase, camelCase and kebabCase compatibility

Solutions

no TypeScript types available

Need to write code generator (say, as a NPM binary script). npx run gen-api-types config.js should generate the following:

type CreateActionRequest = {
  p1: string;
  p2: {
    a1: number;
    b2: number[];
  };
};

export type <ThisModuleName>API = {
  /**
   * See config.ts line 124 for details.
   */
  readAction: (id: string, params: { p1: string; p2?: number }) => Promise<void>;

  /**
   * See config.ts, line 345 for details.
   */
  createAction: (params: CreateActionRequest) => Promise<void>;
};

makeUrl does not handle :args inside URL

makeUrl needs to be extended (for each operation template). New implementations should analyse the url option, and extract any placeholder parameters to an array/set. At the moment of call, it should replace every occurrences of found parameters with values. The id parameter should be treated separately (because it's either the first parameter, or an attribute of the args parameter bag.

This logic should be placed inside src/operations.ts.

sessionPreconditioner / sessionPostconditioner must be included in the configuration, thus creating coupling between ORM and API layers

Need to decouple API and ORM layers by replacing session{Pre|Post}conditioner with evens (use EventEmitter). I.e. actions should emit those events, and application code should register event handlers.

In the future, it can be improved even more, by automatically registering event handlers for certain actions, based on OpenAPI/AsyncAPI schemas.

raw adapter does not work in an intuitive way

This is another coupling point between ORM and API that needs to be refactored. Adapters should have the following signature.

type AdapterFunc = (response: Response) => void;

and be called inside actionFunc in the following way

if (shouldUpdateStore) {
  requestSucceeded(response.body, operation, params);
}