在 Node.js 中使用 Undici 的 Fetch API
简介
Undici 是一个 HTTP 客户端库,它为 Node.js 中的 fetch API 提供支持。 它是从头开始编写的,不依赖于 Node.js 中内置的 HTTP 客户端。 它包含许多使其成为高性能应用程序的理想选择的功能。
有关 Undici 规范合规性的信息,请参阅 Undici 文档。
基本 GET 用法
async function main() {
// Like the browser fetch API, the default method is GET
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
const data = await response.json();
console.log(data);
// returns something like:
// {
// userId: 1,
// id: 1,
// title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
// body: 'quia et suscipit\n' +
// 'suscipit recusandae consequuntur expedita et cum\n' +
// 'reprehenderit molestiae ut ut quas totam\n' +
// 'nostrum rerum est autem sunt rem eveniet architecto'
// }
}
main().catch(console.error);
基本 POST 用法
// Data sent from the client to the server
const body = {
title: 'foo',
body: 'bar',
userId: 1,
};
async function main() {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'User-Agent': 'undici-stream-example',
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
const data = await response.json();
console.log(data);
// returns something like:
// { title: 'foo', body: 'bar', userId: 1, id: 101 }
}
main().catch(console.error);
使用 Undici 自定义 Fetch API
Undici 允许您通过向 fetch
函数提供选项来自定义 Fetch API。 例如,您可以设置自定义标头、设置请求方法和设置请求正文。 以下是如何使用 Undici 自定义 Fetch API 的示例
fetch 函数接受两个参数:要提取的 URL 和一个选项对象。 该选项对象是您可以用来自定义请求的 Request 对象。 该函数返回一个解析为 Response 对象的 Promises。
在以下示例中,我们将带有 JSON 负载的 POST 请求发送到 Ollama API。 Ollama 是一个 cli 工具,允许您在本地机器上运行 LLM(大型语言模型)。 您可以从此处下载
ollama run mistral
这将下载 mistral
模型并在您的本地计算机上运行它。
通过池,您可以重用与同一服务器的连接,从而提高性能。 以下是如何将池与 Undici 结合使用的示例
import { Pool } from 'undici';
const ollamaPool = new Pool('http://localhost:11434', {
connections: 10,
});
/**
* Stream the completion of a prompt using the Ollama API.
* @param {string} prompt - The prompt to complete.
* @link https://github.com/ollama/ollama/blob/main/docs/api.md
**/
async function streamOllamaCompletion(prompt) {
const { statusCode, body } = await ollamaPool.request({
path: '/api/generate',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ prompt, model: 'mistral' }),
});
// You can read about HTTP status codes here: https://mdn.org.cn/en-US/docs/Web/HTTP/Status
// 200 means the request was successful.
if (statusCode !== 200) {
throw new Error(`Ollama request failed with status ${statusCode}`);
}
let partial = '';
const decoder = new TextDecoder();
for await (const chunk of body) {
partial += decoder.decode(chunk, { stream: true });
console.log(partial);
}
console.log('Streaming complete.');
}
try {
await streamOllamaCompletion('What is recursion?');
} catch (error) {
console.error('Error calling Ollama:', error);
} finally {
console.log('Closing Ollama pool.');
ollamaPool.close();
}
使用 Undici 流式传输响应
Streams 是 Node.js 中的一项功能,允许您读取和写入数据块。
import { stream } from 'undici';
import { Writable } from 'stream';
async function fetchGitHubRepos() {
const url = 'https://api.github.com/users/nodejs/repos';
const { statusCode } = await stream(
url,
{
method: 'GET',
headers: {
'User-Agent': 'undici-stream-example',
Accept: 'application/json',
},
},
() => {
let buffer = '';
return new Writable({
write(chunk, encoding, callback) {
buffer += chunk.toString();
try {
const json = JSON.parse(buffer);
console.log(
'Repository Names:',
json.map(repo => repo.name)
);
buffer = '';
} catch (error) {
console.error('Error parsing JSON:', error);
}
callback();
},
final(callback) {
console.log('Stream processing completed.');
callback();
},
});
}
);
console.log(`Response status: ${statusCode}`);
}
fetchGitHubRepos().catch(console.error);