在 Hasura、Apollo和React中实现实时更新的订阅功能
如果需要的话,我会重新写下來的。
实现代码
需要将通信从HTTP切换到WebSocket,因此需要安装插件。
yarn add subscriptions-transport-ws
使用WebSocketLink将ApolloClient的link更改为ws。
原本的URI是在URI中通过HTTP指定的,为http://localhost:8080/v1/graphql。
由于想要进行双向通信,所以将其更改为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编写订阅的方式
我已经写好了查询(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/订阅
https://hasura.io/learn/graphql/react/subscriptions/1-subscription/
Hasura/GraphQL/Vue.js/Subscriptions 在这个链接中让你学习如果使用Vue.js在GraphQL中进行订阅。
WebSocket是什么?https://www.keicode.com/script/html5-websocket-1.php