dev.to api的下一级技术博客
#javascript #网络开发人员 #写作

在技术博客中心拥有像开发人员这样的平台是一个不错的选择。 Dev.To拥有超过100万用户,是最大的开发人员社区之一,欢迎各个级别的技术作家和读者。

也就是说,在写作和交付DEV的内容时,事情很复杂。凭借其最少的编辑器,您可能必须进行大量的副本和手动调整,才能将您的帖子从编辑器到DEV和其他平台以及您可能需要交叉的其他平台,例如Hashnode

值得庆幸的是,Dev的基础平台 - 拥有一个很棒的API,您可以轻松地发表和获取Dev的博客文章。让我告诉你如何?

开始使用Forem API

当前,有2个版本的Forem API可用版本0和版本1。它们的请求格式有所不同,但提供了类似的端点。您可以使用其中一个(两者都是documented in the official docs),尽管建议使用较新的V1。

要在不同版本之间切换,您必须提供适当的HTTP标头。对于V1,这些是:

API-Key: [your-api-key]
Accept: application/vnd.forem.api-v1+json
Content-Type: application/json

v0:

API-Key: [your-api-key]
Accept: application/json
Content-Type: application/json
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)

关键区别在于Accept标题中 - 您必须指定application/vnd.forem.api-v1+json才能启用较新版本。最重要的是,对于V0,您必须提供有效的User-Agent标头,否则您的请求将导致403 Forbidden错误。提供的值只是一个例子,我已确认工作。

从这一点上开始,我将仅参考V1,尽管在两个版本中所描述的所有端点都是相同的。

所有这些都清楚了,您现在需要的只是一个API键。

获取您的API键

要获取您的API键,您必须转到Extensions tab of your Dev.to account’s Settings page的底部。在那里,您会看到 dev社区api键部分:

DEV Community API Keys section

输入自定义描述,并生成API键。您应该在列表中看到一个新的API键,可以在其中复制它。

从开发人员获取文章

现在,您可以使用此API及其终点,这都是pretty well-documented。因此,我不想用作第二个文档,而是想讨论此API的两个可能是最大的用例。

第一个是将dev.to用作您的内容中心,使开发人员成为编程出版物的中心,同时还可以在您自己的网站上提供内容,例如自定义博客或投资组合页面。

此用例最重要的终点是GET /api/articles/me,它使您可以检索所有已发表的文章。在这里如何使用它:

interface DEVArticle {
  type_of: string;
  id: number;
  title: string;
  description: string;
  published: boolean;
  published_at: string;
  slug: string;
  path: string;
  url: string;
  comments_count: number;
  public_reactions_count: number;
  page_views_count: number;
  published_timestamp: string;
  body_markdown: string;
  positive_reactions_count: number;
  cover_image: string;
  tag_list: string[] | string;
  tags?: string[];
  canonical_url: string;
  reading_time_minutes: number;
  user: {
    name: string;
    username: string;
    twitter_username: string | null;
    github_username: string | null;
    user_id: number;
    website_url: string | null;
    profile_image: string;
    profile_image_90: string;
  };
  organization?: {
    name: string;
    username: string;
    slug: string;
    profile_image: string;
    profile_image_90: string;
  };
}
interface GetArticlesOptions {
  pages?: number;
  perPage?: number;
}
const getArticles = async (
  options?: GetArticlesOptions
): Promise<DEVArticle[]> => {
  const articles: DEVArticle[] = [];
  const pages = options?.pages || 1;
  const perPage = options?.perPage || 30;

  for (let page = 1; page <= pages; page += 1) {
    const response = await fetch(
      `https://dev.to/api/articles/me?per_page=${perPage}&page=${page}`,
      {
        method: 'GET',
        headers: {
          'api-key': 'your-api-key',
          accept: 'application/vnd.forem.api-v1+json',
          'content-type': 'application/json',
        },
      }
    );
    const json = await response.json();

    articles.push(...json);
  }

  return articles;
};

getArticles({ pages: 3, perPage: 100 }).then((result) => {
  console.log(result);
});

API是启用了CORS的,这意味着您必须使用后端的getArticles()功能。为了提出实际请求,您可以使用fetch()函数,因为Node.js V18可用。对于node.js的较旧版本,您可以使用fetch()兼容的库,例如node-fetch

转换为HTML

拥有文章数据后,您可能必须将其body_markdown处理为网站所需的格式,例如HTML。有很多工具可以使用Marked.js的一个示例来完成此操作:

