1.0.0-beta.2 • Published 3 years ago

@typified-web/request v1.0.0-beta.2

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

@typified-web/request

A tiny request library to provide compile-time type-safe with your API specification.

Features

  • Types for each API calls with simple declarations for API,

    which means:

    • Code completion by API declarations with supported editor (like VSCode).

    • Type validation at compile-time (design-time).

  • Natural API to request resources.

  • Tiny footprint for runtime of browser and NodeJS (about 4kb uncompressed).

Getting Started

Installation via npm:

npm i @typified-web/request

Declare your API. E.g. the GET /greet/:name end point:

type YourAPI = {
  '/greet/:name': {
    get: {
      input: {
        route: {
          name: string;
        };
      };
      output: {
        body: {
          resCode: string;
          result: {
            name: string;
          };
        };
      };
    };
  };
};

Then create your API request client:

import { createRequest } from '@typified-web/request';

// the decorated reuqest function.
export default createRequest<YourAPI>();

If you're using NodeJS, install node-fetch to provide the fetch implementation, like:

import fetch from 'node-fetch';

export default createRequest<YourAPI>({
  fetch: (path, opt) => {
    return fetch(`${host}${path}`, opt);
  },
});

Then, you can use it anywhere you like via import and get auto completion and validation for each request:

import request from './the/newly/created/request';

// send a request.
request.endpoint('/greet/:name').get({ route: { name: 'Jack' } });

Code-completion and type validation works like a charm.

API

The API includes two parts: the API declaration for design-time and the decorated request client for runtime.

API declaration

The API definition is like the Open API specification, but in a more simpler form of typescript declarations.

export type APISpec = {
  // URL or path of the API endpoint.
  [path: string]: {
    // HTTP Methods.
    [M in Method]?: {
      // Request Specification.
      input?: {
        // Path parameters
        route?: PathParameter;
        // Path parameters
        query?: PathParameter;
        // Headers
        headers?: Record<string, string>;
        // Request body.
        body?: Json;
      };
      // Response Specification.
      output: {
        headers?: Record<string, string>;
        body?: Json;
      };
    };
  };
};

The declaration is just for design-time only and will be swiped in runtime. That's why we call it almost zero-overhead.

The request client

To create a request client, you can specify your customized fetch implemenation for easy extention:

import fetch from 'node-fetch';

const request = createRequest<YourAPI>({
  fetch: (path, opt) => {
    return fetch(`${host}${path}`, opt);
  },
});

The request client itself is complicatedly typed as it uses generics massively.

However, the usage is quite simple.

request.endpoint('PATH').method({ params });

The path is the resource key defined in your API specification and method is the supported method(get/post/put/patch/delete) for your endpoint declaration. The parameters will be inferred for you.

Limitations

It just add type declarations to the JSON-like API, which means the input and output are mostly JSON. Anything outside the JSON-like API is not considered well.

Help is welcomed!

License

MIT.