You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript实现REST API请求方法并返回完整响应对象求助

用TypeScript实现REST API请求方法(支持GET/POST/PUT/DELETE)

嘿,我明白你需要一个能返回完整响应对象的REST请求方法,而且对Promise和async/await有点懵——没问题,咱们一步步来,用web-request库(这个库是Promise-based的,比已经废弃的request库更适合TypeScript)来实现,顺便把异步逻辑讲清楚。

先搞懂Promise和async/await(快速入门)

先给你补个小知识点,不然看代码会懵:

  • Promise:是用来处理异步操作的对象,它有三种状态:pending(进行中)、fulfilled(成功完成)、rejected(失败)。比如发送HTTP请求就是异步操作,web-request的方法会返回一个Promise,代表请求的结果。
  • async/await:是Promise的语法糖,让异步代码看起来像同步代码:
    • 加了async关键字的函数,会自动返回一个Promise。
    • 在async函数里用await,会暂停函数执行,直到后面的Promise完成(成功或失败),然后返回Promise的结果。

第一步:安装依赖

首先得把需要的包装上,打开终端运行:

npm install web-request
npm install --save-dev @types/web-request

@types/web-request是给TypeScript用的类型定义文件,能让你写代码时有自动提示,避免类型错误。

第二步:实现请求方法(完整代码)

咱们写一个通用的工具类,包含GET/POST/PUT/DELETE四个方法,每个方法都返回完整的响应对象(包含响应码、响应体、响应头、状态信息等):

import * as webRequest from 'web-request';

// 定义响应对象的类型,对应web-request返回的响应结构
type ApiResponse = {
    statusCode: number;
    statusMessage: string;
    headers: webRequest.HttpHeaders;
    content: string; // 响应体,你可以根据需要转成JSON
    // 如果需要JSON格式的响应体,可以加个解析后的属性
    jsonBody?: any;
};

/**
 * 发送GET请求
 * @param url 请求地址
 * @param headers 请求头(可选)
 * @returns 完整的响应对象
 */
export async function sendGetRequest(url: string, headers?: webRequest.HttpHeaders): Promise<ApiResponse> {
    try {
        // await等待请求完成,拿到响应结果
        const response = await webRequest.get(url, { headers });
        // 把响应转换成我们定义的结构,顺便解析JSON(可选)
        return {
            statusCode: response.statusCode,
            statusMessage: response.statusMessage,
            headers: response.headers,
            content: response.content,
            jsonBody: response.content ? JSON.parse(response.content) : undefined
        };
    } catch (error) {
        // 如果请求失败(比如网络错误、4xx/5xx状态码),这里可以处理错误,或者直接抛出让上层处理
        // 注意:web-request默认会把4xx/5xx状态码当成错误抛出,如果你想把它们当成正常响应,可以配置throwOnError: false
        throw error;
    }
}

/**
 * 发送POST请求
 * @param url 请求地址
 * @param body 请求体(可选)
 * @param headers 请求头(可选)
 * @returns 完整的响应对象
 */
export async function sendPostRequest(url: string, body?: any, headers?: webRequest.HttpHeaders): Promise<ApiResponse> {
    try {
        // 如果请求体是对象,需要转成JSON字符串,同时设置Content-Type头
        const requestOptions: webRequest.RequestOptions = {
            headers: {
                'Content-Type': 'application/json',
                ...headers
            },
            body: body ? JSON.stringify(body) : undefined
        };
        const response = await webRequest.post(url, requestOptions);
        return {
            statusCode: response.statusCode,
            statusMessage: response.statusMessage,
            headers: response.headers,
            content: response.content,
            jsonBody: response.content ? JSON.parse(response.content) : undefined
        };
    } catch (error) {
        throw error;
    }
}

/**
 * 发送PUT请求
 * @param url 请求地址
 * @param body 请求体(可选)
 * @param headers 请求头(可选)
 * @returns 完整的响应对象
 */
export async function sendPutRequest(url: string, body?: any, headers?: webRequest.HttpHeaders): Promise<ApiResponse> {
    try {
        const requestOptions: webRequest.RequestOptions = {
            headers: {
                'Content-Type': 'application/json',
                ...headers
            },
            body: body ? JSON.stringify(body) : undefined
        };
        const response = await webRequest.put(url, requestOptions);
        return {
            statusCode: response.statusCode,
            statusMessage: response.statusMessage,
            headers: response.headers,
            content: response.content,
            jsonBody: response.content ? JSON.parse(response.content) : undefined
        };
    } catch (error) {
        throw error;
    }
}

/**
 * 发送DELETE请求
 * @param url 请求地址
 * @param headers 请求头(可选)
 * @returns 完整的响应对象
 */
export async function sendDeleteRequest(url: string, headers?: webRequest.HttpHeaders): Promise<ApiResponse> {
    try {
        const response = await webRequest.delete(url, { headers });
        return {
            statusCode: response.statusCode,
            statusMessage: response.statusMessage,
            headers: response.headers,
            content: response.content,
            jsonBody: response.content ? JSON.parse(response.content) : undefined
        };
    } catch (error) {
        throw error;
    }
}

代码解释

  1. 类型定义:ApiResponse是我们自定义的响应类型,包含了你需要的所有属性:响应码statusCode、状态信息statusMessage、请求头headers、响应体content,还有可选的解析后的JSON体jsonBody。
  2. async/await的用法:每个方法都加了async关键字,所以它们返回的是Promise<ApiResponse>。里面用await等待web-request的请求方法完成,这样代码就像同步执行一样,不用写嵌套的.then()回调。
  3. 错误处理:用try/catch包裹请求逻辑,如果请求失败(比如网络问题、404、500),会进入catch块,你可以在这里自定义错误处理,或者直接抛出错误让上层的测试逻辑去处理。
  4. 请求配置:POST和PUT方法里,我们默认设置了Content-Type: application/json,并把请求体转成JSON字符串——如果你的API需要其他格式(比如form-data),可以修改这部分逻辑。

怎么使用这些方法

在你的测试代码里,可以这样调用:

async function runTests() {
    try {
        // 发送GET请求
        const getResponse = await sendGetRequest('https://jsonplaceholder.typicode.com/todos/1');
        console.log('GET响应:', getResponse.statusCode, getResponse.jsonBody);

        // 发送POST请求
        const postResponse = await sendPostRequest('https://jsonplaceholder.typicode.com/todos', { title: 'Test Todo', completed: false });
        console.log('POST响应:', postResponse.statusCode, postResponse.jsonBody);

        // 发送PUT请求
        const putResponse = await sendPutRequest('https://jsonplaceholder.typicode.com/todos/1', { title: 'Updated Todo', completed: true });
        console.log('PUT响应:', putResponse.statusCode, putResponse.jsonBody);

        // 发送DELETE请求
        const deleteResponse = await sendDeleteRequest('https://jsonplaceholder.typicode.com/todos/1');
        console.log('DELETE响应:', deleteResponse.statusCode);
    } catch (error) {
        console.error('请求出错:', error);
    }
}

// 执行测试
runTests();

注意点

  • 如果你的API不需要解析JSON响应体,可以去掉jsonBody属性,直接返回response.content即可。
  • 如果你希望把4xx/5xx状态码当成正常响应(而不是错误),可以在请求选项里加上throwOnError: false,比如:
    const response = await webRequest.get(url, { headers, throwOnError: false });
    

这样即使是404或者500,也会进入try块,而不是catch块。

内容的提问来源于stack exchange,提问作者Hennadii Bulakh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:41:08