{"id":17154521,"url":"https://github.com/maoxiaoke/request-core","last_synced_at":"2025-04-10T15:54:17.663Z","repository":{"id":101399175,"uuid":"577300131","full_name":"maoxiaoke/request-core","owner":"maoxiaoke","description":"A pluggable low-level library for developers to build their own HTTP Clients","archived":false,"fork":false,"pushed_at":"2025-02-08T03:44:49.000Z","size":325,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-24T13:44:05.222Z","etag":null,"topics":["reqeust","web"],"latest_commit_sha":null,"homepage":"","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/maoxiaoke.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-12-12T12:40:48.000Z","updated_at":"2025-02-08T03:44:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"876220df-3e69-4351-9764-5b9ba7a72aa8","html_url":"https://github.com/maoxiaoke/request-core","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maoxiaoke%2Frequest-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maoxiaoke%2Frequest-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maoxiaoke%2Frequest-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maoxiaoke%2Frequest-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maoxiaoke","download_url":"https://codeload.github.com/maoxiaoke/request-core/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248246116,"owners_count":21071640,"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":["reqeust","web"],"created_at":"2024-10-14T21:49:28.051Z","updated_at":"2025-04-10T15:54:17.642Z","avatar_url":"https://github.com/maoxiaoke.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# request-core\n\n`request-core` 是一个基于洋葱模型的，支持中间件的底层库。`request-core` 并不是直接给项目提供的 Http Client，而是为了方便开发者开发自己的请求库。\n\n基于 request-core，你可以很方便地为自己的公司、或项目开发一套统一的请求库。\n\n## Axios is good enough, but not enough\n\n公司内部往往有很多项目，每个项目都有自己的 Http Client，这些请求库的代码大同小异，但是又有一些细微的差别。比如有的项目使用了 axios，有的项目使用了 fetch，有的项目使用了自己封装的请求库。请求库的混乱是阻碍团队协作的，随着公司前端工程的规范化、一致化，就会产生统一请求库的诉求。\n\n但面临实际场景，完全统一的请求库是无法满足不同业务、不同项目的诉求的。如果强行进行统一，只会造成请求库的臃肿和难以使用。\n\n举个实际的例子，错误的统一管控是一个常见的诉求。工程上希望对请求进行统一的错误拦截，当接口报错时，可以对用户进行提示。对于 toB 的业务，可能会采用 [antd](https://ant.design/index-cn/) 的 [Message 组件](https://ant.design/components/message-cn) 来进行提示；而对于无线端业务，有可能会使用到 [antd-mobile](https://mobile.ant.design/index-cn/) 的 [toast](https://mobile.ant.design/zh/components/toast)。这就是由于不同类型业务（PC 业务和无线端业务）导致请求库在处理相同问题时所带来的差异。\n\n`request-core` 的出现就是为了解决这个问题。`request-core` 提供了一个基于洋葱模型的请求库，你可以通过中间件的方式来扩展它，从而满足不同的业务需求。\n\n```ts\n// 这个例子展示使用 request-core 轻易地创建一个项目的请求库\n\n// 引入公用的 baseUrlHandler 中间件\nimport { Core, Req, Response, baseUrlHandler } from '@nzha/request-core';\n\nimport { errorHandlerUsingAntd } from './errorHandlerUsingAntd';\nimport { errorHandlerUsingAntdMobile } from './errorHandlerUsingAntdMobile';\n\nconst toBRequest = new Core\u003cReq\u003e();\ntoBRequest.use(baseUrlHandler(), errorHandlerUsingAntd);\n\nconst mobileRequest = new Core\u003cReq\u003e();\nmobileRequest.use(baseUrlHandler(), errorHandlerUsingAntdMobile);\n```\n\n从上面的例子可以认识到，相比于之前各个项目、各个业务相互为政。`request-core` 通过统一和规范，来分化出针对不同项目和业务的请求能力。对于请求库的开发者，只需要进行中间件的开发，然后针对不同业务、项目进行中间件编排；对于请求库的消费者而言，使用方式基本完全一致：\n\n```js\n// 这个例子展示请求库在项目中的使用\n\nimport { myOwnHttpClient } from 'my-own-http-client';\n\nmyOwnHttpClient.get('https://api.github.com/user');\n```\n\n## How to use\n\n安装 `request-core`：\n\n```bash\npnpm add @nzha/request-core\n# or\nnpm i @nzha/request-core\n```\n\n`request-core` 的 api 非常少，创建你自己的请求库只需要以下以下几行代码：\n\n```ts\nimport { Core, baseUrlHandler } from '@nzha/request-core';\nimport { Req } from '@nzha/request-core';\n\ninterface ExtendReq extends Req {\n  // 你可以在这里扩展 Req 的类型，比如增加一些自定义参数\n  baseUrl?: string;\n}\n\nconst xxxReqeust = new Core\u003cExtendReq\u003e();\n\nxxxReqeust.use(baseUrlHandler);\n\nexport {\n  xxxReqeust,\n}\n```\n\n## 中间件\n\n`request-core` 是核心是中间件。中间件是一个函数，它接受一个 `Req` 对象，返回一个 `Res` 对象。中间件的执行顺序是从左到右。\n\n下面是自定义一个 `request-core` 中间件的例子。\n\n```ts\nimport { Middleware } from '@nzha/request-core';\n\nconst myMiddleware: Middleware = (next) =\u003e async (req) =\u003e {\n  // Do Something to change req params\n  const response = await next(req);\n\n  // Do Something to change response\n  return response;\n};\n\nexport {\n  myMiddleware,\n};\n```\n\n## 内置中间件\n\n`request-core` 内置一些基础的中间件，帮助请求库开发者更简单地开发自己的请求库。\n\n### baseUrlHandler\n\n`baseUrlHandler` 可以在请求时自动拼接 baseUrl。\n\n```ts\n// 使用示例\nimport { baseUrlHandler, Core } from '@nzha/request-core';\n\nconst myOwnRequest = new Core();\nmyOwnRequest.use(baseUrlHandler('https://api.github.com'));\n```\n\n当用户调用 `myOwnRequest.get('/user')` 时，实际上会发起 `https://api.github.com/user` 的请求。\n\n### jsonResponseHandler\n\n`jsonResponseHandler` 会自动将响应体转换为 json 对象。\n\n\n### queryHandler\n\n`queryHandler` 可以在请求时自动拼接 query 参数。可以将 query 参数传递为对象或者字符串。\n\n```ts\n// 使用示例\nimport { queryHandler, Core } from '@nzha/request-core';\n\nconst myOwnRequest = new Core();\nmyOwnRequest.use(queryHandler());\n\n// 使用\nmyOwnRequest.get('/user', {\n  query: {\n    name: 'nzha',\n  },\n});\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaoxiaoke%2Frequest-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaoxiaoke%2Frequest-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaoxiaoke%2Frequest-core/lists"}