在 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.club.tw/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: ${}`);
}

().(.);