0
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?

More than 1 year has passed since last update.

コード譜投稿アプリを作る #4(apollo clientを使ってnextからrailsにリクエストする)

Last updated at Posted at 2022-09-18

←前回の記事

今回やること

前回railsとGraphQLを使ってバックエンドの実装を進めたので今回はそれをフロントで表示するのが目標です。
apollo使います
何かっていうとフロントでgraphqlを使うためのライブラリです。

apollo clientインストール

フロント側で以下を実行

yarn add @apollo/client graphql

apolloセットアップ

/src/pages/_App.tsxに以下を追記

/src/pages/_App.tsx
import type { ReactElement, ReactNode } from 'react'
import type { NextPage } from 'next'
import type { AppProps } from 'next/app'
import { ChakraProvider } from '@chakra-ui/react'
+ import {
+  ApolloClient,
+  InMemoryCache,
+  ApolloProvider,
+  createHttpLink
+ } from "@apollo/client";
+
+ const link = createHttpLink({
+   uri: "http://localhost:3000/graphql",
+   credentials: "include",
+ });
+ 
+ const client = new ApolloClient({
+   cache: new InMemoryCache(),
+   link: link,
+ });

export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (page: ReactElement) => ReactNode
}

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout
}

export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  const getLayout = Component.getLayout ?? ((page) => page)

  return (
+   <ApolloProvider client={client} >
      <ChakraProvider>
        {getLayout(<Component {...pageProps} />)}
      </ChakraProvider>
+   </ApolloProvider>
  )
}

これで全てのページでapollo clientが使用できるようになりました!

実装

とりあえずトップページに前回作ったScoresを一覧で表示しようと思います
ISRとか一旦抜きに普通に表示します

import { Box } from '@chakra-ui/react'
import type { ReactElement } from 'react'
import { Layout } from '../components/common/Layout'
import type { NextPageWithLayout } from './_app'
import { useQuery, gql } from "@apollo/client";

const GET_SCORES = gql`
  query GetScores {
    scores {
      id
      title
    }
  }
`;

type Score = {
  id: Number
  title: String
}

const Page: NextPageWithLayout = () => {
  const { data, loading, error } = useQuery(GET_SCORES)
  if (loading) return <Box>ロード中...</Box>;
  if (error) return <Box>{error.message}</Box>;
  return (
    <Box>
      <ul>
        {data.scores.map((score: Score) => (
          <li>{score.title}</li>
        ))}
      </ul>
    </Box>
  )
}

Page.getLayout = function getLayout(page: ReactElement) {
  return (
    <Layout>
      {page}
    </Layout>
  )
}

export default Page

こんな感じで一旦作成。
無事(?)CORSエラーが出ました
image.png

CORSエラーの解消

Rails側に戻り、Gemfileでコメントアウトになっている以下の行のコメントを外します

Gemfile
gem "rack-cors"

/config/initializers/cors.rbを以下のように編集。

/config/initializers/cors.rb
# Be sure to restart your server when you modify this file.

# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.

# Read more: https://github.com/cyu/rack-cors

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'http://localhost:3001'
    resource "*",
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head],
      credentials: true
  end
end

コメントアウト外してcredentials: trueを追加しています。(methods:の行の最後のコンマ忘れずに!)
私の環境はフロント側のサーバーを:3001ポートで建てているので、ここはよしなに変更してください。

これでサーバー再起動すればCORSエラーが解消されているはずです!

image.png
表示されました!
今回はここまで!

参考にさせていただいたサイト、記事

0
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
0
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?