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にデプロイとかできると面白そうです。
参考リンク
自己紹介サイト