# 请求封装

URL: https://caijiao.org/ky/encapsulation
Source: docs/ky/encapsulation.md
Description: 学习如何封装 Ky 请求，实现统一接口管理、统一错误处理和响应解析，提高代码复用性。

在大型项目中，直接在各个页面中调用 Ky 发送请求会导致重复代码和维护困难。通过封装请求，可实现统一管理。

## 1. 创建请求模块

```javascript
// api.js
import ky from 'ky';

const api = ky.create({
  prefixUrl: 'https://api.example.com',
  timeout: 5000,
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  hooks: {
    afterResponse: [
      (request, options, response) => {
        if (!response.ok) {
          console.warn(`请求失败: ${response.status}`);
        }
      }
    ]
  }
});

export default api;
````

## 2. 封装常用接口

```javascript
// userService.js
import api from './api.js';

export const getUsers = (page = 1, limit = 10) => {
  return api.get('users', { searchParams: { page, limit } }).json();
};

export const createUser = (userData) => {
  return api.post('users', { json: userData }).json();
};

export const updateUser = (id, userData) => {
  return api.put(`users/${id}`, { json: userData }).json();
};

export const deleteUser = (id) => {
  return api.delete(`users/${id}`).json();
};
```

## 3. 调用封装接口

```javascript
import { getUsers, createUser } from './userService.js';

async function main() {
  const users = await getUsers();
  console.log(users);

  const newUser = await createUser({ name: 'Alice', age: 25 });
  console.log(newUser);
}

main();
```

## 4. 封装优点

* **统一管理**：请求前缀、请求头、超时、错误处理都集中管理。
* **减少重复代码**：各模块直接调用封装好的接口即可。
* **可扩展性强**：后续更换请求库或修改全局配置只需修改 api 模块。
* **易于测试**：可对单个接口函数进行单元测试。

## 小结

* 封装 Ky 请求可以提高代码复用性和可维护性。
* 统一配置和统一错误处理让项目更稳定。
* 建议在大型项目中采用模块化请求封装。
