{"id":13475663,"url":"https://github.com/aspida/aspida","last_synced_at":"2025-05-14T21:08:48.478Z","repository":{"id":37330450,"uuid":"213083762","full_name":"aspida/aspida","owner":"aspida","description":"TypeScript friendly HTTP client wrapper for the browser and node.js.","archived":false,"fork":false,"pushed_at":"2023-11-11T14:17:00.000Z","size":5722,"stargazers_count":1071,"open_issues_count":21,"forks_count":36,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-05-13T23:13:55.618Z","etag":null,"topics":["http-client","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/aspida/aspida","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aspida.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-10-05T23:17:49.000Z","updated_at":"2025-05-04T02:20:15.000Z","dependencies_parsed_at":"2024-01-14T08:14:54.622Z","dependency_job_id":"5f970dc3-e7e2-45a1-9e4e-7aa8bf0f1133","html_url":"https://github.com/aspida/aspida","commit_stats":{"total_commits":1148,"total_committers":16,"mean_commits":71.75,"dds":0.6193379790940767,"last_synced_commit":"4c74918ece72d5b440dc897d915c5cbbedb0120f"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspida%2Faspida","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspida%2Faspida/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspida%2Faspida/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aspida%2Faspida/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aspida","download_url":"https://codeload.github.com/aspida/aspida/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254050899,"owners_count":22006377,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["http-client","typescript"],"created_at":"2024-07-31T16:01:22.340Z","updated_at":"2025-05-14T21:08:43.466Z","avatar_url":"https://github.com/aspida.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# aspida\n\n\u003cbr /\u003e\n\u003cimg src=\"https://aspida.github.io/aspida/logos/png/logo.png\" alt=\"aspida\" title=\"aspida\" /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/aspida\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/aspida\" alt=\"npm version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/aspida\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/aspida\" alt=\"npm download\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\u003cp align=\"center\"\u003eTypeScript friendly HTTP client wrapper for the browser and node.js.\u003c/p\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/aspida/aspida/tree/master/packages/aspida#readme\"\u003e🇺🇸English\u003c/a\u003e |\n  \u003ca href=\"https://github.com/aspida/aspida/tree/master/packages/aspida/docs/ja#readme\"\u003e🇯🇵日本語\u003c/a\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n## Features\n\n- Path, URL query, header, body, and response can all specify the type\n- FormData / URLSearchParams content can also specify the type\n- HTTP client supports axios / fetch / node-fetch\n\n\u003cbr /\u003e\n\u003cimg src=\"https://aspida.github.io/aspida/assets/images/vscode.gif\" width=\"720\" alt=\"vscode\" /\u003e\n\u003cbr /\u003e\n\n## Procedure\n\n1. Reproduce the endpoint directory structure in the \"api\" directory\n1. Export a Type alias named \"Methods\"\n1. Call \"aspida\" with npm scripts\n1. API type definition file \"api/\\$api.ts\" will be generated, so import the application and make an HTTP request\n\n## Getting Started\n\n### Installation (axios ver.)\n\n- Using [npm](https://www.npmjs.com/):\n\n  ```sh\n  $ npm install aspida @aspida/axios axios\n  ```\n\n- Using [Yarn](https://yarnpkg.com/):\n\n  ```sh\n  $ yarn add aspida @aspida/axios axios\n  ```\n\n### Create \"api\" directory\n\n```sh\n$ mkdir api\n```\n\n### Type helper `DefineMethods`\n\n`DefineMethods\u003c\u003e` is helper type for defining `Methods`. In earlier aspida, user shuold define without checking for API definition.\nIf you already have aspida in your projects, you can easily use `DefineMethods\u003c\u003e` with surrounding your definition.\nIt is just an option whether to use `DefineMethods\u003c\u003e`.\nBe aware of the limitation that `DefineMethods\u003c\u003e` can't detect extra meaningless properties.\n\n### Create an endpoint type definition file\n\n- GET: /v1/users/?limit={number}\n- POST: /v1/users\n\n  `api/v1/users/index.ts`\n\n  ```ts\n  import type { DefineMethods } from \"aspida\";\n\n  type User = {\n    id: number;\n    name: string;\n  };\n\n  export type Methods = DefineMethods\u003c{\n    get: {\n      query?: {\n        limit: number;\n      };\n\n      resBody: User[];\n    };\n\n    post: {\n      reqBody: {\n        name: string;\n      };\n\n      resBody: User;\n      /**\n       * reqHeaders(?): ...\n       * reqFormat: ...\n       * status: ...\n       * resHeaders(?): ...\n       * polymorph: [...]\n       */\n    };\n  }\u003e;\n  ```\n\n- GET: /v1/users/\\${userId}\n- PUT: /v1/users/\\${userId}\n\n  `api/v1/users/_userId@number/index.ts`\n\n  Specify the type of path variable “userId” starting with underscore with “@number”  \n  If not specified with @, the default path variable type is \"number | string\"\n\n  ```ts\n  import type { DefineMethods } from \"aspida\";\n\n  type User = {\n    id: number;\n    name: string;\n  };\n\n  export type Methods = DefineMethods\u003c{\n    get: {\n      resBody: User;\n    };\n\n    put: {\n      reqBody: {\n        name: string;\n      };\n\n      resBody: User;\n    };\n  }\u003e;\n  ```\n\n### Build type definition file\n\n`package.json`\n\n```json\n{\n  \"scripts\": {\n    \"api:build\": \"aspida\"\n  }\n}\n```\n\n```sh\n$ npm run api:build\n\n\u003e api/$api.ts was built successfully.\n```\n\n### Make HTTP request from application\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const userId = 0;\n  const limit = 10;\n  const client = api(aspida());\n\n  await client.v1.users.post({ body: { name: \"taro\" } });\n\n  const res = await client.v1.users.get({ query: { limit } });\n  console.log(res);\n  // req -\u003e GET: /v1/users/?limit=10\n  // res -\u003e { status: 200, body: [{ id: 0, name: \"taro\" }], headers: {...} }\n\n  const user = await client.v1.users._userId(userId).$get();\n  console.log(user);\n  // req -\u003e GET: /v1/users/0\n  // res -\u003e { id: 0, name: \"taro\" }\n})();\n```\n\n### aspida official HTTP clients\n\n- **[@aspida/axios](https://github.com/aspida/aspida/tree/master/packages/aspida-axios#readme)**\n- **[@aspida/fetch](https://github.com/aspida/aspida/tree/master/packages/aspida-fetch#readme)**\n- **[@aspida/node-fetch](https://github.com/aspida/aspida/tree/master/packages/aspida-node-fetch#readme)**\n\n## Command Line Interface Options\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eOption\u003c/th\u003e\n      \u003cth\u003eType\u003c/th\u003e\n      \u003cth\u003eDefault\u003c/th\u003e\n      \u003cth width=\"100%\"\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd nowrap\u003e\u003ccode\u003e--config\u003c/code\u003e\u003cbr /\u003e\u003ccode\u003e-c\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003estring\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e\"aspida.config.js\"\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eSpecify the path to the configuration file.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd nowrap\u003e\u003ccode\u003e--watch\u003c/code\u003e\u003cbr /\u003e\u003ccode\u003e-w\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n      \u003ctd\u003e\n        Enable watch mode.\u003cbr /\u003e\n        Regenerate \u003ccode\u003e$api.ts\u003c/code\u003e according to\n        the increase / decrease of the API endpoint file.\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd nowrap\u003e\u003ccode\u003e--version\u003c/code\u003e\u003cbr /\u003e\u003ccode\u003e-v\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n      \u003ctd\u003ePrint aspida version.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Options of aspida.config.js\n\n| Option               | Type                                 | Default | Description                                           |\n| -------------------- | ------------------------------------ | ------- | ----------------------------------------------------- |\n| input                | string                               | \"api\"   | Specifies the endpoint type definition root directory |\n| baseURL              | string                               | \"\"      | Specify baseURL of the request                        |\n| trailingSlash        | boolean                              | false   | Append `/` to the request URL                         |\n| outputEachDir        | boolean                              | false   | Generate `$api.ts` in each endpoint directory         |\n| outputMode (\u003e=1.6.0) | \"all\" \\| \"normalOnly\" \\| \"aliasOnly\" | \"all\"   | Output either `get` or `$get` for compression         |\n\n## Node.js API\n\n```ts\nimport { version, build, watch } from \"aspida/dist/commands\";\n\nconsole.log(version()); // 0.x.y\n\nbuild();\nbuild(\"./app/aspida.config.js\");\nbuild({ input: \"api1\" });\nbuild([\n  { baseURL: \"https://example.com/v1\" },\n  {\n    input: \"api2\",\n    baseURL: \"https://example.com/v2\",\n    trailingSlash: true,\n    outputEachDir: true,\n    outputMode: \"all\",\n  },\n]);\n\nwatch();\nwatch(\"./app/aspida.config.js\");\nwatch({ input: \"api1\" });\nwatch([\n  { baseURL: \"https://example.com/v1\" },\n  {\n    input: \"api2\",\n    baseURL: \"https://example.com/v2\",\n    trailingSlash: true,\n    outputEachDir: true,\n    outputMode: \"all\",\n  },\n]);\n```\n\n## Ecosystem\n\n- [openapi2aspida](https://github.com/aspida/openapi2aspida) - Convert OpenAPI 3.0 and Swagger 2.0 definitions\n- [aspida-mock](https://github.com/aspida/aspida-mock) - TypeScript friendly RESTful API mock\n- [frourio](https://frourio.io/) - Fast and type-safe full stack framework, for TypeScript TypeScript\n- [@aspida/react-query](https://github.com/aspida/aspida/tree/master/packages/aspida-react-query) - React Query wrapper\n- [@aspida/swr](https://github.com/aspida/aspida/tree/master/packages/aspida-swr) - SWR (React Hooks) wrapper\n- [@aspida/swrv](https://github.com/aspida/aspida/tree/master/packages/aspida-swrv) - SWRV (Vue Composition API) wrapper\n- [eslint-plugin-aspida](https://github.com/aspida/eslint-plugin-aspida) - Support writing aspida api definition\n\n## Tips\n\n1. [Change the directory where type definition file is placed to other than \"api\"](#tips1)\n1. [Serialize GET parameters manually](#tips2)\n1. [POST with FormData](#tips3)\n1. [POST with URLSearchParams](#tips4)\n1. [Receive response with ArrayBuffer](#tips5)\n1. [Define polymorphic request](#tips6)\n1. [Define endpoints that contain special characters](#tips7)\n1. [Import only some endpoints](#tips8)\n1. [Retrieve endpoint URL string](#tips9)\n1. [Reflect TSDoc comments](#tips10)\n\n\u003ca id=\"tips1\"\u003e\u003c/a\u003e\n\n### Change the directory where type definition file is placed to other than \"api\"\n\nCreate a configuration file at the root of the project\n\n`aspida.config.js`\n\n```javascript\nmodule.exports = { input: \"src\" };\n```\n\nSpecify baseURL in configuration file\n\n```javascript\nmodule.exports = { baseURL: \"https://example.com/api\" };\n```\n\nIf you want to define multiple API endpoints, specify them in an array\n\n```javascript\nmodule.exports = [{ input: \"api1\" }, { input: \"api2\", baseURL: \"https://example.com/api\" }];\n```\n\n\u003ca id=\"tips2\"\u003e\u003c/a\u003e\n\n### Serialize GET parameters manually\n\naspida leaves GET parameter serialization to standard HTTP client behavior  \nIf you want to serialize manually, you can use config object of HTTP client\n\n`src/index.ts`\n\n```ts\nimport axios from \"axios\";\nimport qs from \"qs\";\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(\n    aspida(axios, { paramsSerializer: params =\u003e qs.stringify(params, { indices: false }) })\n  );\n\n  const users = await client.v1.users.$get({\n    // config: { paramsSerializer: (params) =\u003e qs.stringify(params, { indices: false }) },\n    query: { ids: [1, 2, 3] },\n  });\n  console.log(users);\n  // req -\u003e GET: /v1/users/?ids=1\u0026ids=2\u0026ids=3\n  // res -\u003e [{ id: 1, name: \"taro1\" }, { id: 2, name: \"taro2\" }, { id: 3, name: \"taro3\" }]\n})();\n```\n\n\u003ca id=\"tips3\"\u003e\u003c/a\u003e\n\n### POST with FormData\n\n`api/v1/users/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\nimport type { ReadStream } from \"fs\";\n\nexport type Methods = DefineMethods\u003c{\n  post: {\n    reqFormat: FormData;\n\n    reqBody: {\n      name: string;\n      icon: File | ReadStream;\n    };\n\n    resBody: {\n      id: number;\n      name: string;\n    };\n  };\n}\u003e;\n```\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  const user = await client.v1.users.$post({\n    body: {\n      name: \"taro\",\n      icon: imageFile,\n    },\n  });\n  console.log(user);\n  // req -\u003e POST: h/v1/users\n  // res -\u003e { id: 0, name: \"taro\" }\n})();\n```\n\nPost in Node.js (\u003e=1.6.0)\n\n`src/index.ts`\n\n```ts\nimport fs from \"fs\";\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n  const fileName = \"images/sample.jpg\";\n  const user = await client.v1.users.$post({\n    body: {\n      name: \"taro\",\n      icon: fs.createReadStream(fileName),\n    },\n  });\n  console.log(user);\n  // req -\u003e POST: h/v1/users\n  // res -\u003e { id: 0, name: \"taro\" }\n})();\n```\n\n\u003ca id=\"tips4\"\u003e\u003c/a\u003e\n\n### POST with URLSearchParams\n\n`api/v1/users/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\n\nexport type Methods = DefineMethods\u003c{\n  post: {\n    reqFormat: URLSearchParams;\n\n    reqBody: {\n      name: string;\n    };\n\n    resBody: {\n      id: number;\n      name: string;\n    };\n  };\n}\u003e;\n```\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  const user = await client.v1.users.$post({ body: { name: \"taro\" } });\n  console.log(user);\n  // req -\u003e POST: /v1/users\n  // res -\u003e { id: 0, name: \"taro\" }\n})();\n```\n\n\u003ca id=\"tips5\"\u003e\u003c/a\u003e\n\n### Receive response with ArrayBuffer\n\n`api/v1/users/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\n\nexport type Methods = DefineMethods\u003c{\n  get: {\n    query: {\n      name: string;\n    };\n\n    resBody: ArrayBuffer;\n  };\n}\u003e;\n```\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  const user = await client.v1.users.$get({ query: { name: \"taro\" } });\n  console.log(user);\n  // req -\u003e GET: /v1/users/?name=taro\n  // res -\u003e ArrayBuffer\n})();\n```\n\n\u003ca id=\"tips6\"\u003e\u003c/a\u003e\n\n### Define polymorphic request\n\n`api/users/index.ts`\n\n```ts\nimport type { DefineMethods } from 'aspida'\n\ntype User = {\n  id: number\n  name: string\n}\n\nexport Methods = DefineMethods\u003c{\n  post: {\n    // common properties\n    reqFormat: FormData\n    /**\n     * query(?): ...\n     * reqHeaders(?): ...\n     * reqBody(?): ...\n     * status: ...\n     * resHeaders(?): ...\n     * resBody(?): ...\n     */\n    polymorph: [\n      // polymorphic types\n      {\n        reqBody: Omit\u003cUser, 'id'\u003e\n        resBody: User\n        /**\n         * query(?): ...\n         * reqHeaders(?): ...\n         * status: ...\n         * resHeaders(?): ...\n         */\n      },\n      {\n        reqBody: Omit\u003cUser, 'id'\u003e[]\n        resBody: User[]\n      }\n    ]\n  }\n}\u003e\n```\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  const user = await client.users.$post({ body: { name: \"taro\" } });\n  console.log(user); // { id: 0, name: \"taro\" }\n\n  const users = await client.users.$post({\n    body: [{ name: \"hanako\" }, { name: \"mario\" }],\n  });\n  console.log(users); // [{ id: 1, name: \"hanako\" }, { id: 2, name: \"mario\" }]\n})();\n```\n\n\u003ca id=\"tips7\"\u003e\u003c/a\u003e\n\n### Define endpoints that contain special characters\n\nSpecial characters are encoded as percent-encoding in the file name  \nExample `\":\"` -\u003e `\"%3A\"`\n\n`api/foo%3Abar/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\n\nexport type Methods = DefineMethods\u003c{\n  get: {\n    resBody: string;\n  };\n}\u003e;\n```\n\n`api/users/_userId@number%3Aread/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\n\nexport type Methods = DefineMethods\u003c{\n  get: {\n    resBody: User;\n  };\n}\u003e;\n```\n\nWith clients, `\"%3A\"` -\u003e `\":\"`\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  const message = await client.foo_bar.$get();\n  console.log(message);\n  // req -\u003e GET: /foo:bar\n\n  const user = await client.users._userId_read(1).$get();\n  console.log(user);\n  // req -\u003e GET: /users/1:read\n})();\n```\n\n\u003ca id=\"tips8\"\u003e\u003c/a\u003e\n\n### Import only some endpoints\n\nIf you don't need to use all of `api/$api.ts` , you can split them up and import only part of them  \n`outputEachDir` option generates `$api.ts` in each endpoint directory  \n`$api.ts` will not be generated under the directory containing the path variable\n\n`aspida.config.js`\n\n```js\nmodule.exports = { outputEachDir: true };\n```\n\nImport only `$api.ts` of the endpoint you want to use and put it into Object\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api0 from \"../api/v1/foo/$api\";\nimport api1 from \"../api/v2/bar/$api\";\n(async () =\u003e {\n  const aspidaClient = aspida();\n  const client = {\n    foo: api0(aspidaClient),\n    bar: api1(aspidaClient),\n  };\n\n  const message = await client.bar._id(1).$get();\n  // req -\u003e GET: /v2/bar/1\n})();\n```\n\n\u003ca id=\"tips9\"\u003e\u003c/a\u003e\n\n### Retrieve endpoint URL string\n\n`src/index.ts`\n\n```ts\nimport aspida from \"@aspida/axios\";\nimport api from \"../api/$api\";\n(async () =\u003e {\n  const client = api(aspida());\n\n  console.log(client.v1.users.$path());\n  // /v1/users\n\n  console.log(client.vi.users.$path({ query: { limit: 10 } }));\n  // /v1/users?limit=10\n\n  console.log(\n    client.vi.users.$path({\n      method: \"post\",\n      query: { id: 1 },\n    })\n  );\n  // /v1/users?id=1\n})();\n```\n\n\u003ca id=\"tips10\"\u003e\u003c/a\u003e\n\n### Reflect TSDoc comments\n\n`api/index.ts`\n\n```ts\nimport type { DefineMethods } from \"aspida\";\n\n/**\n * root comment\n *\n * @remarks\n * root remarks comment\n */\nexport type Methods = DefineMethods\u003c{\n  /**\n   * post method comment\n   *\n   * @remarks\n   * post method remarks comment\n   */\n  post: {\n    /** post query comment */\n    query: { limit: number };\n\n    /** post reqHeaders comment */\n    reqHeaders: { token: string };\n\n    reqFormat: FormData;\n    /** post reqBody comment */\n    reqBody: UserCreation;\n\n    /**\n     * post resBody comment1\n     * post resBody comment2\n     */\n    resBody: User;\n  };\n}\u003e;\n```\n\n```sh\n$ npm run api:build\n```\n\n`api/$api.ts`\n\n```ts\n/**\n * root comment\n *\n * @remarks\n * root remarks comment\n */\nconst api = \u003cT\u003e({ baseURL, fetch }: AspidaClient\u003cT\u003e) =\u003e {\n  return {\n    /**\n     * post method comment\n     *\n     * @remarks\n     * post method remarks comment\n     *\n     * @param option.query - post query comment\n     * @param option.headers - post reqHeaders comment\n     * @param option.body - post reqBody comment\n     * @returns post resBody comment1\n     * post resBody comment2\n     */\n    $post: (option: {\n      body: Methods0[\"post\"][\"reqBody\"];\n      query: Methods0[\"post\"][\"query\"];\n      headers: Methods0[\"post\"][\"reqHeaders\"];\n      config?: T;\n    }) =\u003e\n      fetch\u003cMethods0[\"post\"][\"resBody\"]\u003e(prefix, PATH0, POST, option)\n        .json()\n        .then(r =\u003e r.body),\n  };\n};\n```\n\n## License\n\naspida is licensed under a [MIT License](https://github.com/aspida/aspida/blob/master/packages/aspida/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspida%2Faspida","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faspida%2Faspida","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faspida%2Faspida/lists"}