「Kotlinサーバサイドプログラミング実践開発」でハマった点のメモ

# この記事について
以下の書籍を読んで試して、何箇所がハマった点があるので対処方法をメモしておきます。

https://gihyo.jp/book/2021/978-4-297-11859-4

第二部で写経したコードはGitHubに上げたので置いておきます。

https://github.com/dhirabayashi/book-manager

# この記事の範囲
主に第2部と、第3部の前半が対象範囲となります。それ以外は読んだだけで写経していないためです。

# 環境
* macOS Big Sur
* Apple Silicon (M1)

# 内容
## 第5章
### DockerでMySQLのイメージが落ちてこない
以下のようなエラーでdockerコマンドがエラーになりました。

https://qiita.com/hogehoge-banana/items/cc3b6cebbafd35b9c342

対処法はリンク先の通り、 `--platform linux/amd64` を指定しました。

```zsh
docker container run --platform linux/amd64 --rm -d -e MYSQL_ROOT_PASSWORD=mysql -p 3306:3306 --name mysql mysql
```

### mysqlコマンドがない
本書だとMySQLはDockerを使って導入しますが、ホスト上でmysqlコマンドを叩いて接続する手順となっていました。
本書手順に従っただけだとホストではmysqlコマンドを使えません。
コンテナの中に入る手もありましたが、既定だと日本語の入力が受け付けられなくて面倒でした。
対処法としては、素直にMySQLのクライアントをホストに入れました。

```zsh
brew install mysql-client 
```

それだけだとパスが通りませんでした。
以下のコマンドを実行しろと表示されたので実行します。

```zsh
echo 'export PATH="/opt/homebrew/opt/mysql-client/bin:$PATH"' >> ~/.zshrc
```

### mbGereratorコマンドでエラー
以下と同じ問題を踏みました。

https://zenn.dev/tm35/articles/7e63c95f57ade6

どうやら本書執筆中にGradleのメジャーバージョンが7に上がってしまい、このようになったようですね。
対処法もリンク先の通り、gradle-wrapper.propertiesを編集してGradle 6.9がダウンロードされるようにしました。
なんとなく悔しい方法ですが、まあMyBatisを試すのがここでの目的なので…

## 第6章
### DockerでMySQLのイメージが落ちてこない
上のと同じですが今度はDocker Composeを使うので、docker-compose.ymlにplatformの指定を書きます。

```yaml:docker-compose.yml
version: '3'
services:
  # MySQL
  db:
    platform: linux/x86_64
    image: mysql:8.0.23
    ports:
      - "3306:3306"
    container_name: mysql_host
    environment:
      MYSQL_ROOT_PASSWORD: mysql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./db/data:/var/lib/mysql
      - ./db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./db/sql:/docker-entrypoint-initdb.d
  # Redis
  redis:
    image: "redis:latest"
    ports:
      - "6379:6379"
    volumes:
      - "./redis:/data"
```

### npm installに失敗
まずnpmコマンドが使えなかったので、 `brew install npm` で入れましたが、それで `npm install` を実行すると失敗しました。
Node.jsの15系だとダメみたいで、14系をインストールしたらうまく動きました。

https://mako-note.com/install-node14-on-m1-mac/

### フロントエンドアプリケーション上で書籍一覧が表示されない
curlでURLを叩くと結果を取得できるのに、フロントエンドアプリケーション上だと表示されませんでした。

ブラウザのコンソールを見ると以下のようなエラーが出ていました。

```
Access to XMLHttpRequest at 'http://localhost:8080/book/list' from origin 'http://localhost:8081' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
```

リクエストのcredentials modeを'include'でなくするか、レスポンスのAccess-Control-Allow-Originヘッダの値をワイルドカードでなくするか？
とりあえず後者で対応してみたところうまくいきました。各コントローラのアノテーションの属性に値を設定します。

```kotlin
@CrossOrigin(origins = ["http://localhost:8081"], allowCredentials = "true")
```

ただ、章が進んでSpring Securityを導入したあたりからは上記の属性はなくても動くようになりました。

## 第9章
### gRPCのサンプルでエラー

Macなのになぜかexeが見つからないとか怒られました。

```
Could not find protoc-3.15.1-osx-aarch_64.exe (com.google.protobuf:protoc:3.15.1).
```

M1だとダメみたいです。

https://github.com/grpc/grpc-java/issues/7690

幸い対処法は書いてあって、その通り書いたら動きました。（artifactの値の後ろに:osx-x86_64を付ける）

```kotlin:build.gradle.kts
protobuf {
    protoc { artifact = "com.google.protobuf:protoc:3.15.1:osx-x86_64" }
    plugins {
        id("grpc") {
            artifact = "io.grpc:protoc-gen-grpc-java:1.36.0:osx-x86_64"
        }
        id("grpckt") {
            artifact = "io.grpc:protoc-gen-grpc-kotlin:1.0.0:jdk7@jar"
        }
    }
    generateProtoTasks {
        all().forEach() {
            it.plugins {
                id("grpc")
                id("grpckt")
            }
        }
    }
}
```

## 第10章
### KtorプラグインがObsoleteになっている

Obsoleteって書かれているだけで、一応現時点ではまだ使えるようだったのでそのまま使いました。

# まとめ
色々ハマったものの、Kotlinを使ったWebアプリケーション開発に必要な技術要素を一通り俯瞰できる良い本でした。