1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SvelteKit 環境で GraphQLを使う

Last updated at Posted at 2023-01-16

SvelteKit 環境で GraphQLを使う

SvelteKit使い始めたばっかりですが、簡潔に記述できるし、SSRがかんたんに出来たりで、とても気に入っています。
Dunning-Kruger効果的には「完全に理解した」状態ですが、学んだこと書いておきます。

やりたいこと。

バックエンドはGraphQLを開発しているので、GraphQLで定義された型、Query、Mutationをフロントで再度定義することなく利用したい。
以下のリンクを参照しながら進めます。the guildのドキュメントは再現性低くて昔から結構読みにくいです。。。

https://the-guild.dev/graphql/codegen/docs/guides/svelte
https://zenn.dev/takurinton/articles/76582f25d942f0

環境について

Ubuntu 22.04
svelte 3.54.0
@graphql-codegen/cli 2.16.4
@graphql-codegen/typescript 2.8.7
@graphql-codegen/typescript-operations 2.5.12

進め方

結果論になりますが、 svelte-apollo は解決不能なエラーが解消が出来ず、初期導入がどうしても出来ずに、諦めました。なんかバグある?
なので、@apollo/clientのインスタンスを自分で作って、CodeGenで作成されるコードから参照させる形を取りました。

Setup

# 素のアプリケーション作成
npm create svelte@latest myapp
cd myapp 
npm install

# code generatorを入れる
npm install --save-dev @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations graphql-codegen-svelte-apollo

# apollo clientをいれる
npm install --save @apollo/client

以下のようにCode Generatorの設定を入れます。

codegen.yml
schema:
  - http://localhost:8080/graphql:
documents:
  - ./src/**/*.gql
generates:
  './src/graphql/generated.ts':
    plugins:
      - typescript
      - typescript-operations
      - graphql-codegen-svelte-apollo
    config:
      clientPath: ../lib/graphql/apollo

そしてApollo ClientをdefaultでExportするファイルを作る。場所は codegen.ymlgenerates.config.clientPathと一致させます。
ついでにidTokenを更新するための関数も用意してexportしておきます。 (トークンを更新するたびにこれを呼べばOKです)

/src/lib/graphql/apollo.ts
import { ApolloClient, InMemoryCache } from '@apollo/client/core/core.cjs'
import { HttpLink } from '@apollo/client/link/http/http.cjs'

const cache = new InMemoryCache()
const client = new ApolloClient({
  cache,
})

const newLink = (idToken: string) => {
  return new HttpLink({
    uri: 'https://MY_GRAPHQL_HOST/graphql',
    headers: {
      Authorization: `Bearer ${idToken}`,
    },
  })
}

export default client
export const updateClientWithIdToken = (idToken: string) => {
  const newHttpLink = newLink(idToken)
  client.setLink(newHttpLink)
}

Firebase Authenticationの場合こんな感じで更新する。。。

getAuth().onAuthStateChanged(async (user) => {
  if (!!user) {
    const idToken = await user.getIdToken()
    updateClientWithIdToken(idToken)
  }
}

使ってみる

とりあえずQueryなりMutationなり書いてみる。codegen.yml で指定した documents で拾われる場所であればどこで置いてもいいです。

src/graphql/my-mutations.gql
mutation SomeMutation {
   someMutation {
    id
    uid 
    validUntil
    createdAt
  }
}

npx graphql-codegen でコードが自動生成されますので、早速使ってみましょう。

<script lang="ts">
  import { onMount } from 'svelte'
  import { SomeMutation } from '../../../../graphql/generated'
  import store from './store'

  onMount(async () => {
    const result = await SomeMutation({})
    store.set(result.data?.someMutation)
  })
</script>

{$store?.id} <-- こんな感じで参照する型も自動生成されるのでIntelliSenseが効いてとても便利です

まとめ

ドキュメントが少なすぎて環境作る際にとても苦労しましたが、それ以外はすんなり行きました。誰かの役に立てば幸いです。
フロントエンドではやっぱり型定義などはやらず、ビジネスロジックをなるべく省いてPresentation Layerの関心事だけに集中するのが好きですが、結構それに近くて気に入っています。

♥ Svelte/Kit, GraphQL

1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?