新聞コラム表示Webアプリの開発環境選定と実装手順

## 開発要件
今回開発する新聞コラムWebアプリには以下の要件があります：

- **一般ユーザー向け機能**:
  - 新聞コラムの**一覧表示**
  - 個別の**詳細表示**
  - **お気に入り機能**の提供
  - **検索機能**: ワード検索、新聞単位、年月日単位の検索
- **管理者向け機能**:
  - 新聞コラムデータの登録機能（新聞名、コラム名、本文、年月日）
  - **CSVインポート機能**で大量データを一括登録
- **バックエンド機能**:
  - バッチ処理による新聞コラムデータの定期取得と保存
- **インフラ要件**:
  - コンテナ化して環境依存を排除
  - 小規模プロジェクトに適した低コストのデプロイ

## 技術選定
### 1. バックエンドの選定: Go言語
#### 選定理由:

- **高速性**: Go言語はコンパイル型言語であり、高速な処理が可能です。バッチ処理を定期的に行う要件があるため、高速なデータ処理能力が求められました。
- **シンプルさ**: 標準ライブラリが充実しており、HTTPサーバーの構築が簡単です。Ginフレームワークを使えば、ルーティングやJSONレスポンスの処理がシンプルに記述できます。
- **スケーラビリティ**: 将来的にアプリケーションを大規模化する場合でも対応可能です。
##### 他の選択肢:

Ruby On Rails: 開発効率に優れていますが、Goのほうがパフォーマンスに優れています。今回の新聞コラムWebアプリでは以下の理由で高パフォーマンスが求められました：

  - **大量データの処理**: バッチで新聞コラムデータを取得するため、高速に処理できる言語が必要。
  - **検索機能**の負荷: ユーザーが頻繁に検索を行う場合、レスポンス速度を優先する必要がある。

Goはコンパイル型言語であり、ネイティブコードに変換されるため、Rails（Rubyのインタプリタ型言語）よりも高速です。この点が大きな差となりました。

### 2. フロントエンドの選定: Next.js + TypeScript
#### 選定理由:

- **SSR**（サーバーサイドレンダリング）対応: Next.jsはSSRが可能なため、SEOに優れており、検索機能やコラム表示が多い今回のアプリに適しています。
- **開発効率**: TypeScriptを導入することで、型定義による安全性を確保しながらスムーズに開発できます。
- **拡張性**: Next.jsはReactベースで柔軟性があり、将来的な機能追加にも対応しやすいです。
##### 他の選択肢:

React単体: 優れたライブラリですが、SSRやプロジェクト構造を自前で設定する必要があります。Next.jsの方が初期設定が簡単でした。

## 環境構築手順
### 1. プロジェクトフォルダの作成
```
mkdir newspaper-app
cd newspaper-app
```
プロジェクト用のフォルダを作成します。

### 2. フォルダ構成の準備
```
mkdir frontend
mkdir backend
touch docker-compose.yml
```
プロジェクトを```frontend```と```backend```に分割し、```docker-compose.yml```を作成します。

### 3. docker-compose.ymlの設定
#### 3-1. 環境変数の設定
```
touch .gitignore
touch .env
```

```.gitignore
.env
```

```.env
POSTGRES_PASSWORD=password
POSTGRES_DB=db
```
#### 3-2. dokcer-compose.ymlの設定
```dokcer-compose.yml
services:
  backend:
    build:
      context: ./backend/
      dockerfile: Dockerfile
    ports:
      - 8080:8080
    volumes:
      - ./backend:/app 
    depends_on:
      - db
  frontend:
    build:
      context: ./frontend/
      dockerfile: Dockerfile
    volumes:
      - ./frontend:/app
    ports:
      - 3000:3000 
  db:
    image: "postgres:15-alpine"
    ports:
      - "5432:5432"
    env_file:
      - .env
    volumes:
      - db-store:/var/lib/postgresql/data

volumes:
  db-store:
```

### 4. バックエンド環境の設定
#### 4-1. Dockerfileの作成

```
touch backend/Dockerfile
```

```Dockerfile:backend/Dockerfile
FROM golang:latest

WORKDIR /app
```
#### 3-2. Ginフレームワークのセットアップ

```
docker-compose run backend sh
```
コンテナ内で以下を実行：
```
# go mod init github.com/jijimama/newspaper-app
# go get -u github.com/gin-gonic/gin
```
#### 3-3. サンプルコードの作成
```
touch main.go
```

```go:main.go
package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
  router := gin.Default()
	
  router.GET("/", func(c *gin.Context) {
	c.JSON(200, gin.H{
      "message": "Hello, World!",
	})
  })

  router.Run(":8080")
}
```

#### 3-4. Dockerfileの更新
```Dockerfile:backend/Dockerfile
FROM golang:latest

WORKDIR /app

COPY . .

RUN go mod download

RUN go build -o main .

EXPOSE 8080

CMD ["go", "run", "main.go"]
```

#### 3-5. 環境の起動
```
docker-compose up backend --build
```
ブラウザで http://localhost:8080 にアクセスすると以下のレスポンスが返ります：

```
{"message":"Hello, World!"}
```
### 4. フロントエンド環境の設定
#### 4-1. Dockerfileの作成

```
touch frontend/Dockerfile
```

```Dockerfile:frontend/Dockerfile
FROM node:18-alpine

WORKDIR /app
```
#### 4-2. Next.jsのセットアップ

```
docker-compose run frontend sh
```
コンテナ内で以下を実行：
```
/app # rm ./Dockerfile
/app # npx create-next-app . --typescript
/app # touch Dockerfile
```
#### 4-3. Dockerfileの設定

```Dockerfile
FROM node:18-alpine

WORKDIR /app

COPY package.json package-lock.json ./

COPY . .

RUN npm install

RUN npm run build

EXPOSE 3000

CMD ["npm","run","dev"]
```

#### 4-4. 環境の起動
```
docker compose up frontend --build
```
ブラウザで http://localhost:3000 にアクセスしてNext.jsアプリが表示されることを確認します。

## 最後に
以上が新聞コラムWebアプリの開発環境構築手順です。この記事を参考にぜひご自身のプロジェクトにも応用してください！

## 参考文献
https://qiita.com/takakou/items/a01af0515f49e90bd05c