Agent Grow Tech Notes
🙌

TypeScript & GraphQL でToDoアプリを開発する #4

に公開

⬅️前回の記事はこちら

https://zenn.dev/agent_grow/articles/8011af2c6d0ec6

⭐️Apollo Clientの起動

frontend/にplugins/apollo-client.tsを作成

apollo-client.ts
import { defineNuxtPlugin } from '#app'
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client/core'

export default defineNuxtPlugin((nuxtApp) => {   // Nuxtにプラグイン(Apollo)を注入 
  const httpLink = new HttpLink({
    uri: 'http://localhost:4001/graphql',   // GraphQLサーバーのエンドポイントを指定
  })

  const apolloClient = new ApolloClient({ 
    link: httpLink,               // 通信方法(httpLink)を指定
    cache: new InMemoryCache(),   // クエリ結果などのキャッシュの設定
  })

  nuxtApp.provide('apollo', apolloClient)   // Nuxtにapolloという名前でApollo Clientを登録
})

frontend/にgraphql/queries.tsを作成

queries.ts
import { gql } from '@apollo/client/core'

export const GET_TODOS = gql`
  query GetTodos {
    getTodos {   # getTodosリゾルバ(クエリ)を呼び出し、Todoの一覧を取得
      id
      title
      completed
    }
  }
`

frontend/graphql/にmutations.tsを作成

mutations.ts
import { gql } from '@apollo/client/core'

export const CREATE_TODO = gql`
  mutation CreateTodo($title: String!) {
    createTodo(title: $title) {   # createTodoリゾルバ(ミューテーション)を呼び出し、Todoを作成
      id
      title
      completed
    }
  }
`

export const UPDATE_TODO = gql`
  mutation UpdateTodo($id: Int!, $title: String, $completed: Boolean) {
    updateTodo(id: $id, title: $title, completed: $completed) {   # updateTodoリゾルバ(ミューテーション)を呼び出し、Todoを更新
      id
      title
      completed
    }
  }
`

export const DELETE_TODO = gql`
  mutation DeleteTodo($id: Int!) {
    deleteTodo(id: $id)   # deleteTodoリゾルバ(ミューテーション)を呼び出し、Todoを削除
  }
`

frontend/にpages/index.vueを作成
(Apollo Clientが正しく動作しているか確認するため、最小限の内容で作成)

index.vue
<template>
    <h1>🚀 index.vueの表示に成功!</h1>
</template>

frontend/のapp.vueを削除
※Nuxtが用意した「ようこそページ」
 pages/ディレクトリを未作成時に表示される用のものなので削除でOK

frontend/にcomposables/useTodos.tsを作成

useTodos.ts
import { useAsyncData, useNuxtApp } from '#app'
import { GET_TODOS } from '@/graphql/queries'

// Todo型を定義
type Todo = {
    id: number
    title: string
    completed: boolean
}

// Todo一覧を取得するためのカスタムコンポーザブル(useTodos)を定義
export const useTodos = () => {
    const { $apollo } = useNuxtApp()  // NuxtアプリケーションからApollo Clientを取得

    // useAsyncDataを使って非同期でデータ取得(キャッシュキーは'todos')
    const { data, pending, error, refresh } = useAsyncData('todos', async () => {
        // Apollo Clientを使ってGraphQLクエリを送信
        const result = await $apollo.query<{ getTodos: Todo[] }>({
            query: GET_TODOS,         // 実行するGraphQLクエリ
            fetchPolicy: 'no-cache',  // キャッシュを使わず、常に最新のデータを取得
        });

        // 取得したTodo一覧をID順にソートして返す
        return result.data.getTodos.slice().sort((a, b) => a.id - b.id)
    })

    // 呼び出し元のコンポーネントが使えるように必要な値を返す
    return {
        todos: data,     // Todo一覧のデータ
        pending,         // データ取得中かどうか(ローディング状態)
        error,           // エラーが発生した場合の情報
        refresh          // データを再取得するための関数
    }
}

frontend/にtypes/apollo.d.tsを作成

apollo.d.ts
import { ApolloClient } from '@apollo/client/core'

// NuxtAppに$apolloを追加するための型定義(明示的なインターフェース定義)
export interface NuxtApp {
  $apollo: ApolloClient<any>
}

// Nuxt 3 のアプリケーションに対して $apollo を型として追加する(型拡張)
declare module '#app' {
  interface NuxtApp {
    $apollo: ApolloClient<any>
  }
}

// Vueコンポーネント に対して this.$apollo を型として追加する(型拡張)
declare module '@vue/runtime-core' {
  interface ComponentCustomProperties {
    $apollo: ApolloClient<any>
  }
}

frontend/package.jsonのscriptsブロックにポートを追記

package.json
//修正前
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
package.json
//修正後
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev --port 3001",   //←ポートを追記
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },

frontend/で npm run dev を実行

% npm run dev

http://localhost:3001 にアクセスしてindex.vueの内容が表示されたら成功

🚀Apollo Clientの起動が完了!!!

#4のおわりに

Apollo Client の起動 お疲れさまでした。
次回は本格的に画面を開発して動作確認をします。
https://zenn.dev/agent_grow/articles/b9fae76d86be49

〜Vueの紹介〜

VueはUI構築のための JS/TSフレームワークです。
ここでは、Vueの特徴を3つに絞って紹介します。

◼️公式エコシステムが充実している
 - 状態管理やビルドツールなど、必要な機能が公式で揃っており、構成に迷いにくくなっています。

◼️単一ファイルコンポーネント(SFC)で構造が明確
 - .vue という単一ファイルに、テンプレート・ロジック・スタイル をまとめて記述できます。

.vue
<template>...</template>
<script>...</script>
<style scoped>...</style>

◼️学習コストが低い
 - HTML/CSS/JavaScriptの基礎知識があれば、直感的に書き始めることができます。

Agent Grow Tech Notes
Agent Grow Tech Notes

Discussion