初心者がLaravelでShopifyアプリ開発してみた　|　fileCreate

# はじめに
shopify業務に携わることになったため、勉強の日々を過ごしているモモナです。
2週間前にshopifyの勉強を始めたばかりなのでわからない部分も多々ありますが、初心者なりに学んだことをまとめていこうと思っています。
訂正箇所や認識違いなどあれば、ご指摘お待ちしております。

今回は、Laravelを利用したshopifyアプリ開発でのファイル作成(fileCreate)を紹介します。

# 動作環境
Mac OS Catalina
PHP 7.4.27
Laravel Framework 8.76.2

# 環境構築
shopifyの登録方法などは、他に詳しくまとめている方もいるので割愛させていただきます。
公式サイトでも流れは確認できるかと思います。

https://www.shopify.jp/blog/partner-shopify-app-development?utm_source=shopifydev&utm_medium=youtube&utm_campaign=jp_shopifydev_youtube

Laravelでの開発は下記サイトを参考にさせていただきました。

https://qiita.com/kkamizuru/items/e70424539ae98e1f3cc5

Laravelで情報をまとめている方がほとんど見つからない中、とても助かりました。
ありがとうございます。

これから環境構築していく場合は、サイトを参考に**[アプリ作成][link-1]**まで進めていただくと手順がわかりやすいです。

[link-1]:https://qiita.com/kkamizuru/items/e70424539ae98e1f3cc5#%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%9C%E6%88%90

## アプリインストール後の場合
アプリの権限変更やアクセストークンの確認が必要なため、ストア側のアプリは一度削除することを推奨します。
ストア側で削除しても、パートナー側で作成したアプリは残っているのでご安心ください。

# 公式リファレンス
fileCreateに関しては、下記サイトが公式内容になります。

https://shopify.dev/api/admin-graphql/2021-10/mutations/filecreate

今回は公式リファレンスを参考に記述を進めていきます。

# 権限付与
まずは、fileCreateできる権限を設定します。
場所は**AuthorizeController**の**scopes**です。

```app/Http/Controllers/AuthorizeController.php
$scopes = 'read_products,write_products,read_script_tags,write_script_tags';
```

read→読み取り、write→書き込み

今回必要な権限は公式リファレンスの[fileCreate][link-2]を見ると一番上に載っています。

[link-2]: https://shopify.dev/api/admin-graphql/2021-10/mutations/filecreate

![スクリーンショット 2021-12-27 17.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/b5109c45-8c91-6702-1a52-c8126962d21c.png)

`write_files`が必要とのことです。
上記**scopes**の箇所に、`write_files`を追加します。

権限を追加した後は`/authorize`でアプリインストールをします。

## Mutation・Query

ちなみに、fileCreateの横にある**mutation**は属性みたいなものと思っています。
もう1つ**query**というものがあり、それぞれ簡単に説明すると

**mutation**→shopify内の情報を変更できる(create・update・deleteなど)
**query**→shopify内の情報を出力し、確認できる

今回の場合「fileCreateを使うときはmutationで記述してね」と解釈しています。

# GraphQL Admin API
ここで少しAPIについて。
今回のfileCreateもGraphQLのものです。

GraphQLは、APIでshopifyの情報を利用するときに使うものになります。
別のAPIに**[REST Admin API][link-1]**もありますが、shopifyはGraphQLを推している様子です。

[link-1]: https://shopify.dev/api/admin-rest#top

記述の仕方はPHPに近いのですが、私はまだよくわかっていません。

公式のShopifyブログにGraphQLについて説明しているものもありますが、参考程度に見ていました。

https://www.shopify.jp/blog/partner-getting-started-with-graphql

## GraphQL App

GraphQLのAppは下記URLからストア側にインストールすることもできます。

https://shopify-graphiql-app.shopifycloud.com/login?itcat=partner_blog&itterm=getting_started_with_graphql

![スクリーンショット 2021-12-28 11.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/eec3ea1c-000f-7d69-0b1d-af52cac18ebf.png)

**Shop URL**にアプリインストールするショップのURLを記入します。
その下に並んでいるAdmin APIやStorefront APIは、どの権限を付与するか選択するところになります。

ただ、このAppだと今回必要なfileの権限がないのです……。
なので、contentやproductsなどの記述確認に使ってみてください。
ストア側のアプリ管理で確認できるので、入れておくのが良いと思います。

GraphQLの記述方法など全てにおいて理解できていないので、fileCreateの場合でも直接記述しながら確認できるのが望ましいなぁと思い、色々調べてみました。

そこで見つかったのは**postman**というサイト。
私はここでGraphQLの記述確認をしていました。

# postman

https://www.postman.com/

アカウント登録が必要なサイトになりますが、Googleアカウントから登録もできるので簡単です。

アカウント登録ができたら、**Home**を開きます。

英語で色々書いていますが、まずは**Start with something new**という枠にある**Create New**をクリックします。

![スクリーンショット 2021-12-28 12.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/486dbe49-376b-7260-4c42-eff42f08cdee.png)

また色々書かれていますが、ここは選択しなくても進むことができるので、一旦右上の×ボタンで閉じます。

