在 Node.js 中使用 Undici 的 Fetch API
¥Using the Fetch API with Undici in Node.js
介绍
¥Introduction
Undici 是一个 HTTP 客户端库,为 Node.js 中的 fetch API 提供支持。它是从头编写的,不依赖于 Node.js 中的内置 HTTP 客户端。它包含许多功能,使其成为高性能应用的不错选择。
¥Undici is an HTTP client library that powers the fetch API in Node.js. It was written from scratch and does not rely on the built-in HTTP client in Node.js. It includes a number of features that make it a good choice for high-performance applications.
基本 GET 用法
¥Basic GET Usage
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 用法
¥Basic POST Usage
// 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
¥Customizing the Fetch API with Undici
Undici 允许你通过向 fetch
函数提供选项来自定义 Fetch API。例如,你可以设置自定义标头、设置请求方法和设置请求正文。以下是如何使用 Undici 自定义 Fetch API 的示例:
¥Undici allows you to customize the Fetch API by providing options to the fetch
function. For example, you can set custom headers, set the request method, and set the request body. Here is an example of how you can customize the Fetch API with Undici:
fetch 函数接受两个参数:要获取的 URL 和选项对象。options 对象是你可用于自定义请求的 请求 对象。该函数返回解析为 响应 对象的 Promise。浏览器中的 Fetch API 和 Node.js 中的 Fetch API 之间的一个区别是 Node.js 版本不支持
¥The fetch function takes two arguments: the URL to fetch and an options object. The options object is the Request object that you can use to customize the request. The function returns a Promises that resolves to a Response object. One difference between the Fetch API in the browser and the Fetch API in Node.js is that the Node.js version does not support
在以下示例中,我们将使用 JSON 有效负载向 Ollama API 发送 POST 请求。Ollama 是一个 cli 工具,可让你在本地计算机上运行 LLM(大型语言模型)。你可以下载 此处
¥In the following example, we are sending a POST request to the Ollama API with a JSON payload. Ollama is a cli tool that allows you to run LLM's (Large Language Models) on your local machine. You can download it here
ollama run mistral
这将下载 mistral
模型并在你的本地机器上运行它。
¥This will download the mistral
model and run it on your local machine.
使用池,你可以重复使用与同一服务器的连接,从而提高性能。以下是如何使用 Undici 池的示例:
¥With a pool, you can reuse connections to the same server, which can improve performance. Here is an example of how you can use a pool with 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://web.nodejs.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 流式响应
¥Streaming Responses with Undici
流 是 Node.js 中的一项功能,允许你读取和写入数据块。
¥Streams is a feature in Node.js that allows you to read and write chucks of data.
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);