🍞

Remixで、apollo-clientを使う

2021/11/29に公開

概要:

Remixで、apollo-client使用、GraphQL操作する例です。

  • Remix追加時に、Cloudflare Workersを選択し、Cloudflare Workersデプロイする構成になります

構成

  • remix: 1.0.6
  • Cloudflare Workers
  • @apollo/client
  • apollo-server
  • mongoDB atlas: aws us-east リージョン
  • node: 16.13

関連

  • remix, Creating the project

https://remix.run/docs/en/v1/tutorials/blog

  • 前の、Cloudflare Workersデプロイ 記事

https://zenn.dev/knaka0209/articles/7a0ececce48a23

https://zenn.dev/knaka0209/books/befdda3d27a264/viewer/cf706d

https://zenn.dev/knaka0209/articles/9a72a4790d99e7

  • apollo-server 、下記

https://github.com/kuc-arc-f/apollo_sv_atlas_2_pub


準備

  • apollo-serverエンドポイントの設定
apollo-client.ts
import { ApolloClient, InMemoryCache } from "@apollo/client";

const client = new ApolloClient({
    uri: 'http://localhost:3000/graphql',
    cache: new InMemoryCache(),
});

export default client;
  • npm 追加
npm i --save @apollo/client graphql

  • query, loader内の, query実行の例です
test5.tsx
import { useEffect, useRef } from "react";
import type { MetaFunction, LoaderFunction } from "remix";
import { useLoaderData, Link } from "remix";
import { Form, json, useActionData, redirect } from "remix";
import { gql } from "@apollo/client";
import client from '../../../apollo-client'


export let meta: MetaFunction = () => {
  return {
    title: "Remix Starter",
    description: "Welcome to remix!"
  };
};
export let loader: LoaderFunction = async () => {
  const data = await client.query({
    query: gql`
    query {
      tasks {
        id
        title
        created_at
      }
    }
    `,
    fetchPolicy: "network-only"
  });
console.log(data.data.tasks); 
  return json(data.data.tasks);
}

export default function Page() {
  let data: any[] = useLoaderData<any>();
//console.log(data);
  return (
    <div className="remix__page">
      <main>
        <h2>Welcome , Test4-88</h2>
        <hr />
        <ul>
        {data.map(item => (
          <li key={item.id} className="remix__page__resource">
            {item.title}
          </li>
        ))}
        </ul>
      </main>
    </div>
  );
}

  • mutation, action内で実行の例です
test6.tsx
// GQL, add sample
import { useEffect, useRef } from "react";
import type { MetaFunction, LoaderFunction } from "remix";
import { Form, json, useActionData, redirect } from "remix";
import { gql } from "@apollo/client";
import client from '../../../apollo-client'

export let meta: MetaFunction = () => {
  return {
    title: "Remix Starter",
    description: "Welcome to remix!"
  };
};
export async function action({ request }) {
  let formData = await request.formData();
  let answer = formData.get("answer");
console.log(answer);
  //db
  const result = await client.mutate({
    mutation:gql`
    mutation {
      addTask(title: "${answer}"){
        id
      }
    }            
  `
  });
console.log(result);
  if(result.data.addTask.id === 'undefined'){
    throw new Error('Error , addTask');
  }
  return json({ result: 'OK' })
}

export default function Page() {
  let data = useActionData();
  console.log(data);

  let onClick = function(){
    console.log("#onClick");
  }
  
  return (
    <div className="remix__page">
      <main>
        <h2>Welcome , Test6 -22</h2>
        <hr />
        <Form method="post" name="form3" id="form3" className="remix__form">
        <h3>Post an Action</h3>        
        <label>
            <div>Answer:</div>
            <input  name="answer" type="text" />
          </label>
          <div>
            <button type="submit">Submit</button>
          </div>
        </Form>
        <hr />
        <button onClick={() => onClick()}>Click
        </button>

      </main>
    </div>
  );
}


  • デプロイは、前のworkesデプロイと同様で、 yarn deployでデプロイできました。

  • package.json
{
  "private": true,
  "name": "remix-app-template",
  "description": "",
  "license": "",
  "scripts": {
    "build": "remix build",
    "dev": "remix watch",
    "postinstall": "remix setup cloudflare-workers",
    "build:worker": "esbuild --define:process.env.NODE_ENV='\"production\"' --minify --bundle --sourcemap --outdir=dist ./worker",
    "dev:worker": "esbuild --define:process.env.NODE_ENV='\"development\"' --bundle --sourcemap --outdir=dist ./worker",
    "start": "miniflare --build-command \"npm run dev:worker\" --watch",
    "deploy": "npm run build && wrangler publish"
  },
  "dependencies": {
    "@apollo/client": "^3.5.5",
    "@remix-run/cloudflare-workers": "^1.0.6",
    "@remix-run/react": "^1.0.6",
    "graphql": "^16.0.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remix": "^1.0.6"
  },
  "devDependencies": {
    "@cloudflare/workers-types": "^2.2.2",
    "@remix-run/dev": "^1.0.6",
    "@types/react": "^17.0.24",
    "@types/react-dom": "^17.0.9",
    "esbuild": "0.13.14",
    "miniflare": "2.0.0-next.3",
    "typescript": "^4.1.2"
  },
  "engines": {
    "node": ">=14"
  },
  "sideEffects": false,
  "main": "dist/worker.js"
}


参考のコード

  • CRUD参考を、追加しました。

https://github.com/kuc-arc-f/remix8


....

Discussion