![スクリーンショット 2021-12-28 12.29.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/8798e8fc-fc6a-00ed-0360-c7e050d9e537.png)

次に+ボタンをクリック

![スクリーンショット 2021-12-28 12.30.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/380ca505-4f6a-52c3-a939-c0d68f10e009.png)

ここまで開くことができれば、後は下記サイトを参考に進めることができます。

![スクリーンショット 2021-12-28 12.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/2e93362b-f766-88a3-747b-bc49d39d2503.png)

https://qiita.com/GoogIeSensei/items/d920febd1c43b1dca33b

とてもわかりやすくて、助かった投稿です。
ありがとうございます。

設定が終わったら、実際にコードを記述していきましょう。

# コード記述
公式リファレンス[fileCreate][link-2]で下の方にコード例が載っています。

```php:
//Mutation
mutation fileCreate($files: [FileCreateInput!]!) {
  fileCreate(files: $files) {
    files {
      # File fields
    }
    userErrors {
      field
      message
    }
  }
}
```

```php:
//Variables
{
  "files": {
    "alt": "",
    "contentType": "",
    "originalSource": ""
  }
}
```

この部分、私は記述の方法がわからなくて詰まりました。

コード例の書き方がMutationとVariablesで項目が分かれていれば使えるものだと思うので、今回のLaravelで開発する場合は少し当てはまらない気がしています。
この書き方を使って、Laravelで動かす方法あるのかな……。
あったら教えてください。

# 正しい記述
色々迷走してしまったので、先に正解の記述を置いておきます。

```app/Http/Controllers/AuthorizeController.php
public function file()
{
$file_create = Http::withHeaders([
            'X-Shopify-Access-Token' => '***ACCESS-TOKEN-FOR-THIRD-PARTY-APP***'
        ])
            ->accept('application/graphql')
            ->post('https://yourshop.myshopify.com/admin/api/2021-10/graphql.json', [
                'query' => <<<Query

                mutation {
                    fileCreate(
                    files: {
                        alt: "test",
                        contentType: FILE,
                        originalSource: "https://code.jquery.com/jquery-3.6.0.min.js"
                    }) {
                    files {
                        alt
                        createdAt
                        fileStatus
                    }
                    userErrors {
                        field
                        message
                    }
                    }
                }

        
        
                Query
            ]);

return view ('/file');
    }
```

## ルーティング設定
```routes/web.php
Route::get('/file', 'App\Http\Controllers\AuthorizeController@file');
```

## blade作成
```html:resources/views/file.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h2>file-create 完了</h2>
</body>
</html>
```

# 正解に辿り着くまで
記述の仕方がわからなかったので、先輩に助けを求めました。

```php:
$file_create = Http::withHeaders([
            'X-Shopify-Access-Token' => '***ACCESS-TOKEN-FOR-THIRD-PARTY-APP***'
        ])
            ->accept('application/graphql')
            ->post('https://yourshop.myshopify.com/admin/api/2021-10/graphtql.json', [
                'query' => <<<Query

        ///GraphQL記述
        
                Query
            ]);
```

ここで私は何を思ったか、 queryの部分を全部mutationに変えました。
queryは出力だし、書き込みだからmutationなのかなと……。

しばらくこのコードを使っていたので、エラー放出祭りでした。
当たり前ですね。

## GraphQLの記述
GraphQLの記述に関しては自分でやり切りたい、と思っていました。
ただ、先ほどのコードでエラー祭り状態なので、どうやってもうまくいきませんでした。

なので、また先輩のお世話になりました。

```php:
mutation {
	fileCreate(
    files: {
      alt: "test",
      contentType: FILE,
      originalSource: "test.js"
    }) {
    files {
      alt
      createdAt
      fileStatus
    }
    userErrors {
      field
      message
    }
  }
}
```

公式リファレンス[fileCreate][link-2]の記述を元に、MutationとVariablesを1つにまとめている記述であると今なら少しわかります。

しかし`originalSource: "test.js"`の部分でエラーが出ました。
この部分はURLでの記述が必要なため、直接データを入れることができない様子。(〇〇.jpgは指定できない)

色々試したところ、パートナー画面の設定＞ファイルのところで直接ファイルをアップロードした場合、そのリンクを使ってfileCreateは可能でした。

![スクリーンショット 2021-12-27 18.46.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2437071/14497920-afe2-4a4a-bbc9-6becacd8ee00.png)


上記の正しい記述では
`originalSource: "https://code.jquery.com/jquery-3.6.0.min.js"`
Jqueryのファイルを使用しました。

ここまで来てもエラーが出たため、やっとMutationエラー祭りの記述を変更し、正しい記述に辿り着きました。

## fileCreate完了
ちなみに、正しい記述でfileCreate出来れば、上記の**000012 JPG**という写真が入っている場所に新しいファイルを確認できます。

# 最後に
迷走に迷走を重ね、結局記述間違いでした。
GraphQLの書き方も、公式リファレンスくらいしか参考になるものがなく、今回は本当にキツかったです。
先輩にもたくさんお世話になりました。

まだGraphQLの記述の仕方を理解し尽くせていないので、復習必須です。
とりあえず、流れは理解できると思うので、行き詰まっている方の参考になれば良いなと思います。