Rails8 apiモードのskipオプション比較

# Rails8
Rails4ごろから使ってきて、既に5世代目。
最近の開発ではRailsはバックエンドapiでしか使用していないが、Active RecordやActive Modelは便利だし、今後もRailsは使っていくと思う。

# apiモード
ということでRailsはフロントエンドからjsonが取得できればそれでいい。Rails8のapiモードで何をskipすればいいのかを検証してみた。

## 前準備
+ projectディレクトリを作成し、compose.yamlを作成
```sh:
mkdir project
cd project && touch compose.yaml
```
+ backendディレクトリを作成し、更に配下にapiディレクトリを作成
```sh:
mkdir backend && mkdir backend/api
```
+ 必要ファイル(Dockerfile,Gemfile,Gemfile.lock)作成
```sh:
cd backend && touch {Dockerfile,Gemfile,Gemfile.lock}
```
##### この時点でのディレクトリ構成
```sh:
project/
├── backend/
│   ├── Dockerfile
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── api/
└── compose.yaml
```
+ Dockerfile
```docker:Dockerfile
FROM ruby:3.3.0
ENV APP /api
ENV TZ Asia/Tokyo
WORKDIR $APP
ADD Gemfile $APP/Gemfile
ADD Gemfile.lock $APP/Gemfile.lock
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```
+ Gemfile
```ruby:Gemfile
source 'https://rubygems.org'
gem "rails", "~> 8.0.0"
```
+ compose.yaml
```yaml:compose.yaml
services:
    apitest:
        build: ./backend/
        platform: linux/x86_64
        environment:
          TZ: Asia/Tokyo
        volumes:
          - type: bind
            source: ./backend/api
            target: /api
          - type: volume
            source: gemdata
            target: /usr/local/bundle
        ports:
          - "3000:3000"
volumes:
   gemdata:
```
# ノーマルのrails new --api(--skipオプションをつけない)
まずはノーマルのapiモードでrails newしてみる
```sh:
docker compose run --rm apitest rails new . --api
```
ずらずらずら
```sh:
[+] Creating 2/0
 ✔ Network apitest_default   Created                                                                                                                         0.1s 
 ✔ Volume "apitest_gemdata"  Created                                                                                                                         0.0s 
[+] Building 68.6s (11/11) FINISHED                                                                                                               docker:orbstack
 => [apitest internal] load build definition from Dockerfile                                                                                                 0.0s
 => => transferring dockerfile: 230B                                                                                                                         0.0s
 => [apitest internal] load metadata for docker.io/library/ruby:3.3.0                                                                                       12.9s
 => [apitest internal] load .dockerignore                                                                                                                    0.0s
 => => transferring context: 2B 
 ####以下略#####
 ```
api以下にrails8のファイルが作成された。

### この状態でrailsを起動
```sh:
docker compose up -d
```
Rails8が起動した！DBの設定をしなくとも起動するようだ。
![スクリーンショット 2025-01-11 18.44.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82975/8381ccfb-4eb2-95f1-edb5-b0b60bd49348.png)


### 気になるのはdatabase.yml
何もskipしない状態のapiモードだと、database.ymlにはcacheやqueue、cableのDB設定の項目がある。
```yaml:database.yml
####前略########

# Store production database in the storage/ directory, which by default
# is mounted as a persistent Docker volume in config/deploy.yml.
production:
  primary:
    <<: *default
    database: storage/production.sqlite3
  cache:
    <<: *default
    database: storage/production_cache.sqlite3
    migrations_paths: db/cache_migrate
  queue:
    <<: *default
    database: storage/production_queue.sqlite3
    migrations_paths: db/queue_migrate
  cable:
    <<: *default
    database: storage/production_cable.sqlite3
    migrations_paths: db/cable_migrate
```
### スキップする前にRails8の各機能について

https://qiita.com/ryohashimoto/items/2be94159653e75d741c4

おさらいの意味も含めて、rails newのskipコマンドを見てみて、要否の判断をしてみる。
# skipしてもよさそう
+ --skip-docker
 Skip Dockerfile, .dockerignore and bin/docker-entrypoint
 → Dockerで構築しているのに、更にDockefileを作る。不要
+ --skip-action-mailer
+ --skip-action-mailbox
+ --skip-action-text
 → Action Mailer,Action Mailbox,Action Textは使用しない
+ --skip-active-job
+ --skip-action-cable
 → activejob(queue機能)は使用しない
 → activecable(websocket通信)は使用しない
+ --skip-asset-pipeline
 → apiモードではアセットは使用しない
+ --skip-javascript
 → apiモードではjavascriptは使用しない
+ --skip-hotwire
 → 他のフロントエンドフレームワークReact、Vue.js、Angularなど、別のJavaScriptフレームワークやライブラリを使用してインタラクティブなUIを作成する場合、Hotwireは不要
+ --skip-jbuilder
 → apiはjsonを返すので一見必要そうに見えるが、render jsonを返す場合は必要なし
+ --skip-test
 → キリッ
+ --skip-system-test
 → APIでシステムテストはしないため不要
+ --skip-thruster
 → HTTP/2プロキシ「Thruster」APIモードには不要
+ --skip-rubocop
 → rubyコードの静的チェック。不要
