next.js 在Apollo客户端中使用多个端点

w41d8nur  于 2023-08-04  发布在  其他
关注(0)|答案(3)|浏览(132)

这是我的第一篇讨论文章。我通过奥德赛学会了Apollo + GraphQL。目前,我正在使用Next.js构建自己的项目,这需要从2GraphQL端点获取数据。
我的问题:如何使用ApolloClient多个GraphQL端点获取数据?
下面是我的第一个端点的代码:

import { ApolloClient, InMemoryCache, createHttpLink } from "@apollo/client";

const client = new ApolloClient({
  ssrMode: true,
  link: createHttpLink({
    uri: "https://api.hashnode.com/",
    credentials: "same-origin",
    headers: {
      Authorization: process.env.HASHNODE_AUTH,
    },
  }),
  cache: new InMemoryCache(),
});

export default client;

字符串

xoshrz7s

xoshrz7s1#

你试图完成的是有点反对阿波罗的“一个图表”的方法。了解网关和联盟-https://www.apollographql.com/docs/federation/
话虽如此,一些黑客解决方案是可能的,但你需要维护一个更复杂的结构,并在每个查询中指定端点,这会破坏内置机制,并可能导致优化问题。

//Declare your endpoints
const endpoint1 = new HttpLink({
    uri: 'https://api.hashnode.com/graphql',
    ...
})
const endpoint2 = new HttpLink({
    uri: 'endpoint2/graphql',
    ...
})

//pass them to apollo-client config
const client = new ApolloClient({
    link: ApolloLink.split(
        operation => operation.getContext().clientName === 'endpoint2',
        endpoint2, //if above 
        endpoint1
    )
    ...
})

//pass client name in query/mutation
useQuery(QUERY, {variables, context: {clientName: 'endpoint2'}})

字符串
这个包似乎做你想要的:https://github.com/habx/apollo-multi-endpoint-link
此外,请在此处查看讨论:https://github.com/apollographql/apollo-client/issues/84

rpppsulh

rpppsulh2#

今天遇到了同样的问题。我想让它有活力,所以这就是我出来的:

export type DynamicLinkClientName = "aApp" | "bApp" | "graphqlApp";
type Link = RestLink | HttpLink;
type DynamicLink = { link: Link; name: DynamicLinkClientName };
const LINK_MAP: DynamicLink[] = [
  { link: aRestLink, name: "aApp" },
  { link: bAppRestLink, name: "bApp" },
  { link: graphqlAppLink, name: "graphqlApp" },
];

const isClientFromContext = (client: string) => (op: Operation) =>
  op.getContext().client === client;

const DynamicApolloLink = LINK_MAP.reduce<ApolloLink | undefined>(
  (prevLink, nextLink) => {
    // When no name is specified, fallback to defaultLink.
    if (!prevLink) {
      return ApolloLink.split(
        isClientFromContext(nextLink.name),
        nextLink.link,
        defaultLink
      );
    }
    return ApolloLink.split(
      isClientFromContext(nextLink.name),
      nextLink.link,
      prevLink
    );
  },
  undefined
) as ApolloLink;

字符串

kkih6yb8

kkih6yb83#

真的很喜欢Pete的解决方案,因为它允许超过2个端点。
为了更好地进行类型检查,我决定编写自己的版本。
以下是我对他的解决方案的看法:

打印文本:

const defaultClient: keyof typeof clients = "heroku";

const clients = {
  "heroku": new HttpLink({ uri: "https://endpointURLForHeroku" }),
  "lists": new HttpLink({uri: "https://endpointURLForLists" })
}

const isRequestedClient = (clientName: string) => (op: Operation) =>
  op.getContext().clientName === clientName;

const ClientResolverLink = Object.entries(clients)
  .map(([clientName, Link]) => ([clientName, ApolloLink.from([Link])] as const))
  .reduce(([_, PreviousLink], [clientName, NextLink]) => {

    const ChainedLink = ApolloLink.split(
      isRequestedClient(clientName),
      NextLink,
      PreviousLink
    )

    return [clientName, ChainedLink];
  }, ["_default", clients[defaultClient]])[1]

declare module "@apollo/client" {
  interface DefaultContext {
    clientName: keyof typeof clients
  }
}

字符串

JS:

const defaultClient = "heroku";

const clients = {
  "heroku": new HttpLink({ uri: "https://endpointURLForHeroku" }),
  "lists": new HttpLink({uri: "https://endpointURLForLists" })
}

const isRequestedClient = (clientName) => (op) =>
  op.getContext().clientName === clientName;

const ClientResolverLink = Object.entries(clients)
  .reduce(([_, PreviousLink], [clientName, NextLink]) => {

    const ChainedLink = ApolloLink.split(
      isRequestedClient(clientName),
      NextLink,
      PreviousLink
    )

    return [clientName, ChainedLink];
}, ["_default", clients[defaultClient]])[1]

相关问题