可运行的 HTTP 样例
本仓库样例不访问外部网络。fixture 对 GET /users/1 返回 { "id": 1, "name": "Ada" },对其他请求返回确定的 JSON 404。
服务端
mjs
/*
* Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createServer } from 'node:http';
const server = createServer((request, response) => {
const found = request.method === 'GET' && request.url === '/users/1';
response.writeHead(found ? 200 : 404, {
'content-type': 'application/json; charset=utf-8',
});
response.end(
JSON.stringify(found ? { id: 1, name: 'Ada' } : { error: 'Not Found' }),
);
});
server.listen(8787, '127.0.0.1', () => {
console.log('Fixture listening on http://127.0.0.1:8787');
});
process.on('SIGINT', () => server.close());客户端
ts
/*
* Copyright [2021-present] [ahoo wang <ahoowang@qq.com> (https://github.com/Ahoo-Wang)].
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ExchangeError,
Fetcher,
HttpStatusValidationError,
ResultExtractors,
} from '@ahoo-wang/fetcher';
interface User {
id: number;
name: string;
}
const client = new Fetcher({ baseURL: 'http://127.0.0.1:8787' });
const user = await client.get<User>(
'/users/1',
{},
{ resultExtractor: ResultExtractors.Json },
);
if (user.id !== 1 || user.name !== 'Ada') {
throw new Error(`Unexpected user: ${JSON.stringify(user)}`);
}
try {
await client.get('/missing');
throw new Error('Expected /missing to fail with HTTP 404');
} catch (error) {
if (
!(error instanceof ExchangeError) ||
!(error.cause instanceof HttpStatusValidationError) ||
error.exchange.response?.status !== 404
) {
throw error;
}
}
console.log(user.name);客户端在 get 的第三个参数中选择 JSON 提取器,并确认 /missing 会产生 ExchangeError:其 cause 为 HttpStatusValidationError,响应状态为 404;其他错误继续抛出。
在本仓库运行
在仓库根目录使用仓库规定的 Node >=20.20.2 与 pnpm 10.34.5:
bash
pnpm --filter @ahoo-wang/fetcher build
pnpm exec tsc -p wiki/examples/http/tsconfig.json
node wiki/examples/http/server.mjs保持该终端运行。在另一个终端执行:
bash
node wiki/examples/http/dist/client.js预期输出:
text
Ada在服务端终端按 Ctrl+C 停止 fixture。要将样例复制到独立项目,请继续阅读第一个请求。
