🍞
Remixで、apollo-clientを使う
概要:
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
- 前の、Cloudflare Workersデプロイ 記事
- apollo-server 、下記
準備
- 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参考を、追加しました。
....
Discussion