API(laravel作成)につながらない時用

## はじめに
外部から作成したlaravelにつなげようとするとつながらない場合の切り分けとして、誰でもつながる用のテストAPIの例を記載する。

## API作成
Laravelを使用してJSONレスポンスを返す簡単なAPIエンドポイントを作成する例を示す。
(Laravel環境をまず作る。環境構築例は後で記載。)
1. **ルーティングの設定**
`routes/api.php` ファイルを開き、以下の内容を追加する。
```php
use Illuminate\Http\Request;

Route::get('/sample', function (Request $request) {
   return response()->json([
       'message' => 'Hello, API!',
       'data' => [
           'id' => 1,
           'name' => 'Sample Data'
       ]
   ]);
});
```
このルーティングは、GETリクエストが `/api/sample` に対して行われたときにJSONレスポンスを返す。

**APIエンドポイントをテスト**
ブラウザとcurlを使用した例。

ブラウザからURLにアクセス。(下記はdocker環境でのアクセス)
```
http://localhost:8000/api/sample
```
`curl` コマンドを使用。
```bash
curl http://localhost:8000/api/sample
```

上記のエンドポイントにアクセスすると、以下のようなJSONレスポンスが返されるはず。

```json
{
   "message": "Hello, API!",
   "data": {
       "id": 1,
       "name": "Sample Data"
   }
}
```
上記で早急に、簡単なコード記載で、このLaravelのAPIにつながるか確認することができる。
また。この例を基に、さらに複雑なAPIの機能やエンドポイントを追加していくことができる。


## 環境構築例
上記が動く環境の作り方として、docker環境で、laravel環境を作る。
Laravelの環境をDockerでセットアップするための基本的な手順を以下に記載。
この手順は、Dockerが既にインストールされていることを前提としている。
Dockerの説明は本題から外れるため特に記載していない。
### 準備
以下ファイル作成
```
.
├── Dockerfile
├── docker-compose.yml
├── nginx
 　　　　　　　 └── default.conf
```

### 手順
1: **DockerファイルとDocker Composeファイルを作成する**

`Dockerfile`:
```Dockerfile
FROM php:8.1-fpm

# インストールする依存関係
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    libonig-dev \
    libzip-dev \
    unzip

# PHPの拡張モジュールをインストール
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd

# Composerのインストール
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
```

`docker-compose.yml`:
```yaml
version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: my-laravel-app
    container_name: laravel_app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./:/var/www
    networks:
      - laravel

  nginx:
    image: nginx:stable-alpine
    container_name: nginx
    ports:
      - "8000:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - ./:/var/www
    networks:
      - laravel

  db:
    image: mysql:5.7
    container_name: mysql
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: homestead
      MYSQL_USER: homestead
      MYSQL_PASSWORD: secret
      MYSQL_ROOT_PASSWORD: root
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    networks:
      - laravel

networks:
  laravel:
    driver: bridge
```

2: **Nginxの設定ファイルを作成する**

新しく`nginx`というディレクトリを作成し、その中に`default.conf`というファイルを作成します。

`nginx/default.conf`:
```nginx
server {
    listen 80;
    server_name localhost;
    root /var/www/public;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}
```

3: **Dockerコンテナをビルドして実行する**

以下のコマンドを実行して、Dockerコンテナをビルドして実行する。

```bash
docker-compose up -d
```

5: **Laravelのプロジェクトをセットアップする**

以下はできない。
対象フォルダがからである必要があるが、今回はホストをコンテナにdocker関連ファイルをコピーしているため。
```bash
docker-compose exec app composer create-project --prefer-dist laravel/laravel .
```

```bash
Creating a "laravel/laravel" project at "./"

In CreateProjectCommand.php line 371:
                                                
  Project directory "/var/www/." is not empty.  
                                                
```

以下の手順を実施する(Laravelプロジェクト作成)


### Laravelプロジェクト作成

エラーが発生しているのは、Laravelの新しいプロジェクトを作成しようとするディレクトリ (`/var/www/.`) が空でないため。DockerやDocker Composeの設定ファイルなど、すでに一部のファイルやディレクトリが存在すると、`composer create-project`コマンドは失敗する。

以下の手順で行う。

5.1:  **一時的なディレクトリでLaravelプロジェクトを作成し、後でファイルを移動する**

    まず、Laravelプロジェクトを一時的なディレクトリに作成します:
```bash
docker-compose exec app composer create-project --prefer-dist laravel/laravel temp
```


5.2: `temp` ディレクトリ内のファイルとディレクトリを現在のディレクトリ (`/var/www/`) に移動、エラーが発生しても続行させる。

```bash
docker-compose exec app sh -c 'mv temp/* temp/.[!.]* . 2>/dev/null || true'
```
このコマンドは、`temp` ディレクトリ内のファイルと、`.` で始まる隠しファイルを現在のディレクトリに移動する。エラーが発生してもコマンドの実行を続行する。

5.3: `temp` ディレクトリを削除:

```bash
docker-compose exec app rmdir temp
```
これで、`temp` ディレクトリの内容が現在のディレクトリに正しく移動される。


## Laravel ログファイル 権限
以下発生すれば、以下のようにログ書き込み許可の対応をする。
(Windowsで行うと発生したが、Macでは下記は発生しなかった。)
```bash
The stream or file "/var/www/storage/logs/laravel.log" could　
 not be opened in append mode: Failed to open stream: 　
Permission denied The exception occurred while attempting to 
　log: The stream or file "/var/www/storage/logs/laravel.log"
　 could not be opened in append mode: Failed to open stream:　 
Permission denied The exception occurred while attempting to　
```
このエラーは、Laravelがログファイル (`laravel.log`) に書き込みするのに必要な適切な権限が設定されていないことを示している。Dockerコンテナ内のファイルやディレクトリの所有者やグループが正しくない場合にこのようなエラーが発生することがある。

この問題を解決するために、Laravelプロジェクト内の `storage` および `bootstrap/cache` ディレクトリの権限を変更する。

以下のコマンドを実行して、これらのディレクトリの権限を変更する。
```bash
docker-compose exec app chown -R www-data:www-data storage bootstrap/cache
```

このコマンドは、`storage` および `bootstrap/cache` ディレクトリ内の全てのファイルとサブディレクトリの所有者とグループを `www-data` に変更します。`www-data` は、多くのLinuxディストリビューションでWebサーバーのプロセスを実行するための標準的なユーザーおよびグループ。

この変更を行った後、再度Laravelアプリケーションをアクセスして、エラーが解消されたか確認。

## おわりに
今回作ったAPIにつながらないというときの切り分け用として例を記載した。
ところで、API作ったことある？、と聞かれて特にそんな案件携わったことないと回答していたが、改めてその定義を考えているとデータ取得する用のものを作ることである。今回示したものでデーターから何か取得するのを作ればもうそれはAPIである。