VueとLaravelで始めるGraphQL

## 環境構築

### Docker周りの設定

1. プロジェクトフォルダ内にdocker-compose.yamlを作成し、下記コードを記載する。

```yaml:docker-compose.yaml
# docker-composeのバージョンを指定
version: '3'
# docker-composeが起動させる各コンテナを記載
services:
  app:
    container_name: app
    # 実行するDockerfileのパス
    build: ./docker/php
    volumes:
      - .:/var/www
  nginx:
    image: nginx
    container_name: nginx
    # このポートをlocalhostの末尾につけたらアプリケーションが表示される
    ports:
      - 8000:80
    volumes:
      - .:/var/www
      - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
    working_dir: /var/www
    depends_on:
      - app
  db:
    image: mysql:5.7
    container_name: db
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: database
      MYSQL_USER: db-user
      MYSQL_PASSWORD: db-pass
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 3306:3306
```

1. dockerフォルダを作成し、さらにphpフォルダとnginxフォルダを作成する。
2. nginxフォルダにdefault.confを作成し、下記コードを記載。

```conf:default.conf
server {
  listen 80;
	#ルートフォルダを指定
  root /var/www/backend/public;
	#ルートファイル設定
  index index.php;
  location / {
    root /var/www/backend/public;
    index index.php;
    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;
  }
}
```

1. phpフォルダにphp.iniとDockerfileを作成し、それぞれ下記コードを記載。

```ini:php.ini
# php.ini
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"
[opcache]
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1
opcache.enable_cli=1
```

```Dockerfile:Dockerfile
# Dockerfile
#イメージ名
# nginxで動かすには「-fpm」が必要
FROM php:8.0-fpm
# RUNはFROMのイメージ環境によって実行させるコマンドを指定する
# データベース周りのアプリをインストール
RUN apt-get update && apt-get install -y zlib1g-dev mariadb-client vim libzip-dev && docker-php-ext-install zip pdo_mysql

# Composer install
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
# ファイル移動
RUN mv composer.phar /usr/local/bin/composer

# nodeJs install
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN apt-get install -y nodejs

#set up vue
RUN npm install -g @vue/cli

# 環境変数の設定
# composerをroot権限で実行させるための権限付与
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATY $PATH:/composer/vendor/bin

# 作業フォルダ名
WORKDIR /var/www
# Laravelのインストール
RUN composer global require "laravel/installer
```

1. `docker-compose up -d`を実行し、コンテナを作成する。

### 参考資料

