SHARE
  1. Top
  2. ブログ一覧
  3. Shopifyアプリ開発を効率化する一手:TypeScriptとapi-codegen-presetの活用
Eコマース

Shopifyアプリ開発を効率化する一手:TypeScriptとapi-codegen-presetの活用

公開日

2025.02.27

更新日

2025.02.27

SHARE
Shopifyアプリ開発を効率化する一手:TypeScriptとapi-codegen-presetの活用のサムネイル

ShopifyアプリをTypeScriptで開発する際、複数のAPIエンドポイントを呼び出すロジックの実装や更新は手間のかかる作業となりがちです。そこで活用できるのが、Shopifyの公式リポジトリにある「api-codegen-preset」です。
このツールはTypeScript開発を想定したコード生成テンプレートを提供し、GraphQLやRESTといった複数のAPI仕様に対応するクライアントコードを自動生成してくれます。手動でAPI呼び出し部分を書き換える手間が省け、メンテナンスの効率化にもつながるため、大規模なShopifyアプリ開発や頻繁な仕様変更に対応しやすいことが大きなメリットです。今回は、このapi-codegen-presetの概要と使い方、そしてどのようにTypeScriptアプリ開発の生産性を高めるかを解説していきます。

TypeScriptでの開発で起きること

Shopifyアプリ開発でAdmin APIやStorefront APIを利用する場合、戻り値の型がないと、開発者はAPIエンドポイントのレスポンスを手動で型定義しなければなりません。これにより、APIの仕様変更に伴う型定義の変更や、エラーハンドリングの追加など、開発・保守コストが増大してしまいます。また、APIエンドポイントが増えるほど、手動でのコード生成作業が複雑化し、開発効率が低下することも考えられます。

例えばCheckout UI Extensionsを開発していると商品データ取得するようなStorefront APIのエンドポイントを呼び出すコードを書くことがあるでしょう。

const productQuery = `query GetProduct($id: ID!) {
    product(id: $id) {
      id
      title
      featuredImage {
        url
      }
      variantsCount {
        count
      }
    }
  }
`;

const { data } = await query(productQuery, {
  variables: {
    id: "gid://shopify/Product/123456789”,
  },
  version: "2025-01",
});

console.log('Product:', data.product);

このとき、dataはunknown型となりコードの補完やエラーチェックが効かないため困ります。IDEでもこのような警告が表示されるかと思います。

alt text

api-codegen-presetとは

api-codegen-presetは、Shopifyが提供するTypeScript用のAPIクライアントコード生成ツールです。Shopifyアプリ開発において、GraphQLやREST APIを利用する際に、APIエンドポイントの呼び出し部分を自動生成することができます。これにより、APIの仕様変更に柔軟に対応できるほか、開発者はビジネスロジックやUX改善などの付加価値の高い領域にリソースを集中させることが可能です。

このコード生成ツールは以下のケースに合わせて使い分けることができます。

  • Shopify カスタムストアアプリ
  • Shopify App
  • Shopify App Extensions
    • Checkout UI Extensions
    • Shopify Functions

使い方

基本的にREADMEに沿って進めていきます。

api-codegen-presetのインストール

まずは、Shopifyアプリのプロジェクトディレクトリにapi-codegen-presetをインストールします。最新バージョンはnode 20以上が必要です。
今回はnpmを使ってインストールしますが、yarnを使うことも可能です。

npm install --save-dev @shopify/api-codegen-preset

設定ファイルの作成

Shopifyアプリのプロジェクトディレクトリに.graphqlrc.tsという名前で設定ファイルを作成します。このファイルには、APIエンドポイントの情報や生成するクライアントコードの設定を記述します。
今回はCheckout UI Extensionsの設定例を示します。

※ JavaScriptの場合は、.graphqlrc.jsという名前で作成してください。

import { shopifyApiProject, ApiType } from "@shopify/api-codegen-preset";
import type { IGraphQLConfig } from "graphql-config";

function getConfig(): IGraphQLConfig {
  return {
    projects: {
      default: shopifyApiProject({
        // APIエンドポイントの種類
        apiType: ApiType.Storefront,
        apiVersion: "2025-01",
        // Extension内のクエリに対してコード生成を想定しているためextensionsディレクトリ配下のファイルを指定
        documents: [
          "./extensions/**/*.{js,ts,jsx,tsx}",
          "./extensions/.server/**/*.{js,ts,jsx,tsx}",
        ],
        // 生成された型定義ファイルの出力先
        outputDir: "./extensions/types",
      })
    },
  };
}

const config = getConfig();
export default config;

バージョンを変数で管理している場合は、以下のように記述します。

先にapiパッケージをインストールします。

npm install --save-dev @shopify/shopify-api

続いて、設定ファイルを更新します。2025-01の部分を変数(LATEST_API_VERSION)に置き換えます。

