フューチャー技術ブログ

「業務を通じて学ぶ」vs「業務外で学ぶ」Vue.jsで人気曲ランキングを当てるWebアプリを作ってみた

フューチャー夏休みの自由研究連載の3本目です。

はじめに

はじめまして。TIG DXユニットの佐々木です。

2022年4月に新卒入社し、7月からプロジェクトに参画しています。

未経験の技術が採用されている開発にも携わっているのですが、技術のキャッチアップ方法には試行錯誤の毎日です…!!

今回は自由研究企画ということで「業務を通じて学ぶ」と「業務外で学ぶ」のどちらが良いのかについて、実際に業務外で技術をキャッチアップした結果を基に整理したいと思います!

なぜ業務を通じて学ぶことに試行錯誤しているのか

そもそも私がなぜ業務を通じて学ぶことに試行錯誤しているかを振り返ってみました。
自分なりに考える主な要因はここら辺なのかなと思っています。

  • 期限内にアウトプットを出すために短期間でキャッチアップするため、断片的な知識が蓄積されがちで、なんとなく分かる・書ける状態になりやすい
  • システムの基盤が既に完成しているため、既存のソースコードを応用することで担当するアウトプットが作れる

なるべくチームメンバー全員がシステム・技術を体系的に理解している状態で成果を出せるようになる状態が理想だとは思うのですが、現状のままでは難しいなと感じています。
そこで業務外で体系的に学ぶべく、プロジェクトで採用されている技術を用いて簡単なアプリを作りました!

作ったアプリの紹介

各アーティストの人気曲ランキングを当てる簡単なWebアプリを作りました。
操作イメージ.gif

使用技術

実際にプロジェクトで採用されている技術を模倣しました。

  • Vue.js
  • TypeScript
  • Vuetify(UIフレームワーク)

楽曲データ源

各アーティストの楽曲データは無料で公開されているSpotifyのWebAPIを使用して取得しました。
Spotifyに登録されている全アーティストの楽曲情報を取得することができます。

「業務外で学ぶ」のメリット・デメリット

プロジェクトで採用されている技術を用いてアプリを作ることで以下のようなメリット・デメリットがありました。

メリット

  1. 仕様・言語に慣れて業務中のソースを読む速度が上がった
  2. 普段は気にかけていなかった部分のコードの意味も考えるようになった
  3. 公式ドキュメントや記事を読む時間が増えた
  4. コンポーネント設計やライブラリ選定など、普段の業務では考えない領域に触れられた
  5. 採用されている技術のことがちょっと好きになった

デメリット

  1. 自分の理解・ソースが間違っていないか議論できない
  2. 業務との頭の切り替えが必要でいつもよりチョット疲れが溜まっている感じがする

「業務を通じて学ぶ」 vs 「業務外で学ぶ」

業務外で学ぶことのメリットをたくさん発見しましたが、私の中での優勝は・・・
「業務を通じて学ぶ」 です!!

メインの理由は以下の3点です。

  1. 業務外で学ぶメリットの1番〜3番は工夫次第では業務を通じても獲得できる
  2. 間違った理解をしていた時にはチームメンバーと議論できる
  3. 何より業務時間の方が基本的に長いので、長い目で見るとその時間を有効活用する考え方が大事そう

個人開発をするのは業務では触れられない興味のある領域を開発したいときかなと思いました。
もっと言えば興味のある領域を仕事にしたい!

まとめ

これから長く続くエンジニア・コンサルとしての道のりですが、働き方を自分なりに考えて工夫する必要があるなと感じました。
また、改めてチームメンバーの皆さんと議論できる機会があることのありがたさを実感しました!

おまけ

今回はSpotifyが提供する外部APIから楽曲データを取得してアプリを作成しました。
その中で外部APIを用いるがゆえに沼った箇所がありましたので、その時に得た知見を記します!

非同期通信を並列で処理する

SpotifyのWebAPIではアーティストの全楽曲を直接取得するAPIは用意されていません。

全楽曲を取得するためには以下の2つのAPIを用いる必要がありました。

  • アーティストの全シングル・アルバムを取得するAPI
  • シングル・アルバムに収録されている全楽曲を取得するAPI

全楽曲取得後にデータを加工する必要があるため、次のような非同期通信のコードを書きました。

// アーティストの全シングル・アルバムを取得
async function getArtistAlbums(){
}

// シングル・アルバムに収録されている全楽曲を取得
async function getAlbumTracks(album){
}

async function main(){
...
const albums = await getArtistAlbums()
for (var album of albums){
await getAlbumTracks(album)
}
// 加工処理
}

しかし、forの中でawaitを用いることでアーティストが公開しているシングル・アルバム数に比例して処理時間が長くなってしまいます。

そのためPromise.all()を用いることでawait処理をループの外に置き、並列で実行されるようにしました。

これで下図のように処理時間を大幅に短縮することができました。

// アーティストの全シングル・アルバムを取得
async function getArtistAlbums(){
}

// シングル・アルバムに収録されている全楽曲を取得
async function getAlbumTracks(album){
}

async function main(){
...
const albums = await getArtistAlbums()
// Promiseインスタンスを配列化
const promises = []
for (var album of albums){
promises.push(getAlbumTracks(album))
}
await Promise.all(promises)
// 加工処理
}
並列化

非同期通信の並列数を制御する

SpotifyのWebAPIでは、秒間あたりのアクセス数が制限されていることから、先程のコードを用いて大量のリクエストを同時に投げると一部のリクエストからエラーが返ってきてしまいました。そこで、外部APIへのリクエストの並列数を制限することを試みました。

使用したのはp-mapというライブラリです。このライブラリを用いることで並列数を制御しつつPromise.all()と同等のことを実現できました。

また、今回は使用しませんでしたが、返ってくるレスポンスの内容に応じて後続のリクエストの制御を実施することもできます。

import pMap from 'p-map'

// アーティストの全シングル・アルバムを取得
async function getArtistAlbums(){
}

// シングル・アルバムに収録されている全楽曲を取得
async function getAlbumTracks(album){
}

async function main(){
...
const albums = await getArtistAlbums()
// 並列処理数を5個に制限
await pMap(albums, getAlbumTracks(), {concurrency: 5})
// 加工処理
}

これで下図のようにSpotifyへの同時リクエスト数が一定数を超えないように制御しながら高速に処理を行うことができるようになりました。
並列数を制限.png

おわりに

今回は自由研究ということで技術のキャッチアップの方法についてまとめてみました。

個人的にアプリ設計を自分で考えるところが楽しかったのでまた機会があれば取り組もうと思います。

今後はもっと技術に踏み込んだ記事を執筆していけたらと思います!