へび年🐍にPython始めました

# はじめに

**「Next.js + TypeScriptのバックエンドは何を選ぶべき？」**

この度、個人開発でWebアプリケーションを開発するにあたって、バックエンドの技術選定を行いました。

候補としては

- Ruby (Rails)
- Go
- Python (FastAPI)

の3つがあがり、最初は「Railsでいいのでは？」と思いつつ、Goも気になっていましたが、結果として**Python (FastAPI)** を採用しました🐍

この記事では、Pythonを採用した理由と、他の候補であったRubyやGoとの比較についてまとめていければと思います。

# 前提
・Webアプリケーションサービスを作成する
・フロントエンドはNext.js＋TypeScript
・バックエンドを新規作成する(予定)
・スキルセットとして、JavaとRuby(Rails)の開発経験あり


# Pythonを採用した理由
## 1.新しい言語をやってみたかった

新しい技術を習得することで、エンジニアとしての幅を広げたいという思いがありました。

もともとRubyを使っていたこともあり、Pythonは比較的学習コストが低く、文法がシンプルで読みやすいため、スムーズに習得できるかなと（直感で）感じました。
※実際に本屋でPythonの入門本を立ち読みしたところ、割と内容がスッと入ってきたのも結構決め手になりました。

## 2. FastAPIが書きやすかった

RailsもGoもそれぞれ魅力的でしたが、FastAPIは
- **Pydanticによる型安全**
- **非同期処理が標準対応**
- **Swagger UIでAPIドキュメントが自動生成**

という点が魅力でした。

::: note info
Pydantic：リクエストの型チェックができるデータバリデーションのライブラリ
:::

例えば、こんなコードを書くだけでAPIのリクエストバリデーションができます。

```python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    in_stock: bool

@app.post("/items/")
def create_item(item: Item):
    return {"message": f"{item.name}を登録しました"}
```

このレベルの型チェックが「RailsやGoよりも楽」にできるのは、個人的にはめちゃくちゃ快適でした。

ただ、以下のようなデメリットもあるので、FastAPIを選択する際は注意が必要になります。

- FastAPIは比較的新しいフレームワークなので、**認証や権限管理周りなどはRailsほど成熟していない**ことです。

>例えば、RailsではDeviseやPunditといったライブラリが存在する一方で、FastAPIでは認証関連の実装をよりカスタマイズする必要があります。

- **公式なORMは用意されていない**ため、SQLAlchemyなどを活用する必要があります。


## 3.機械学習を使ってみたかった
将来的に、データ分析や機械学習の機能を組み込みたいなと考えていました。
Pythonはその分野で非常に強力な言語ということもあり、特に以下の点が魅力的でした。

- 豊富なライブラリ
    - 機械学習やAI開発に必要なライブラリが充実していて、scikit-learn, TensorFlow, PyTorchなどを活用すれば高度なモデルを簡単に導入できる点
- データ処理のしやすさ
    - Pandas, NumPy などのライブラリを使うことで、データの前処理や分析が効率的に行える点

単なるWebアプリの開発だけでなく、将来的にデータ分析機能を追加しやすい点も、Pythonを選んだ理由の1つです。
※実際に使うかは別として、「あのときPythonにしとけば良かった...」を避けたかったというのもあります。

# 他言語との比較検討
Pythonの他に、開発経験のある**Ruby**と、未経験ながら興味があった**Go**を候補に挙げて比較しました。

## Ruby
### ✅ メリット
- 開発生産性が高い
    - Rails のエコシステム (Active Record, Scaffolding など) により、短期間での開発が可能
- エレガントなコード
    - DSL (Domain-Specific Language) が充実しており、可読性が高い
- GraphQL対応
    - GraphQL API構築が容易 (例：graphql-rubyライブラリを活用する)

### ❌ デメリット
- 非同期処理が弱い
    - Goに比べると、リアルタイム性の高い処理には不向き
- スケーラビリティに課題
    - 高トラフィック環境だと、キャッシュの最適化やデータベースの分割、バックグラウンドジョブの活用などの適切なチューニングが必要になる

### その他
::: note ingo
Rubyでも、dry-schema や ActiveModel::Validations を使えば、型チェックを強化することはできます。
:::

### ▶ 採用しなかった理由
FastAPIではstrawberryなどのライブラリを用いることでGraphQL APIを実装できるということもあり、総合的に判断してRailsを選ぶ決定打がなかったので、今回は見送ることにしました。

## Go
### ✅ メリット
- 超高速な処理
    - Goroutineによる並行処理が可能なため、非同期処理に強い
- 静的型付け
    - 型安全でバグを防ぎやすい
- クロスコンパイル可能
    - バイナリ単体での配布が可能なため、デプロイが容易

### ❌ デメリット
- エコシステムが発展途上
    - 特にWebフレームワーク周りでは、FastAPIやRailsほどの成熟度はない
- 記述量が多い
    - Goは静的型付けのため、型定義を明示する必要があり、エラーハンドリングの記述もPythonやRubyに比べると冗長になりがち
    - また、インターフェースの実装も明示的に行う必要があるため、コード量が増える傾向にある。

**例：エラーハンドリングの比較**
・Go
``` Go
package main
import (
    "errors"
    "fmt"
)

func doSomething() error {
    return errors.New("Something went wrong")
}

func main() {
    if err := doSomething(); err != nil {
        fmt.Println("Error:", err)
    }
}
```

・Ruby
``` Ruby
def do_something
  raise "Something went wrong"
end

begin
  do_something
rescue => e
  puts "Error: #{e.message}"
end
```

・Python
``` Python
def do_something():
    raise Exception("Something went wrong")

try:
    do_something()
except Exception as e:
    print(f"Error: {e}")
```

### ▶ 採用しなかった理由
Goはパフォーマンス面では非常に優秀であるものの、APIサーバーとしての開発スピードや拡張性を考慮すると、Pythonのほうが適していると判断しました。
※個人開発のため、そこまで高いパフォーマンスは求めていないことも理由の1つです。

（ただ、Goは本を読んでみて、実装してみたいと思ったのでいつか挑戦したい…！）

# まとめ
Python(FastAPI)を選んだ理由は、

- 非同期処理 & 型安全性 → Next.js + TypeScriptとの相性が良い

- 学習コストが低い → Pythonは比較的簡単に習得できる

- 将来的な機械学習活用 → Pythonなら拡張しやすい

という点でした。

今回は採用しなかったものの、RubyやGoも強力な選択肢ではあるので、この記事が「Next.js＋TypeScript」と組み合わせるバックエンド検討時の1つの参考になれば幸いです。