🗂

Orval TanstackQeury 基本的な使い方

2024/11/17に公開

最近業務で Orval と TanstackQuery を触っているので、基本的な使い方をメモ程度にまとめました。

今回取り上げないこと

  • Tanstack Qeury 単体の基本的な使い方
  • OpenAPI の書き方

Orvalとは

Orvalとは、OpenAPIドキュメントをもとにクエリなどを自動生成するライブラリです。このライブラリが生成した関数を呼び出すだけで、簡単にデータのフェッチや更新を行うことが可能です。

https://orval.dev/

Orval✖️TanstackQueryの主な4つの使い方

Orvalで自動生成されたコードをもとにTanstack Queryのコードの使い方を紹介します。

  • データのフェッチ
  • データの更新
  • データのキャッシュ
  • 状態管理

データのフェッチ

以下はOpenAPIドキュメントの例です。こちらをもとにOrvalでコードが自動生成されます。

OpenAPI 例
  /todos:
    get:
      summary: Get all todo items
      responses:
        "200":
          description: A list of todo items
          content:
            application/json:
              schema:
                type: object
                properties:
                  todoList:
                    type: array
                    items:
                      $ref: "#/components/schemas/Todo"
                  pageCount:
                    type: integer
                    description: Total number of pages
                required:
                  - todoList
                  - pageCount
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

上記からフェッチ関数が生成され、以下のように呼び出すことができます。使い方はよく見るフェッチ関数の使い方と同じなのでそこまで難しくないです。

import { useGetTodos } from '@/api/generated/todoAppAPI'
import TodoList from '@/components/feature/todoList/todoList'
import { Stack } from '@mui/material'

const TodoContent: React.FC = ({
}) => {
  const { data, error, isLoading, refetch } = useGetTodos()

  if (isLoading) {
    return <div>Loading...</div>
  }

  if (error) {
    return <div>Error: {error.message}</div>
  }

  return (
    <Stack sx={{ m: 4 }}>
      <TodoList
        todoList={data?.todoList || []}
        pageCount={data?.pageCount || 0}
      />
    </Stack>
  )
}

export default TodoContent

データの更新

以下がOpenAPIドキュメントの例です。こちらをもとにOrvalでコードが自動生成されます。

OpenAPI 例
  /todo:
    post:
      summary: Create a new todo item
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTodoInput"
      responses:
        "201":
          description: Todo item created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateTodoResponse"
        default:
          description: Unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

Orvalで生成したusePostTodoを呼び出し、mutateAsyncを実行します。あとは try-catch などを使用してエラーを処理しています。

import { usePostTodo } from "@/api/generated/todoAppAPI"
import { CreateTodoInput } from "@/api/generated/todoAppAPI.schemas"
import { AxiosError } from "axios"
import { useCallback } from "react"


export const useCreateTodo = () => {
  const { mutateAsync } = usePostTodo()
  const handleCreateTodo = useCallback(async (input: CreateTodoInput) => {
    try {
      const result = await mutateAsync({ data: input })

      if (result) {
        alert("保存に成功しました")
        return true
      }

      alert("予期せぬエラーが発生しました。もう一度お試しください")
      return false
    } catch (err) {
      if (err instanceof AxiosError) {
        alert(err.message)
        return false
      }

      alert("予期せぬエラーが発生しました。もう一度お試しください")
      return false
    }
  }, [mutateAsync])

  return {
    handleCreateTodo
  }
}

データのキャッシュ

Orvalでhooksを生成する際、キャッシュのkeyも自動生成されます。本来キャッシュは一意にする必要があるが Orval側が担ってくれるのであまり意識する必要がないです。

状態管理

状態管理といえば、hooksを使う機会が多いと思うのですが、TanstackQueryでは状態管理も担っています。以下のように setQueryData で状態管理を行うことができます。hooks と似たような感覚で使うことができるので使いやすいです。

queryClient.setQueryData(queryKey, newData)

最後に

いかがでしたでしょうか、Orvalでコードを生成するとTanstack Qeury のキャッシュをいい感じに行ってくれたりするので使う時にあまり意識しなくても良いのが個人的にいいなと思いました。

Discussion