1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Nuxt 3】apollo-upload-clientをNuxtで使用してみた

Posted at

概要

Apollo Clientでファイルアップロードを実現する際、ApolloのFile uploadsのドキュメントにある通り、apollo-upload-clientのように別途ライブラリを使用する方法が挙げられています。ドキュメントではReactでの使用が載せられていますが、今回はこのapollo-upload-clientをNuxtで使用してみたのでそのメモ書きです。

前提

  • 使用したNuxtのバージョンは3.13.0です。
  • 使用したNuxt Apolloのバージョンは5.0.0-alpha.14です。
  • 使用したapollo-upload-clientのバージョンは18.0.1です。
  • NuxtをTypeScriptで今回使用しましたが、apollo-upload-clientがこの記事を書いた時点(2024年9月)で型に対応してないので、types/apollo-upload-clientを別途入れます。バージョンは18.0.0を使用しました。
  • graphql-codegen/cli5.0.2を使用して、schemaからコードを生成します。

対応方針

基本的な実装方針はGraphQL File Uploads Client Side with NuxtJSにある通りです。pluginsで別途Apollo Clientの設定を実装することができるので、ここでapollo-upload-clientを使用するようにします。

設定部分の実装サンプル

まずはcodegenの設定でschemaでUploadを使用できるよう、File型を設定するようにします。以下の通り設定しました。

codegen.ts
import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
  schema: "graphqlSchema/*.graphql",
  documents: ["query/*.ts"],
  ignoreNoDocuments: true, // for better experience with the watcher
  generates: {
    "./gql/": {
      preset: "client",
      presetConfig: {
        fragmentMasking: false,
      },
      config: {
        useTypeImports: true,
        scalars: {
          Upload: "File", // UploadにFile型を割り当てる
        },
      },
    },
  },
};

export default config;

次にpluginsの実装です。基本的には上記で紹介した記事の通りですが、TypeScriptの対応などで一部実装を変えてる箇所もあります。

plugins/apolloConfig.ts
import { from, ApolloLink } from "@apollo/client/core";
import { onError } from "@apollo/client/link/error";
import { setContext } from "@apollo/client/link/context";
import { provideApolloClient } from "@vue/apollo-composable";
import createUploadLink from "apollo-upload-client/createUploadLink.mjs";

export default defineNuxtPlugin((app) => {
  const envVars = useRuntimeConfig();
  // 型のエラーを出さないために一旦anyにする
  const { $apollo } = useNuxtApp();
  const apollo: any = $apollo;

  const errorLink = onError((err) => {
    app.callHook("vue:error", err, null, "apollo error"); // must be called bc `@nuxtjs/apollo` will not do it anymore
  });

  const authLink = setContext(async (_, { headers }) => {
    const { getToken } = useApollo(); //get you token from Nuxt/Apollo helper
    const token = await getToken();
    return {
      headers: {
        ...headers,
        "Apollo-Require-Preflight": "true",
        Authorization: `Bearer ${token}`,
      },
    };
  });

  // create an customLink as example for an custom manual link
  const customLink = new ApolloLink((operation, forward) => {
    return forward(operation).map((data) => {
      return data;
    });
  });

  // Default httpLink (main communication for apollo) use createUploadLink function from apollo-upload-client
  const httpLink = createUploadLink({
    uri: envVars.public.apiEndpoint, // 環境変数でGraphQLの接続先を設定する
    useGETForQueries: false, // GETは使用しないのでfalseにする
  });

  apollo.defaultClient.setLink(
    from([errorLink, authLink, customLink, httpLink])
  );

  provideApolloClient(apollo.defaultClient);
});
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?