在 Node.js 中通过 Undici 使用 Fetch API

介绍

Undici 是一个 HTTP 客户端库,为 Node.js 中的 fetch API 提供支持。它是从头开始编写的,不依赖于 Node.js 中的内置 HTTP 客户端。它包含许多特性,使其成为高性能应用程序的理想选择。

有关 Undici 规范符合性的信息,请参阅 Undici 文档

基本的 GET 用法

async function () {
  // Like the browser fetch API, the default method is GET
  const  = await ('https://jsonplaceholder.typicode.com/posts');
  const  = await .();
  .();
  // 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'
  // }
}

().(.);

基本的 POST 用法

// Data sent from the client to the server
const  = {
  : 'foo',
  : 'bar',
  : 1,
};

async function () {
  const  = await ('https://jsonplaceholder.typicode.com/posts', {
    : 'POST',
    : {
      'User-Agent': 'undici-stream-example',
      'Content-Type': 'application/json',
    },
    : .(),
  });
  const  = await .();
  .();
  // returns something like:
  // { title: 'foo', body: 'bar', userId: 1, id: 101 }
}

().(.);

使用 Undici 自定义 Fetch API

Undici 允许您通过向 fetch 函数提供选项来自定义 Fetch API。例如,您可以设置自定义请求头、请求方法和请求体。以下是如何使用 Undici 自定义 Fetch API 的示例

fetch 函数接受两个参数:要获取的 URL 和一个选项对象。该选项对象是可用于自定义请求的 Request 对象。该函数返回一个 Promises,它会解析为一个 Response 对象。

在以下示例中,我们向 Ollama API 发送一个带有 JSON 载荷的 POST 请求。Ollama 是一个命令行工具,允许您在本地机器上运行 LLM(大型语言模型)。您可以在这里下载它。

ollama run mistral

这将下载 mistral 模型并在您的本地机器上运行它。

通过连接池,您可以重用与同一服务器的连接,从而提高性能。以下是如何在 Undici 中使用连接池的示例:

import {  } from 'undici';

const  = new ('https://:11434', {
  : 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 () {
  const { ,  } = await .request({
    : '/api/generate',
    : 'POST',
    : {
      'Content-Type': 'application/json',
    },
    : .({ , : '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 ( !== 200) {
    throw new (`Ollama request failed with status ${}`);
  }

  let  = '';

  const  = new ();
  for await (const  of ) {
     += .(, { : true });
    .();
  }

  .('Streaming complete.');
}

try {
  await ('What is recursion?');
} catch () {
  .('Error calling Ollama:', );
} finally {
  .('Closing Ollama pool.');
  .close();
}

使用 Undici 进行流式响应

是 Node.js 的一项功能,允许您读写数据块。

import {  } from 'stream';

import {  } from 'undici';

async function () {
  const  = 'https://api.github.com/users/nodejs/repos';

  const {  } = await (
    ,
    {
      : 'GET',
      : {
        'User-Agent': 'undici-stream-example',
        : 'application/json',
      },
    },
    () => {
      let  = '';

      return new ({
        (, , ) {
           += .toString();

          try {
            const  = .();
            .(
              'Repository Names:',
              .map( => .name)
            );
             = '';
          } catch () {
            .('Error parsing JSON:', );
          }

          ();
        },
        () {
          .('Stream processing completed.');
          ();
        },
      });
    }
  );

  .(`Response status: ${}`);
}

().(.);