在 Node.js 中构建您自己的 Dev.to API 客户端

2025-06-08

在 Node.js 中构建您自己的 Dev.to API 客户端

📣 这篇文章最初出现The Bearer Blog上,题为《在 Node.js 中构建您自己的 API 客户端》

注意:dev.to API最近进行了重大更新,因此现在是尝试它的好时机。

当您与 REST API 交互时,您是直接调用,还是使用 API 提供商提供的客户端?现在许多 API 都提供客户端、包装器或 SDK。这些术语在此上下文中含义相同。如果您使用的 API 没有提供客户端,会发生什么情况?您真的需要客户端吗?有什么好处吗?在本文中,我们将探讨一些您可能需要构建客户端的原因。我们还将构建一个示例 API 客户端,可用作功能更齐全的 API 的基础。

用例

API 客户端(有时也称为 API SDK 或 API 包装器)是用于与 API 间接交互的接口。API 客户端的一些常见功能包括:

  • 集中身份验证和设置
  • 加快开发
  • 处理错误逻辑并提供自定义错误
  • 执行特定语言的约定

大多数 API 客户端的主要目标是简化开发。这使得 API 的新用户能够更快地上手并运行。如果您是 API 的提供者,考虑使用客户端可能会有所帮助。如果您是 API 的使用者,创建包装器可以帮助抽象出重复使用的功能。甚至有一些工具可以自动化此过程。如果您的 API 使用 OpenAPI 标准,像Swagger 的 Codegen这样的工具可以为各种语言生成 SDK。

考虑到这一点,让我们从头开始为 Node.js 和浏览器创建我们自己的 API 客户端。

计划和设置

对于这个例子,我们想关注几个核心特性。

  1. 集中设置和身份验证
  2. 简化的 REST 交互

我们还想选择一个符合我们需求的请求库。由于Fetch是浏览器的标配,我们将使用它。我们将包含一个类似 的库isomorphic-unfetch来管理旧版支持Node.js 支持。如果您愿意,可以将本文中提到的任何概念调整到您选择的库https中。如果您只关心服务器使用情况,甚至可以使用 Node.js 中包含的模块。

⚠️ 注意:虽然我们正在构建的客户端可以在浏览器和 Node.js 中运行,但务必不要在客户端 JavaScript 中暴露 API 密钥,除非它们是公开的。在进行客户端调用之前,请务必与您所使用的 API 确认首选密钥用法。

首先,请确保已安装 Node.js 和 NPM。然后使用以下终端命令设置一个新的 Node.js 项目:

# Make a new directory
mkdir node-api-client-demo

# Change to the new directory
cd node-api-client-demo

# Initialize a new Node.js project
npm init -y
Enter fullscreen mode Exit fullscreen mode

接下来,创建一个名为 的新文件index.js。为了方便使用,我们会将所有代码放在一个文件中,但如果您愿意,也可以将代码拆分成多个模块。

定义客户端接口

在本例中,我们将使用Dev.to API的一部分。它目前仅提供基于密钥的身份验证,这使我们的示例更加简单。要继续操作,您需要一个帐户和一个 API 密钥。您可以按照其文档中的步骤获取这两个密钥。或者,您可以使用像Movie DB这样的 API或类似的基于 API 密钥的平台。

在开始构建包装器之前,我们先来看看用户可能希望如何与它交互。这是一种“文档优先”的方法。

const api = new DevTo({
  api_key: "xxxxxxxxx"
})

api.getArticles(options).then(articles => {})
api.getArticleById(id).then(article => {})

api.createArticle(body).then(article => {})
Enter fullscreen mode Exit fullscreen mode

在上面的代码中,我们创建了一个类的实例DevTo并将其传递给它api_key。然后,我们可以看到各种与 API 交互的方法。为了简洁起见,我们将重点介绍检索文章、获取特定文章以及创建新文章。如果您仔细查看Dev.to API的文档 URL ,您会注意到我们使用的名称与其内部的 getter 和 setter 相同。这不是必需的,但命名方案相当常见。

现在我们可以开始建立我们的课程了。

构建客户端类

打开index.js之前的文件,并创建一个如下类:


class DevTo {
  constructor(config) {
    this.api_key = config.api_key
    this.basePath = "https://dev.to/api"
  }
}
Enter fullscreen mode Exit fullscreen mode

上面的代码定义了DevTo类,并设置了构造函数来接受一个配置对象。然后,它api_key从配置中设置了 ,并将basePath属性设置为 API 端点的基准 URL。现在,安装并引入一个HTTP 库。我们将在本例中使用它isomorphic-unfetch,因为它是基于 Promise 的。

安装isomorphic-unfetch

npm install isomorphic-unfetch
Enter fullscreen mode Exit fullscreen mode

在文件顶部需要包index.js

// index.js
const fetch = require("isomorphic-unfetch")

class DevTo {
  /*...*/
}
Enter fullscreen mode Exit fullscreen mode

接下来,我们可以搭建方法的脚手架。我们需要上面用例示例中的三个方法,以及一个request用于处理构建和发出请求的可复用方法。