[https://www.torat.jp/laravel-docker-lemp/](https://www.torat.jp/laravel-docker-lemp/)

## Laravelの設定

1. プロジェクトフォルダで`composer create-project laravel/laravel --prefer-dist フォルダ名`を実行する。今回はDocker設定の都合上フォルダ名はbackendにする。
    1. `--prefer-dist`　と`—-prefer-source`の2種類があるが、distの方は配布版(zipファブル)sourceの方はgit cloneでコードを取得している。
2. .envファイルのデータベース設定を下記のように変更する。
    
    ```env:.env
    DB_CONNECTION=mysql #イメージの種類
    DB_HOST=db # container_name
    DB_PORT=3306 # docker-compose.yamlで設定したポート番号
    DB_DATABASE=database # docker-compose.yamlのMYSQL_DATABASE
    DB_USERNAME=db-user　# docker-compose.yamlの MYSQL_USER
    DB_PASSWORD=db-pass　# docker-compose.yamlのMYSQL_PASSWORD
    ```
    
3. database/seeders/DatabaseSeeder.phpの`\App\Models\User::factory(10)->create();`のコメントアウトを外し、`php artisan migrate --seed`を実行する。
4. `composer require nuwave/lighthouse`を実行し、lighthouseをインストールする。
5. `php artisan vendor:publish --tag=lighthouse-schema`を実行し、デフォルトをschma.graphqlを作成する。graphqlフォルダが作成され、その中に生成される
6. `composer require mll-lab/laravel-graphql-playground`を実行し、GraphQLの動作テストをUIで行えるライブラリをインストールする。
7. config/cors.phpに下記コードを追加する

```php
'paths' => ['api/*', 'graphql'],
```

1. `php artisan vendor:publish --tag=lighthouse-config`を実行し、lighthouseの設定ファイルを作成する。(この説明では使いません)
2. [http://localhost:8000/graphql-playground](http://localhost:8000/graphql-playground)にアクセスして、graphqlで情報が取得できるかを確認する。

### 参考資料

[https://maasaablog.com/development/backend/php/laravel/1873/](https://maasaablog.com/development/backend/php/laravel/1873/)

[https://kin29.info/composer-の-prefer-distってよく使うけど何してる？/](https://kin29.info/composer-%E3%81%AE-prefer-dist%E3%81%A3%E3%81%A6%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%81%91%E3%81%A9%E4%BD%95%E3%81%97%E3%81%A6%E3%82%8B%EF%BC%9F/)

[https://hara-chan.com/it/programming/prefer-dist-prefer-source-difference/](https://hara-chan.com/it/programming/prefer-dist-prefer-source-difference/)

[https://don-bu-rakko.com/laravel-で-graphql-を使えるようにする！-lighthouseハンズオン/#Lighthouse_の導入](https://don-bu-rakko.com/laravel-%E3%81%A7-graphql-%E3%82%92%E4%BD%BF%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%EF%BC%81-lighthouse%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3/#Lighthouse_%E3%81%AE%E5%B0%8E%E5%85%A5)

## Vueプロジェクトの設定

1. `npm init vite@latest folder_name -- --template vue-ts` を実行し、vueプロジェクトを作成する。
    1. npm のバージョンが7以上の場合は`—template`の前にハイフンが二つ必要([参考資料](https://ja.vitejs.dev/guide/#%E6%9C%80%E5%88%9D%E3%81%AE-vite-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B:~:text=%23%20npm%207%2B%20%E3%81%AF%E8%BF%BD%E5%8A%A0%E3%81%A7%202%20%E3%81%A4%E3%81%AE%E3%83%80%E3%83%83%E3%82%B7%E3%83%A5%E3%81%8C%E5%BF%85%E8%A6%81%3A%0Anpm%20create%20vite%40latest%20my%2Dvue%2Dapp%20%2D%2D%20%2D%2Dtemplate%20vue))
2. 作成したフォルダに移動して、`npm install --save graphql graphql-tag @apollo/client`を実行しモジュールをインストールする
3. `npm install --save @vue/apollo-composable`コマンドを実行する。
4. main.ts下記のように変更する。

```tsx:main.ts
import { createApp, provide, h } from 'vue'
import './style.css'
import App from './App.vue'
import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client/core'
import { DefaultApolloClient } from '@vue/apollo-composable'

// HTTP connection to the API
const httpLink = createHttpLink({
    // GraphQLの情報を取得できるURLを指定
		// 今回はDockerの都合上下記URLを指定
    uri: 'http://localhost:8000/graphql',
  })
  
  // Cache implementation
  const cache = new InMemoryCache()
  
  // Create the apollo client
  const apolloClient = new ApolloClient({
    link: httpLink,
    cache,
  })

createApp({
    setup () {
      provide(DefaultApolloClient, apolloClient)
    },
  
    render: () => h(App),
  }).mount('#app')
```

1. 情報を取得したいvueファイルのscript内、もしくはcomposableフォルダに下記のようなコードを追加して、情報を取得できるか確認する。

```tsx:graphql.ts
import { useQuery } from '@vue/apollo-composable'

const getVal = async () => {
  const {result} = await useQuery(gql`query{
	  users {
		  data{
		    name
		  }
	 }
  }`)
   return result
 }
```

### 参考資料

[https://v4.apollo.vuejs.org/guide-composable/setup.html#_1-install-vue-apollo-composable](https://v4.apollo.vuejs.org/guide-composable/setup.html#_1-install-vue-apollo-composable)

[https://v4.apollo.vuejs.org/guide-composable/query.html#usequery](https://v4.apollo.vuejs.org/guide-composable/query.html#usequery)

[https://zenn.dev/gamin/articles/881a3e33be3135](https://zenn.dev/gamin/articles/881a3e33be3135)