Qiita API で Qiita 全体の毎日の投稿数を取得して表示する

# Qiita API で記事一覧を取得したときの合計件数

たとえば Qiita のウェブ版で記事を検索したとき、ヒットした結果の全体件数は「すべて」の横に数字が表示されています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27471/8ec89131-c2f6-9f9a-77a7-57134e150a10.png)

API でもこれと同じ数字を取得する手段が用意されていて、レスポンスボディには記事一覧が入りますが、合計件数はレスポンスヘッダーに含まれて返ってくるようになっていました。API ドキュメントでは以下のように書かれています。

> ページを指定できるAPIでは、要素の合計数が `Total-Count` レスポンスヘッダに含まれます。

https://qiita.com/api/v2/docs#%E3%83%9A%E3%83%BC%E3%82%B8%E3%83%8D%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3

実際にブラウザでアクセスして確認してみました。

- [`https://qiita.com/api/v2/items?query=created:>=2023-07-06 created:<=2023-07-06`](https://qiita.com/api/v2/items?query=created:%3E=2023-07-06%20created:%3C=2023-07-06)

Chrome のデベロッパーツールで見てみると、`Total-Count` レスポンスヘッダが含まれています。（ウェブ版のスクリーンショットを撮ったときより2件増えていました :smile: ）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27471/e81c7141-d881-b46f-2454-736b34073a02.png)

# 毎日の投稿数を取得する

上記の確認でも使っていたのですが、検索オプションを利用して記事の投稿日による絞り込みが可能です。

https://qiita.com/yonex/items/d3ade7c1ae9897536b28

ちょうど [Qiita Engineer Festa 2023](https://qiita.com/official-campaigns/engineer-festa/2023) というイベントが開催中だったので、開催期間中の日ごとの投稿数を出してみたいと思います。

https://qiita.com/official-campaigns/engineer-festa/2023

日付を指定して投稿数を取得するコードを TypeScript で作成しました。

```typescript
// Qiita API のアクセストークンを環境変数から取得
const accessToken = process.env.QIITA_API_ACCESS_TOKEN
// イベント開催期間中の日付を表す型
type QiitaFestaDate = "2023-06-14" | "2023-06-15" | "2023-06-16" | "2023-06-17" | "2023-06-18" | "2023-06-19" | "2023-06-20" | "2023-06-21" | "2023-06-22" | "2023-06-23" | "2023-06-24" | "2023-06-25" | "2023-06-26" | "2023-06-27" | "2023-06-28" | "2023-06-29" | "2023-06-30" | "2023-07-01" | "2023-07-02" | "2023-07-03" | "2023-07-04" | "2023-07-05" | "2023-07-06" | "2023-07-07" | "2023-07-08" | "2023-07-09" | "2023-07-10" | "2023-07-11" | "2023-07-12" | "2023-07-13" | "2023-07-14" | "2023-07-15" | "2023-07-16" | "2023-07-17" | "2023-07-18" | "2023-07-19" | "2023-07-20" | "2023-07-21"

// 日付を指定して、その日の投稿数を取得する関数
async function fetchTotalCountByDate(date: QiitaFestaDate): Promise<number> {
  // 投稿数だけが欲しい場合には記事本体の情報は不要なので、
  // page=1&per_page=1 とすることで最小のレスポンスになるようにし、
  // 投稿数の情報をレスポンスヘッダーから取得するのがよいと思う。
  // なお、per_page=0 は無理
  const params = new URLSearchParams({
    page: 1,
    per_page: 1,
    query: `created:>=${date} created:<=${date}`
  })
  const response = await fetch(
    `https://qiita.com/api/v2/items?${params}`,
    {
      headers: {
        'Authorization': `Bearer ${accessToken}`,
      },
    }
  )
  return (response.headers.get("Total-Count") || 0) as number
}
```

こちらを日数分のループで実行することで、毎日の投稿数を取得できました。実際に表示してみると、このような具合です。毎日とてもたくさんの記事が投稿されていますね！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27471/b6c1ad09-f401-e762-6e2c-5204fce34b14.png)

# おまけ：日付を表す文字列の型

ところで、このコードにおける `QiitaFestaDate` のような型をもっと上手く表現できないものでしょうか？

```typescript
// イベント開催期間中の日付を表す型
type QiitaFestaDate = "2023-06-14" | "2023-06-15" | "2023-06-16" | "2023-06-17" | "2023-06-18" | "2023-06-19" | "2023-06-20" | "2023-06-21" | "2023-06-22" | "2023-06-23" | "2023-06-24" | "2023-06-25" | "2023-06-26" | "2023-06-27" | "2023-06-28" | "2023-06-29" | "2023-06-30" | "2023-07-01" | "2023-07-02" | "2023-07-03" | "2023-07-04" | "2023-07-05" | "2023-07-06" | "2023-07-07" | "2023-07-08" | "2023-07-09" | "2023-07-10" | "2023-07-11" | "2023-07-12" | "2023-07-13" | "2023-07-14" | "2023-07-15" | "2023-07-16" | "2023-07-17" | "2023-07-18" | "2023-07-19" | "2023-07-20" | "2023-07-21"
```

詳しい人がいたら聞いてみたいです。いったん ChatGPT さんに聞いてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27471/4d48b4ed-8ecf-f95f-c811-d06f595e6077.png)

たしかに Template Literal Types を利用することで、コードは少し見やすく短く書けそうです。ChatGPT の回答を修正してみました。

```typescript
type QiitaFestaDate = `2023-06-${14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30}` |
  `2023-07-${"01" | "02" | "03" | "04" | "05" | "06" | "07" | "08" | "09" | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21}`

const qiitaFestaDates: QiitaFestaDate[] = [
  "2023-06-14",
  "2023-06-15",
  "2023-06-16",
  //...(省略)...
  "2023-07-19",
  "2023-07-20",
  "2023-07-21",
]
```

const の生成については、実際は Date クラスを使ってループで生成したほうがいいかもしれません