class Devto{
  constructor(config) {
    this.api_key = config.api_key
    this.basePath = "https://dev.to/api"
  }

  request(endpoint, options) { /*...*/ }

  getArticles(options) {
    // 1. Convert options to query string
    // 2. return this.request
  }
  getArticleById(id) {
    // 1. Build endpoint based on id
    // 2. return this.request
  }
  createArticle(body) {
    // 1. Build endpoint
    // 2. return this.request with body attached
  }
 }
Enter fullscreen mode Exit fullscreen mode

上述方法包含了每个方法所需的步骤。我们将逐一构建它们,但首先,我们需要确保它们request可用。


request(endpoint = "", options = {}) {

  let url = this.basePath + endpoint

  let headers = {
    'api_key': this.api_key,
    'Content-type': 'application/json'
  }

  let config = {
    ...options,
    ...headers
  }


  return fetch(url, config).then(r => {
    if (r.ok) {
      return r.json()
    }
    throw new Error(r)
  })
}
Enter fullscreen mode Exit fullscreen mode

在上面的代码块中,我们填充了 的功能request。它接受一个endpoint字符串和config一个对象作为参数。然后,我们url从 和endpoint构建basePath。Dev.to API 使用api_key作为身份验证的标头,因此我们将其定义为标头以及 ,以便Content-Type预先处理我们稍后发出的请求。接下来,我们使用扩展运算符POST将传入的options对象与headers合并为一个新的config

最后,我们返回fetch并进行一些简单的错误检查和 JSON 转换。这是最重要的部分。Return 与其他方法的返回相结合,将允许用户像与任何其他 Promise 交互一样与我们的客户端进行交互。无论是通过链式调用then还是使用 async/await。

接下来,让我们定义getArticles方法。为此,我们需要一个小的辅助工具来将选项对象合并到查询字符串中。如果您使用的是浏览器,可以使用NPM 上的某个库,或者自己编写。如果您使用的是 Node,则可以使用内置querystring模块。

首先,在顶部需要模块isomorphic-unfetch

const querystring = require("querystring")
Enter fullscreen mode Exit fullscreen mode

然后,填写getArticles方法:

getArticles(options) {
  let qs = options ? "?" + querystring.stringify(options) : ""

  let url = "/articles" + qs
  let config = {
    method: 'GET'
  }
  return this.request(url, config)
}
Enter fullscreen mode Exit fullscreen mode

这里我们根据用户传入的任何选项构建一个查询字符串。该GET /articles端点允许使用相当多的查询参数。我们让用户以对象的形式提供这些参数,然后将它们处理成 API 能够理解的查询字符串。之后,我们将这些参数添加到端点,并设置一个基本配置,methodGET.定义为GET默认值,因此您可以根据需要省略这一步。

接下来,对于与上述略有不同的版本,我们可以填写getArticleById方法。

getArticleById(id) {
  let url = "/articles/" + id
  return this.request(url, {})
}
Enter fullscreen mode Exit fullscreen mode

这里我们遵循相同的模式来构建 URL,然后返回request带有适当参数的方法。

最后,让我们构建我们的createArticle方法。

createArticle(body) {
  const options = {
    method: 'POST',
    body: JSON.stringify(body)
  }
  return this.request('/articles', options)
  // Optional: add your own .catch to process/deliver errors or fallbacks specific to this resource
}
Enter fullscreen mode Exit fullscreen mode

结尾与之前的方法相同。唯一的区别在于,我们的配置现在将 设置methodPOST,并将文章对象字符串化为body。在所有返回之后,您可以选择链接catch来处理特定于资源的任何错误处理。否则,您的用户将不得不处理任何错误。

整合所有

客户端安装完成后,我们可以回到最初的客户端实现示例:

const api = new DevTo({
  api_key: "XXXXXXXXX"
})

api.getArticles({ username: "bearer", page: 1 }).then(data => console.log(data))
Enter fullscreen mode Exit fullscreen mode

这将返回Dev.to 上 Bearer 帐户的第一页文章。作为此客户端的消费者,我们可以更进一步,使用Bearer来监视 API 调用:

const Bearer = require("@bearer/node-agent")

Bearer.init({
  secretKey: "YOUR-SECRET-KEY"
}).then(() => {
  const api = new DevTo({
    api_key: "XXXXXXXXX"
  })

  api
    .getArticles({ username: "bearer", page: 1 })
    .then(data => console.log(data))
})
Enter fullscreen mode Exit fullscreen mode

这仅仅是个开始。您的 API 客户端可以处理各种重复的用例。它可以将 API 版本锁定到客户端版本,可以允许更复杂的身份验证方法,并且您可以根据用户的需求定制开发者体验。以下是我们示例的完整代码。您是否围绕经常使用的 API 构建过包装器?请在@BearerSH上告诉我们,并关注Bearer 博客,了解更多关于使用 API 的文章。

鏂囩珷鏉ユ簮锛�https://dev.to/bearer/build-your-own-dev-to-api-client-in-node-js-5e5p
PREV
开发人员所说的“API”是什么意思
NEXT
React Hooks 数据处理第一部分 - 获取数据