💬

Zennの記事フィードをjsonで取得するTypeScript

2023/03/28に公開

背景

自分のポートフォリオにZennの投稿記事のヘッドラインを載せたいと思い、いろいろ調べて組み立ててみました。

実装

getZennFeeds.ts
import axios from "axios";

export const getZennFeeds = async <T>(username: string): Promise<T> => {

    return new Promise<T>(function (resolve, reject) {

        const serverURL = `https://api.rss2json.com/v1/api.json?rss_url=https://zenn.dev/${username}/feed`;

        axios.get(serverURL)
            .then((response) => {
                if (response.status == 200) {
                    resolve(response.data);
                } else {
                    reject(Error(response.statusText));
                }
            })
            .catch((error) => {
                console.error(error);
            });
    });
}

export interface Root {
    status: string
    feed: Feed
    items: Item[]
}

interface Feed {
    url: string
    title: string
    link: string
    author: string
    description: string
    image: string
}

interface Item {
    title: string
    pubDate: string
    link: string
    guid: string
    author: string
    thumbnail: string
    description: string
    content: string
    enclosure: Enclosure
    categories: any[]
}

interface Enclosure {
    link: string
    type: string
}

HTTPリクエストにはaxiosを使いました。
「rss2json」というサービスを経由して、Zennのフィードから得られるXMLデータをjsonに変換しています。

後半はレスポンスの構造を定義したinterface部分です。
functionと合わせて呼び出し元にexportできるようにしていますが、FeedItemEnclosureRootの内部構造なので、exportするのはRootだけでOKです。

呼び出す

import { getZennFeeds } from "getZennFeeds";  // <- from以降のパスはお手元のファイル構成に合わせてよしなに
import type { Root } from "getZennFeeds";

let promise = getZennFeeds<Root>("your-user-name");

promise.then(result => {
    console.log(result.feed.title);   // 例)記事のタイトル
    console.log(result.items.length); // 例)記事の本数
})

getZennFeedsPromiseを返すので、thenで待ってレスポンスを取り出してあげます。
先ほど定義したRoot型のオブジェクトとして返ってくるので、フィードのタイトルや記事の中身にもプロパティとしてアクセスすることができます。

まとめ

ポートフォリオを作成した記事は別に投稿する予定でおりますが、実務からはずいぶんと離れていたJavaScript、TypeScriptのナウいところを勉強できてよかったです。

ではまた!

参考記事

Discussion