使用Apollo客户端从nextjs中的getInitialProps方法执行graphQL查询时,返回ECONNREFUSED

时间:2019-01-28 22:12:51

标签: nginx graphql apollo-client next.js

with-apollo-auth为例 我执行客户端ApolloConsumer查询时的成功行为。我让客户通过并进行查询。

当我尝试通过getInitialProps进行服务器端查询时,行为失败。我将客户端通过调用相同查询的处理程序传递,并收到ECONN被拒绝的错误,如下所示。

enter image description here

重现行为的步骤:

我在init-apollo文件中设置我的ApolloClient如下:

  const httpLink = createHttpLink({
    uri: 'http://localhost:8080/api/graphql',
    credentials: 'same-origin'
  })

  const authLink = setContext((_, { headers }) => {
    const token = getToken()
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : ''
      }
    }
  })

  return new ApolloClient({
    connectToDevTools: process.browser,
    ssrMode: !process.browser, // Disables forceFetch on the server (so queries are only run once)
    link: ApolloLink.from([ authLink, httpLink ]),
    cache: new InMemoryCache().restore(initialState || {})
  })

我将查询设置如下:

import gql from 'graphql-tag'

export default apolloClient => {
  apolloClient
    .query({
      query: gql`
        {
          getUser {
            id
          }
        }
      `
    })
    .then(({data}) => {
      console.log(data);
      return { userDetails: data.getUser }
    })
    .catch((err) => {
      // Fail gracefully
      console.log(err);
      return { userDetails: {} }
    })
  }

我在页面目录中的index.js文件中设置了getInitialProps函数:

  import getUser from '../shared/services/get-user';

  static async getInitialProps (context) {
    const results = await getUser(context.apolloClient)
    console.log(results);
    return {}
  }

预期的行为 我希望看到返回的用户日志,但是出现了如上所述的ECONNREFUSED错误。

系统信息 操作系统:macOS Mojave 浏览器(如果有)Chrome Next.js版本:7.0.2 ApolloClient版本:2.4.12l 其他背景 使用苦艾酒(Elixir + Phoenix)GraphQL API,指定的网址:http://localhost:8080/api/graphq 使用docker-compose启动多个容器。 API和NextJS客户端位于nginx服务器后面的单独容器中。 Nginx服务器根据指定的url端点路由到相关容器。 这很可能是问题,但我无法找到解决方案。如果url包含api,客户端将被路由到我的API容器。

这是我的nginx配置的设置:

upstream client {
  server client:3000;
}

upstream api {
  server api:4000;
}

server {
  listen 80;

  location / {
    proxy_pass http://client;
  }

  location /sockjs-node {
    proxy_pass http://client;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
  }

  location /api {
    rewrite /api/(.*) /$1 break;
    proxy_pass http://api;
  }
}

1 个答案:

答案 0 :(得分:0)

尽管回答得很晚,但是您应该在backend-api框架上提供了更多信息,即您正在运行哪个框架?我相信前端是nextjs。都一样,我认为您的问题是与Nginx配置有关。请通过端口号data[:, 5], data[:, 6], data[:, 7], data[:, 8] proxy_pass而不是\location,因为它们是两个不同的Web服务。尝试此配置,注意标题。另外,将操作系统配置为侦听端口8030。


server {
  listen 80;

  location / {
    proxy_pass http://client;
    proxy_pass_request_headers on;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
  }
}

server {
  listen 8030;

  location / {
    proxy_pass http://api;
    proxy_pass_request_headers on;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_redirect off;
  }
}