const markdownToHTML = (markdown: string): string => {
  const regex = new RegExp(/^.*{%\s?(.+?) (.+?)\s?%}.*(?:\n|$)/);
  const getEmbedUrl = (embedType: string, input: string): string => {
    switch (embedType) {
      case 'youtube':
        return `https://www.youtube.com/embed/${input}`;
      case 'codepen':
        return input.replace(/\/pen\//, '/embed/');
      case 'codesandbox':
        return `https://codesandbox.io/embed/${input}`;
      default:
        // etc...
        return '';
    }
  };
  const embedExtension = {
    name: 'embedExtension',
    level: 'block',
    start(src) {
      return src.match(/^.*{%/)?.index;
    },
    tokenizer(src) {
      const match = regex.exec(src);

      console.log('tokenizer', src, match);
      if (match) {
        return {
          type: 'embedExtension',
          raw: match[0],
          embedType: match[1].trim(),
          input: match[2].trim(),
          tokens: [],
        };
      }
    },
    renderer(token) {
      return `<iframe src="${getEmbedUrl(
        token.embedType,
        token.input
      )}"></iframe>`;
    },
  };
  marked.use({ gfm: true, extensions: [embedExtension] });

  return marked.parse(markdown);
};

在大多数情况下,开发人员使用标准的赌注格式,该格式很容易通过标记。对于嵌入(即液体标签),您可以使用其Custom Extension系统轻松扩展标记。上面是将液体标签转换为<iframe>元素的示例,为YouTube,codepen或codesandbox等嵌入式创建适当的URL。您应该能够轻松地将其扩展到处理所使用的嵌入。

如果您想超越获取文章,Forem API提供了其他各种端点,我鼓励您探索。这里有几个例子:

在Dev Via API上发布

可以说,诸如forems之类的API更流行的用例已简化或自动出版。

一般而言,在各种代码和文本编辑器之间编写技术文章时,会有很多副本,例如Dev或Hashnode等出版物,甚至有可能为您的自定义博客提供动力的CMS。每篇文章的整个过程都可能很累。

也就是说,有了一些自动化和不同的API,您可以高度简化此过程。对于Forem API,您可以使用POST /api/articles首先在DEV上发布文章,然后根据PUT /api/articles/{id}进行需要进行更新。这是一个例子:

interface DEVArticleInput {
  title?: string;
  body_markdown?: string;
  published?: boolean;
  series?: string | null;
  main_image?: string | null;
  canonical_url?: string | null;
  description?: string;
  tags?: string[];
  organization_id?: number | null;
}

const publishArticle = async (
  article: DEVArticleInput
): Promise<DEVArticle> => {
  const response = await fetch('https://dev.to/api/articles', {
    method: 'POST',
    headers: {
      'api-key': 'your-api-key',
      accept: 'application/vnd.forem.api-v1+json',
      'content-type': 'application/json',
    },
    body: JSON.stringify({
      article,
    }),
  });
  const json = await response.json();

  return json;
};
const updateArticle = async (
  articleId: string | number,
  articleUpdate: DEVArticleInput
): Promise<DEVArticle> => {
  const response = await fetch(`https://dev.to/api/articles/${articleId}`, {
    method: 'PUT',
    headers: {
      'api-key': 'your-api-key',
      accept: 'application/vnd.forem.api-v1+json',
      'content-type': 'application/json',
    },
    body: JSON.stringify({
      article: articleUpdate,
    }),
  });
  const json = await response.json();

  return json;
};

使用这两个功能,您可以根据需要轻松发布和更新文章,例如

publishArticle({
  title: 'Hello, world!',
  body_markdown: '# Hello World\nThis is my first post published through Forem API!',
  published: false,
}).then((article) => {
  console.log(article);
});

// Later on
updateArticle('1234567', {
  tags: ['javascript', 'typescript', 'react', 'node'],
  series: 'Hello World',
  canonical_url: 'https://example.com',
}).then((updatedArticle) => {
  console.log(updatedArticle);
});

现在,您需要将内容输入转换为与Dev兼容的Markdown格式,对Marked.js前面证明的情况进行了某种反向操作。这可能需要一些自定义处理以最适合您的用例。

现在,如果正确实施,这种发布自动化可以大大改善您的出版经验。尽管如此,这可能会帮助您逃脱编辑之间的复制。

也就Vrite 开源技术内容的无头CM

轻松出版Vrite

vrite结合了所有开发人员熟悉的多种工具和概念,例如:

以无头CM的形式。我认为这是一种独特的组合,有可能在整个技术写作领域提供最佳体验。有关更多详细信息,您可以check out the official guide

Vrite editor

通过Dev.to扩展出版

呆在dev.to的主题上,vrite的最新功能 - 扩展 使与dev集成的vrite一样容易,就像单击几个按钮一样,使您可以轻松地发布并将内容从Vrite更新到手动和自动

现在,Vrite扩展可以轻松地与Dev,Hashnode或Medium等平台进行集成,并使用OpenAI的GPT-3.5的功能扩展了Vrite编辑器的功能,还可以将更多内容集成。

>

设置扩展名很容易,可以从扩展侧面面板中完成:

Configuring Dev.to extension

您可以check out this blog post进行更详细的vrite扩展介绍。

底线

您可以使用Dev.to的API做很多事情。在获取和发布内容之间,它确实具有多种用途,可用于处理许多自定义用例。

也就是说,如果您对更好的技术写作经验感兴趣,请肯定地尝试一下,让我知道您对此的看法以及如何使它变得更好!