+ import { LATEST_API_VERSION } from "@shopify/shopify-api";

・・・
・・・
- apiVersion: "2025-01",
+ apiVersion: LATEST_API_VERSION,

ちなみにバージョン一覧は2025/02現在、以下の通りです。

export declare enum ApiVersion {
    October22 = "2022-10",
    January23 = "2023-01",
    April23 = "2023-04",
    July23 = "2023-07",
    October23 = "2023-10",
    January24 = "2024-01",
    April24 = "2024-04",
    July24 = "2024-07",
    October24 = "2024-10",
    January25 = "2025-01",
    Unstable = "unstable"
}
export declare const LATEST_API_VERSION = ApiVersion.January25;

クエリを記述

次に、クエリを記述します。extensionの任意の場所にクエリを記述します。ここではextensions/add-to-cart/src/query/query.tsに記述します。
記述するときは#graphqlをタグとして記述します。

export const productQuery = `#graphql
  query GetProduct($id: ID!) {
    product(id: $id) {
      id
      title
      featuredImage {
        url
      }
      variantsCount {
        count
      }
    }
  }
  `;

コード生成

設定ファイルとクエリを記述したら、以下のコマンドで型定義ファイルを生成します。

npx graphql-codegen

✔ Parse Configuration
✔ Generate outputs

実行後、extensions/typesディレクトリに3つファイルが生成されます。

  • storefront-2025-01.schema.json (APIスキーマ)
  • storefront.generated.d.ts (作成クエリに対する型定義ファイル)
  • storefront.types.d.ts (StoreFront API型定義ファイル)

storefront.generated.d.tsを見ると、クエリに対する型定義が自動生成されていることが確認できます。

export type GetProductQuery = { product?: StorefrontTypes.Maybe<(
    Pick<StorefrontTypes.Product, 'id' | 'title'>
    & { featuredImage?: StorefrontTypes.Maybe<Pick<StorefrontTypes.Image, 'url'>>, variantsCount?: StorefrontTypes.Maybe<Pick<StorefrontTypes.Count, 'count'>> }
  )> };

コードの利用

最後に、生成された型定義ファイルを使ってコードを書き換えます。
queryメソッドに型定義を追加します。

import { GetProductQuery } from "../../types/storefront.generated";

・・・
・・・

- const { data } = await query(productQuery, {
+ const { data } = await query<GetProductQuery>(productQuery, {
  variables: {
    id: "gid://shopify/Product/123456789”,
  },
  version: "2025-01",
});

これで無事型定義が適用され、IDEでの補完やエラーチェックが有効になります。

alt text

Tips: 設定ファイルの項目

preset 設定パラメーター

オプション デフォルト 説明
apiType ApiType N/A スキーマを取得するAPI。
module string? ApiType に依存 型を上書きするモジュールを変更する。指定したパッケージの型を上書きできる(同じ名前の型を使用している場合)。

shopifyApiTypes 設定パラメーター

オプション デフォルト 説明
apiType ApiType N/A スキーマを取得するAPI。
apiVersion string? 最も古い安定バージョン 特定のバージョンのスキーマを取得する。
apiKey string? N/A アプリのAPIキー(Shopify Partnersの「Authentication」セクションで確認可能)。カスタマーAPIプリセットとヘルパーでのみ有効。
outputDir string? . 型ファイルの出力先ディレクトリ。
documents string[]? ./**/*.{ts,tsx} 解析するファイルのグロブパターン。
module string? ApiType に依存 型を上書きするモジュールを変更する。指定したパッケージの型を上書きできる(同じ名前の型を使用している場合)。
declarations boolean? true true の場合、.d.ts の型宣言ファイルを作成する。false の場合、.ts ファイルを作成し、アプリコードでインポート可能にする(ビルドサイズがわずかに増加する可能性あり)。

shopifyApiProject` 設定パラメーター

オプション デフォルト 説明
apiType ApiType N/A スキーマを取得するAPI。
apiVersion string? 最も古い安定バージョン 特定のバージョンのスキーマを取得する。
outputDir string? . 型ファイルの出力先ディレクトリ。
documents string[]? ./**/*.{ts,tsx} 解析するファイルのグロブパターン。
module string? ApiType に依存 型を上書きするモジュールを変更する。指定したパッケージの型を上書きできる(同じ名前の型を使用している場合)。
declarations boolean? true true の場合、.d.ts の型宣言ファイルを作成する。false の場合、.ts ファイルを作成し、アプリコードでインポート可能にする(ビルドサイズがわずかに増加する可能性あり)。

まとめ

Shopifyアプリ開発において、api-codegen-presetを使うことで、APIエンドポイントの呼び出し部分を自動生成し、開発・保守コストを削減することができます。これにより、ビジネスロジックやUX改善など、付加価値の高い領域へリソースを集中させることが可能です。

参考