メモ書き
需要が有れば書き直します。
実装コード
httpの通信からWebSocketの通信に切り替える必要があるのでプラグインのインストール
yarn add subscriptions-transport-ws
WebSocketLinkを使ってApolloClientのlinkをwsに変える
uriでhttp指定していたURIがhttp://localhost:8080/v1/graphql
であった
WebSocketで双方向に通信したいのでws://localhost:8080/v1/graphql
に書き換える。
この時、Hasura側では特に何もする必要はない。
import {
ApolloClient,
InMemoryCache,
gql
} from "@apollo/client";
import { WebSocketLink } from "@apollo/client/link/ws";
import { useSubscription } from '@apollo/react-hooks'
import ArticleCards from '../components/ArticleCards'
const client = new ApolloClient({
// uriをlinkに変更(http通信からws通信にする)
link: new WebSocketLink({
uri: 'ws://localhost:8080/v1/graphql',
options: {
reconnect: true,
connectionParams: {
headers: {
// 認証系はここに書く
}
}
}
}),
cache: new InMemoryCache(),
});
export default function Home() {
return (
<ApolloProvider client={client}>
<ArticleCards></ArticleCards>
</ApolloProvider>
);
}
記事一覧のコンポーネント(雑につくった)でリアルタイム更新
useQuery
を使っていた場合は、useSubscription
に書き換える。
gqlのコード以外は特に変わらないので説明は割愛
import { useSubscription } from '@apollo/react-hooks'
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import articleStyle from '../styles/ArticleCards.module.css';
import { ARTICLES_SUBSCRIPTIONS } from '../gql/articles';
interface ArticleType {
id: string;
text: string;
}
const Article = (article: ArticleType) => {
return (
<Card variant="outlined" className={articleStyle.card}>
<CardContent>
<Typography variant="body2" component="p">
{article.text}
</Typography>
</CardContent>
<CardActions>
<Button size="small">MORE</Button>
</CardActions>
</Card>
);
}
const ArticleCards = () => {
const { loading, error, data} = useSubscription(ARTICLES_SUBSCRIPTIONS);
console.log(data)
// ローディング中の表示
if (loading) return <p>loading</p>
// エラー時の表示
if (error) return <p>{error.toString()}</p>
// 成功してデータが帰ってきた時の表示
return (
<div className={articleStyle.article}>
{data.articles.map((article: ArticleType) => (
<Article {...article} key={article.id}></Article>
))}
</div>
);
}
export default ArticleCards
gqlでsubscriptionsを書く
参考までにquery
, subscription
, mutation
を書いておいた。
import gql from "graphql-tag";
export const ARTICLES_QUERY = gql`
query {
articles {
id
text
}
}
`;
export const ARTICLES_SUBSCRIPTIONS = gql`
subscription ArticlesSubscriptions {
articles(limit: 30, order_by: { created_at: asc }) {
date
id
text
}
}
`;
export const ADD_ARTICLES = gql`
mutation AddArticles($text: String = "", $date: date = "") {
insert_articles(objects: { text: $text, date: $date }) {
returning {
id
text
date
}
}
}
`;
参考記事
Hasura/GraphQL/React.js/Subscriptions
https://hasura.io/learn/graphql/react/subscriptions/1-subscription/
Hasura/GraphQL/Vue.js/Subscriptions
https://hasura.io/learn/graphql/vue/subscriptions/1-subscription/
WebSocketとは?
https://www.keicode.com/script/html5-websocket-1.php