自作webアプリケーション「arXiv Checker」の紹介

# はじめに
ポートフォリオとして、バックエンドに Node.js+Express を、フロントエンドに Next.js を用いて web アプリケーションを作成しました。本記事では、その紹介と作成時に考えていたことなどを共有できればと思います。

# アプリの概要
### 説明
**arXiv Checker** は最新の研究を効率的に閲覧し、把握するために作成されたツールであり、自身の専攻分野を登録しておくと前回ログイン時から更新された論文をタイムライン形式で表示してくれます。
「いいね」のような形式でお気に入り登録した論文はアカウントと紐づけられて保存され、各論文にタグを付けて管理したり、Notion 形式のノートを取ることで内容を整理することが可能です。
また、ノートのシェア機能も備えており、同じ論文を読んでいる他の研究者に自分の取ったノートを公開することでその人の理解を助けることができます。

### リポジトリ
- [フロントエンド](https://github.com/migawari558/arXiv_checker_frontend)
- [バックエンド](https://github.com/migawari558/arXiv_checker_backend)

### アプリケーションページ
- [arXiv Checker](https://arxiv-checker-frontend.vercel.app/)
（デプロイは、フロントを versel に、バックエンドを render にしています。MongoDBのプランが無料枠なので容量がいっぱいになると動作に支障が出てしまう可能性があります。）
> テスト用アカウント
username: test
password: ASdf123456

### 使用技術
- フロントエンド
    - TypeScript
    - React
    - Next.js
    - Redux
    - blocknote
    - chakra ui... など
- バックエンド
    - JavaScript
    - Node.js
    - Express
    - mongoDB
    - mongoose
    - arXiv API... など
- 開発環境
    - docker, docker-compose
    - vscode

### 実装済み機能一覧（おおまかに）
- ユーザー関連
    - 作成、更新、削除機能
    - ログイン、ログアウトのセッションでの管理
- 論文関連
    - 更新論文の自動取得機能
    - 分野、タイトル、概要、フリーワードなどでの検索機能
    - 気になった論文の保存機能
- 保存済み論文関連
    - タグ付け機能
    - ノート作成機能（blocknote）
    - ノートのシェア機能

### ER図
![arxivChecker_er.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3633270/08e4ec85-488c-4366-a960-dbda4f04ac8d.png)

# 動機・作成理由
大学で研究するにあたって様々な論文を読むようになり、それらを体系的に管理できるツールとして「zotero」のような文献管理ツールを利用していましたが、arXiv の査読済みでない論文については
- 引用文献として利用できないので別個で管理したい
- そもそも情報の管理が違うらしくツールでうまく情報を拾えない

という不満点をかかえていました。

また、既存の文献管理ツールは pdf をダウンロードすることを前提に設計されていることが多く、ノートテイキングも「obsidian」や「notion」などの別ツールと連携しないと快適とは言い難い物がありました。

そんな折、「arXivの論文をマチアプのように表示してお気に入りを溜めていけるツールはないのか」というXのポスト（該当リンクを紛失しました……）を見かけ、**「更新論文を確認するツール」と「arXiv 文献についての管理からメモまでを一貫してできるツール」** を作成したら役に立つのではないかと思い製作に至りました。

# 技術選定について
ここには自分なりに技術選定の理由を記載していきます。当方 web アプリケーションの製作はこれが初めてであったため、不適切な記述などがありましたら気軽にご指摘いただければ幸いです。


### 開発環境
開発環境による依存や、共有できない状況の発生を防ぐため、docker を利用して開発環境を構築しました。
以下は、 docker-compose の内容です。フロントエンド、バックエンドの双方に dockerfile を配置し、それらを一括で起動できるようにしています。
``` docker: docker-compose.yaml
version: "3"
services:
  backend:
    image: backend-container
    container_name: backend
    build:
      context: ./backend
    volumes: 
      - ./backend/src:/usr/src/app/src
    ports: 
      - "8000:8000"
    env_file:
      - ./backend/.env
  frontend:
    image: frontend-container
    container_name: frontend
    build:
      context: ./frontend
    volumes: 
      - ./frontend/src:/usr/src/app/src
      - ./frontend/public:/usr/src/app/public
    ports:
      - "3000:3000"
    env_file:
      - ./frontend/.env
```

### フロントエンド
フロントエンドには **Next.js** を採用しました。採用理由は大まかに以下の通りです。
- SSR, SSG, CSR などのレンダリング戦略を柔軟に採用することができ、ページの内容に応じて最適化をすることができる
- Dynamic Routing など、ルーティングが簡易
- ある程度成熟しているため、学習やトラブルシューティング、プラグインなどが豊富であり、またReactの知識が使いやすい

それぞれについての詳細は以下のとおりです。

#### レンダリング戦略
今回のアプリケーションでは、ユーザーの変更を常に反映しなければいけないページ（自身の保存した論文関連）や、長期間変更はないが、ユーザーの情報に応じてレンダリングが必要なページ（timeline）など、それぞれのレンダリング状況が異なると想定されました。

快適な体験のため、CSR や ISR, SSR を適切に区別しながら用いることが重要であると考え、これらの柔軟な利用が可能出る Next.js を採用しました。

#### ルーティング
React を利用した際に必要となる Router Component の設定なく、ディレクトリ関係によって Routing が完成することは非常に簡便で効率的だと感じました。
また、Dynamic Rouing によって、id 等に依存するページも比較的単純に作成できる点は非常に魅力的だと思います。

#### サポート関連
開発に不慣れな状況であったため、ドキュメンテーションが充実していることは個人的に重要でした。その点、歴史もあり利用者が多い Next.js は個人のブログを含む様々なコンテンツが充実しており、学習の面で非常に役に立ちました。
また、React から追加で必要となる知識量が少なめであったことも、短期間での開発に優位であったように思います。

### バックエンド
バックエンドには **Node.js + Express** を採用しました。
大まかな採用理由は以下のとおりです。
- フロントエンドが Next.js であるため、一貫した言語で開発が可能である
- 高度な計算能力+堅牢性を要求しないアプリケーションである

以下それぞれの詳細です。

#### 一貫性
Node.js は Javascript であるため、学習コストや一貫性によるバグの減少などが見込めると考え採用しました。特に学習コストについては、フルスタックでの開発を行う上で両者を同一の言語で書けることは非常に助かりました。また、npm を用いたパッケージの簡易な導入が可能である点も非常に魅力的でした。

#### 特性
今回のアプリケーションにおけるバックエンドの動作はデータの fetch などのトランザクションに終始しており、一般的に指摘される Node.js の課題：「CPU負荷が重いタスクに不向きである」による影響を受けづらいと考えました。また、個人開発の小さなアプリケーションであるため、堅牢性を理由に Java などを選択する理由も薄いかと感じたため、Node.js を採用しました。

### データベース
データベースには **MongoDB** を利用しました。大まかな理由は以下のとおりです。
- Node.js (Javascript) との相性がいい
- 柔軟性が高い

以下に詳細を述べます。

#### Node.js との相性
これが一番の理由です。MongoDB は json ベースのドキュメント型のデータベースであり、json との相性が良い Javascript を利用してバックエンドを開発することを加味すると扱いやすいように思い、採用しました。

#### 柔軟性
今回の開発においては、発展の段階でデータの形式が異なるデータを格納する可能性がありました（arXivだけでない他の形式の論文に対応させるなど）。その際に、柔軟なデータ構造を処理できることが重要となる可能性があり、リレーショナルDB よりも適切な選択肢であると考えました（実際にはそのようなデータ構造への対応はしませんでしたが）。
また、今回のデータは簡便な構造をしているため、リレーショナルデータベースによる強力な一貫性を要求せずとも、整合性を保った開発が可能であると考えました。

## 開発上こだわった点
### 見た目
開発時にはとにかく、「シンプルで、説明書がなくても利用ができるアプリケーション」を目指しました。自身が新しいアプリケーションを導入する際に最も負荷となるように感じるのが「説明を読む」ところだと感じていたためです。
そのため、なるべく「どこかで見たことある」レイアウトを心がけました。実際の論文誌のページや、他ノートアプリの見た目を参考にし、直感的なデザインを行ったつもりです。

### 高速に動作すること
なるべくストレスフリーな動作を心がけました。timeline を ISR にし、表示を高速化したり、入力欄がある場合には component を分割して state を別個管理することでレンダリングを防いだりなどです（軽量なページでは分割していません）。まだ改善の余地はあるかと思いますが。

## 苦労話
### npm パッケージの arxiv api の問題
実は npm のパッケージとして arxiv api を検索するものが提供されています（[これ](https://www.npmjs.com/package/arxiv-api)）。が、こちらで提供されている検索クエリでは所望の動作を実現できませんでした。
そこで、arxiv の公式ドキュメントや当該パッケージなどを参考にしながら、今回必要なクエリを作成する関数を作成しました。最初は途方に暮れていましたがなんとかなってよかったです（笑）。

### session 管理周り
session 管理は、express-session でセッション情報を作成し、mongoDB 内に保存する形式を取っています。session id をフロント側に cookie で返しているのですが、ここでトラブルが起きました。
Next.js 側ではデータの fetch をサーバーアクションで行っているのですがそのままだと cookie がブラウザに届かず、サーバーサイドで止まってしまうため session id がクライアントに届かなかったのです。
そこで、以下の記事（[これ](https://qiita.com/P-man_Brown/items/52c5a14d2ffc4493f98b)）を参考にしながらクライアント側にクッキーをセットする実装を行いました。

### Next のバージョン問題
Next.js は 15 以降、仕様が大きく変更されています。そのため、迂闊に検索をすると仕様変更前の記事がヒットしてしまい、エラーを吐くというのが何度もありました。
これに関しては公式のドキュメントを読むのが結局一番参考になるという結論に落ち着きました。英語を怖がらずに最初から読んでおけばよかったです（笑）。

## 課題
今後の開発などに向けた課題として感じたことをまとめておきます。

### コードの保守性
ある程度意識しながら開発していたものの、バグや仕様変更をしたいときに少し触りにくいと感じるコードになってしまっている部分がありました。チーム開発などをするうえでこれは致命的になりうると感じたので、（大枠の機能を作成することには慣れたという現状を踏まえると）次回以降の作品ではもう少し保守性を意識した設計にしていきたいと感じています。並行して、リファクタリングも進めていけたらと思っています。

### OAuth認証
今回の開発ではアカウント情報にメールアドレスを要求しない形式としましたが、例えば新着論文情報のメール配信などの機能を実装する場合やパスワード忘れへの対処を考える場合、この機能は必須となります。そして、それに伴ってOAuthを利用したログイン機能があると便利なのではないかと感じました。次回以降の作品では挑戦してみたい内容です。

### スマホ対応
スマホに適切に対応したUIにはなっていないので、今後そういった対応ができるアプリケーションが作成できればと思っています。

# 最後に
ここまで読んでいただきありがとうございました。初めての web アプリ開発でしたが、なるべく仕様の裏を追いかけながら開発したおかげか、普段目にしているものがどう動作しているのかをかなり把握できて良い勉強になったように感じます。
まだまだ未熟なアプリケーションですので、知人などにフィードバックをもらいつつ改善して行ければと思っています。

### 今後実装予定の機能や改善点
フィードバックなどから改善点などを列挙していきます。
- タグでの保存論文の検索機能の追加
- 保存論文のフォルダリング機能の追加
- タグ追加がどこからできるかがわかりにくいことの改善
- ヘルプページのｔ
- etc...