GitHubpagesに自己紹介サイトを立てて少しずつ拡張しています。
今回、サイトにQiita記事へのリンクを貼りたい、けどリンクをペタペタ貼るのもつまらないということで、QiitaApiから私が書いた記事を取得しサイトに表示することにしました。
準備
yarn add @nuxtjs/axios
QiitaのPATを使用する
Qiitaの設定でPATを生成、axiosのヘッダーに登録します。
ここではQiitaApiクラスを作成し、asyncData(ctx:Context)などで使用できるようにします。
(ここでは型定義の紹介は省きます)
import { Plugin } from '@nuxt/types'
import QiitaApi from '~/api/QiitaApi'
import { QiitaApi as MockApi } from '~/mock/QiitaApi' // テストとかではモックに切り替えたい願望
import IApi from '~/types/Qiita/Api/v2/IApi'
// vueインスタンスから$qiitaApiを使用可能にする
declare module 'vue/types/vue' {
  interface Vue {
    $qiitaApi: IApi
  }
}
// this.$nuxt.contextから$qiitaApiを使用可能にする
declare module '@nuxt/types' {
  interface NuxtAppOptions {
    $qiitaApi: IApi
  }
  interface Context {
    $qiitaApi: IApi
  }
}
export const apiPlugin: Plugin = (context, inject): void => {
  const qiitaAxios = context.$axios.create({
    // baseURL: context.$config.baseURL
    baseURL: 'https://qiita.com/api/v2/',
    headers: { 
      // 環境変数に設定したQiita PATを登録
      Authorization: 'Bearer ' + process.env.PAT
    }
  })
  inject('qiitaApi', new QiitaApi(qiitaAxios))
}
export default apiPlugin
GET /api/v2/authenticated_user/itemsを使用することで、PATを設定したユーザーの記事を取得できます。
import { NuxtAxiosInstance } from '@nuxtjs/axios'
import { PostData } from '~/types/Qiita/Api/v2/datas'
import IApi from '~/types/Qiita/Api/v2/IApi'
export default class QiitaApi implements IApi {
  private readonly axios: NuxtAxiosInstance
  constructor (axios: NuxtAxiosInstance) {
    this.axios = axios
  }
  public async getMyQiitaItems (): Promise<PostData[]> {
     const url = 'authenticated_user/items'
     try {
       const response : PostData[] = await this.axios.$get(url)
       return response
     } catch (e) {
       return Promise.reject(e)
     }
  }
}
APIから取得する記事のタイプ
/**
 * 投稿データ
 * https://qiita.com/api/v2/docs#%E6%8A%95%E7%A8%BF
 * */
export interface PostData{
  /** HTML形式の本文 */
  rendered_body:string
  /** Markdown形式の本文 */
  body:string
  /** この記事が共同更新状態かどうか (Qiita Teamでのみ有効) */
  coediting:boolean
  /** この記事へのコメントの数 */
  comments_count:number
  /** データが作成された日時 */
  created_at:string
  /** Qiita Teamのグループを表します。 */
  group:any
  /** 記事の一意なID */
  id:string
  /** この記事への「LGTM!」の数(Qiitaでのみ有効) */
  likes_count:number
  /** 限定共有状態かどうかを表すフラグ (Qiita Teamでは無効) */
  private:boolean
  /** 絵文字リアクションの数(Qiita Teamでのみ有効) */
  reactions_count:number
  /** 記事に付いたタグ一覧 */
  tags:any
  /** 記事のタイトル */
  title:string
  /** データが最後に更新された日時 */
  updated_at:string
  /** Qiita上のユーザー情報 */
  user: any
  /** 記事のurl */
  url:string
  /** Qiita上のユーザーを表します。 */
  page_views_count:number | undefined
  /** Qiita Teamのチームメンバー情報を表します */
  team_membership: any
}
QiitaのPATを使用しない
publicリポジトリでGithub pages使うとenvファイルに書いたPATが丸見えになってしまうので他の方法を考えます。(もしかしたらGithubのsecretsなどをうまく使用する方法があるのかもしれませんが、現状思い浮かばなかったので...)
GET /api/v2/itemsで取得します。
まだ、大した記事数ではないのでpageやper_pageパラメータは使用せず、検索クエリパラメータqueryのみ使用します
import { NuxtAxiosInstance } from '@nuxtjs/axios'
import { PostData } from '~/types/Qiita/Api/v2/datas'
import IApi from '~/types/Qiita/Api/v2/IApi'
export default class QiitaApi implements IApi {
  private readonly axios: NuxtAxiosInstance
  constructor (axios: NuxtAxiosInstance) {
    this.axios = axios
  }
  public async getMyQiitaItems (): Promise<PostData[]> {
    const url = 'items'
    try {
      const response: PostData[] = await this.axios.$get(url, {
        params: {
          query: 'user:sYamaz'//ユーザー名でフィルタリング
        }
      })
      return response
    } catch (e) {
      return Promise.reject(e)
    }
  }
}
終わりに
@nuxt/axiosを使ってQiitaApiにアクセスし、自分の記事一覧を取得することができました。
ただし、使用制限(認証あり:1000回/時、認証なし:60回/時)があったり、記事自体そこまで頻繁に更新するものでもないことから、今回のような目的の場合はスクリプトなどでコードを自動生成するような方法の方が適していると思います。
Github Actionを使って定期的にApiアクセス&コード自動生成→コミット/マージ→Github Pagesにデプロイとかできると面白そうです。
参考リンク
自己紹介サイト