+ --skip-brakeman
 → Brakemanとはソースコードに、SQLインジェクションやXSS等の脆弱性がないかを解析してくれるGem。不要
+ --skip-ci
 → GitHub CI filesを生成しない
+ --skip-kamal
+ --skip-solid
 → Rails8の機能であるkamalもSolid Cache,Queue,Cableも必要ない
+ --skip-devcontainer
 → devcontainerは使用しない
+ --skip-edge
 → 最新の Rails 開発版を使用して作成するためのもの。不要
+ --skip-main
 → gitのmainブランチをGemfileにむにゃむにゃ（よくわからんが不要）
# skipしない方がよさそう
+ --skip-git
 Skip git init, .gitignore and .gitattributes
 → git関連のファイルを作成しない。あったほうがいい
+ --skip-keeps
 Skip source control .keep files
 → .keepファイルは空のディレクトリの中に配置されて、空のディレクトリをGitに含めるために使用する。あったほうがいい
+ --skip-active-record
 → Active Recordは使用する
+ --skip-active-storage
 → フロントからファイルアップロードを行う場合があるので使用する
+ --skip-bootsnap
 → bootsnapは起動を高速化させるので必要
+ --skip-dev-gems
 → developmentのgemは必要
# これを踏まえてskip版コンテナを作成する
比較のためにskip版コンテナ用のbackend2を作成する
projectディレクトリ直下に移動してmkdir
```sh:
mkdir backend2 && mkdir backend2/api
```
```sh:
cd backend2 && touch {Dockerfile,Gemfile,Gemfile.lock}
```
#### この時点でのディレクトリ構成
```sh:
project/
├── backend/
│   ├── Dockerfile
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── api/
├── backend2/
│   ├── Dockerfile
│   ├── Gemfile
│   ├── Gemfile.lock
│   └── api/
└── compose.yaml
```
+ Dockerfile(backend2側)
```docker:Dockerfile
FROM ruby:3.3.0
ENV APP /api
ENV TZ Asia/Tokyo
WORKDIR $APP
ADD Gemfile $APP/Gemfile
ADD Gemfile.lock $APP/Gemfile.lock
RUN bundle install
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```
+ Gemfile(backend2側)
```ruby:Gemfile
source 'https://rubygems.org'
gem "rails", "~> 8.0.0"
```
+ compose.yaml
compose.yamlでskip版のコンテナを設定する
GemのVolumeも分ける
```yaml:compose.yaml
services:
    apitest:
        build: ./backend/
        platform: linux/x86_64
        environment:
          TZ: Asia/Tokyo
        volumes:
          - type: bind
            source: ./backend/api
            target: /api
          - type: volume
            source: gemdata
            target: /usr/local/bundle
        ports:
          - "3000:3000"
    # 以下はskip版コンテナの設定
    apiskiptest:
        build: ./backend2/
        platform: linux/x86_64
        environment:
          TZ: Asia/Tokyo
        volumes:
          - type: bind
            source: ./backend2/api
            target: /api
          - type: volume
            source: gemdata2
            target: /usr/local/bundle
        ports:
          - "3001:3000"
volumes:
   gemdata:
   gemdata2:
```
# skipオプションてんこもりでnewしてみる
こちらは--skipオプションてんこもりでnewしてみる。
```sh:
docker compose run --rm apiskiptest rails new . --api --skip-docker --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-job --skip-action-cable --skip-asset-pipeline --skip-javascript --skip-hotwire --skip-jbuilder --skip-test --skip-system-test --skip-thruster --skip-rubocop --skip-brakeman --skip-ci --skip-kamal --skip-solid --skip-devcontainer --skip-edge --skip-main
```
ずらずらずら（略）
### docker compose up -dする
docker compose up -dすると
+ localhost:3001でskip版apiモードのRails8コンテナ
+ lcoalhost:3000で通常のapiモードのRails８コンテナ
が起動する。
##### skipてんこ盛りでも問題なく起動
![スクリーンショット 2025-01-12 13.03.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82975/3cc58cda-02e7-2c76-d4c8-0aaa8d418b19.png)
# 比較のため--api --minimalも作成
ここまで来たらminimalモードと何が違うのかということで--api --minimalでnewするためのコンテナをbackend3配下に作成する。手順は省略。
こちらも問題なくrails newはできた。
```sh:
docker compose run --rm apiskiptest rails new . --api --minimal
```

# それぞれの配下のディレクトリ、ファイル数の違い
+ 通常のapiモード（backend配下）
```sh:backend
tree
###略###
301 directories, 1692 files
````
+ skip版apiモード(backend2配下)
```sh:backend2
tree
###略###
289 directories, 1332 files
```
+ minimal版apiモード(backend3配下)
```sh:backend3
tree
###略###
31 directories, 51 files
```
少なっ!!!!
これでもgemにsolid_cache、solid_queue、kamal、thrusterが入っている

# 結果
ミニマリストには以下のnewコマンドが最強
```sh:
docker compose run --rm apiminimaltest rails new . --api --minimal --skip-test --skip-system-test --skip-thruster --skip-rubocop --skip-brakeman --skip-ci --skip-kamal --skip-solid --skip-devcontainer
```
この場合のディレクトリ＆ファイル数は以下の通り
```sh:
tree
###略###
24 directories, 36 files
```