Aspida

TypeScript friendly HTTP client wrapper for the browser and node.js.

README

aspida


aspida

Features


- Path, URL query, header, body, and response can all specify the type
- FormData / URLSearchParams content can also specify the type
- HTTP client supports axios / fetch / node-fetch


vscode

Procedure


1. Reproduce the endpoint directory structure in the "api" directory
1. Export a Type alias named "Methods"
1. Call "aspida" with npm scripts
1. API type definition file "api/\$api.ts" will be generated, so import the application and make an HTTP request

Getting Started


Installation (axios ver.)


- Using npm:

  sh
  $ npm install aspida @aspida/axios axios
  

- Using Yarn:

  sh
  $ yarn add aspida @aspida/axios axios
  

Create "api" directory


  1. ```sh
  2. $ mkdir api
  3. ```

Type helper DefineMethods


DefineMethods<> is helper type for defining Methods. In earlier aspida, user shuold define without checking for API definition.
If you already have aspida in your projects, you can easily use DefineMethods<> with surrounding your definition.
It is just an option whether to use DefineMethods<>.
Be aware of the limitation that DefineMethods<> can't detect extra meaningless properties.

Create an endpoint type definition file


- GET: /v1/users/?limit={number}
- POST: /v1/users

  api/v1/users/index.ts

  ts
  import type { DefineMethods } from "aspida";

  type User = {
    id: number;
    name: string;
  };

  export type Methods = DefineMethods<{
    get: {
      query?: {
        limit: number;
      };

      resBody: User[];
    };

    post: {
      reqBody: {
        name: string;
      };

      resBody: User;
      /
       reqHeaders(?): ...
       reqFormat: ...
       status: ...
       resHeaders(?): ...
       polymorph: [...]
       */
    };
  }>;
  

- GET: /v1/users/\${userId}
- PUT: /v1/users/\${userId}

  api/v1/users/_userId@number/index.ts

  Specify the type of path variable “userId” starting with underscore with “@number”  
  If not specified with @, the default path variable type is "number | string"

  ts
  import type { DefineMethods } from "aspida";

  type User = {
    id: number;
    name: string;
  };

  export type Methods = DefineMethods<{
    get: {
      resBody: User;
    };

    put: {
      reqBody: {
        name: string;
      };

      resBody: User;
    };
  }>;
  

Build type definition file


package.json

  1. ```json
  2. {
  3.   "scripts": {
  4.     "api:build": "aspida"
  5.   }
  6. }
  7. ```

  1. ```sh
  2. $ npm run api:build

  3. > api/$api.ts was built successfully.
  4. ```

Make HTTP request from application


src/index.ts

  1. ```ts
  2. import aspida from "@aspida/axios";
  3. import api from "../api/$api";
  4. (async () => {
  5.   const userId = 0;
  6.   const limit = 10;
  7.   const client = api(aspida());

  8.   await client.v1.users.post({ body: { name: "taro" } });

  9.   const res = await client.v1.users.get({ query: { limit } });
  10.   console.log(res);
  11.   // req -> GET: /v1/users/?limit=10
  12.   // res -> { status: 200, body: [{ id: 0, name: "taro" }], headers: {...} }

  13.   const user = await client.v1.users._userId(userId).$get();
  14.   console.log(user);
  15.   // req -> GET: /v1/users/0
  16.   // res -> { id: 0, name: "taro" }
  17. })();
  18. ```

aspida official HTTP clients



Command Line Interface Options


Option Type Default Description
--config
-c
string "aspida.config.js" Specify the path to the configuration file.
--watch
-w
Enable watch mode.
Regenerate $api.ts according to
        the increase / decrease of the API endpoint file.
--version
-v
Print aspida version.

Options of aspida.config.js


OptionTypeDefaultDescription
--------------------------------------------------------------------------------------------------------------------
inputstring"api"Specifies
baseURLstring""Specify
trailingSlashbooleanfalseAppend
outputEachDirbooleanfalseGenerate
outputMode"all""normalOnly""aliasOnly"

Node.js API


  1. ```ts
  2. import { version, build, watch } from "aspida/dist/commands";

  3. console.log(version()); // 0.x.y

  4. build();
  5. build("./app/aspida.config.js");
  6. build({ input: "api1" });
  7. build([
  8.   { baseURL: "https://example.com/v1" },
  9.   {
  10.     input: "api2",
  11.     baseURL: "https://example.com/v2",
  12.     trailingSlash: true,
  13.     outputEachDir: true,
  14.     outputMode: "all",
  15.   },
  16. ]);

  17. watch();
  18. watch("./app/aspida.config.js");
  19. watch({ input: "api1" });
  20. watch([
  21.   { baseURL: "https://example.com/v1" },
  22.   {
  23.     input: "api2",
  24.     baseURL: "https://example.com/v2",
  25.     trailingSlash: true,
  26.     outputEachDir: true,
  27.     outputMode: "all",
  28.   },
  29. ]);
  30. ```

Ecosystem


- openapi2aspida - Convert OpenAPI 3.0 and Swagger 2.0 definitions
- aspida-mock - TypeScript friendly RESTful API mock
- frourio - Fast and type-safe full stack framework, for TypeScript TypeScript
- @aspida/react-query - React Query wrapper
- @aspida/swr - SWR (React Hooks) wrapper
- @aspida/swrv - SWRV (Vue Composition API) wrapper
- eslint-plugin-aspida - Support writing aspida api definition