私が歌川です

@utgwkk が書いている

YouTube Data APIをラップしたGraphQL APIを作る

はじめに

表題のものを途中まで作った。指定したチャンネルにアップロードされた動画ぐらいは取れるというステータス。

developers.google.com

基本的にはAPIドキュメントを読みながらGraphQLスキーマを作ってリゾルバを実装していけばよい。けど、このAPIでは欲しいデータが取得できないということに気づいて中断したので、途中だけど載せておきます。↓こういうクエリで一気にデータを取得できる。

query ChannelUploadsQuery($id: ID!) {
  channel(id: $id) {
    title
    uploads: relatedPlaylist(key: UPLOADS) {
      items(first: 100) {
        pageInfo {
          hasNextPage
          endCursor
        }
        edges {
          node {
            position
            video {
              id
              title
              publishedAt
              duration
            }
          }
        }
      }
    }
  }
}

動機

REST APIで各リソースの子リソースを辿ろうとすると、リソースが変わるごとにAPIリクエストを都度発行する必要があり、手元でちょっと試すのには不便。GraphQL APIにしておいたらフィールドを指定するだけで所望のAPIを叩いていってくれるので便利なんじゃないかと思ってやってみた。

実装

github.com

graphql-jsとTypeScriptを使ってすごく素朴にリゾルバを実装していった。静的型の恩恵を受けるなら違う道具を使ったほうがいいと思う。graphql-jsだと型注釈にコツが要る。

みどころ

51件以上一気に取得する

YouTube Data APIでは maxResults パラメータでデータの取得件数を指定できるが、最大値は50になっている。つまり、51件以上のデータを一気に取得したい場合はリクエストを分割する必要がある。ので、50件ずつデータを取得して、指定された件数になるまで順に詰めていく処理を実装している。ページングする必要があるのでリクエストは直列になってしまう。

https://github.com/utgwkk/youtube-data-graphql-api/blob/267fe041642d824e35d5c0e294e0fdab7dcedcd6/src/schema/playlist.ts#L44-L89

dataloader

PlaylistItemを複数件取得したあと、PlaylistItemに紐づくVideoを取得するには別のAPIを叩く必要がある。1リクエストずつ送っているとレイテンシが増大するしAPIのレートリミットにも引っかかりやすいと思うので、できるだけリクエストをまとめたい。dataloaderを使うとサクッとできる。

これも51件以上データを取得するときはリクエストを分割する必要があることに注意する。こっちはidの配列を渡せばよいので並列にリクエストを送れる。

https://github.com/utgwkk/youtube-data-graphql-api/blob/267fe041642d824e35d5c0e294e0fdab7dcedcd6/src/dataloader.ts#L6-L23

全然関係ないけど、chunk関数を手作りする機会が多い気がする。

おわりに

みなさまも好きなREST APIをGraphQL APIとしてラップしてみてはいかがでしょうか。