无法让中继通过网络进行 GraphQL 调用

Cannot get Relay to make GraphQL Call over the network

我是 Relay 的新手,我在使用 GraphQL 服务器时遇到问题。

我对Tea sample from the relay homepage to the SWAPI relay service. I cloned swapi-graphql进行了适配,并在express服务器中添加了cors。我用这段代码测试了 link:

var query = `
  {
    allFilms {
      edges {
        node {
          id
        }
      }
    }
  }
`

fetch("http://localhost:50515/graphiql?query=" + query)
  .then(response=>response.json())
  .then(json=>console.log(json))

我收到了服务器的响应,我看到了一些网络操作,它成功了!我可以与 graphiql 服务通信。

接下来,我创建了一个结构类似于 TeaStoreQuery 的查询。我 tested 它,它返回了预期的结果。

query AllFilmQuery {
  allFilms {
    ...filmListFragment
  }
}

fragment filmListFragment on FilmsConnection {
  edges {
    node {
      ...filmFragment
    }
  }
}

fragment filmFragment on Film {
  id
  title
  releaseDate
}

如何使用继电器实现此功能??

我不知道如何使用中继查询服务器。这是我从 Tea 示例改编的代码。

import { render } from 'react-dom'
import { 
  RootContainer, 
  createContainer, 
  Route, 
  injectNetworkLayer 
} from 'react-relay'

// React component for each star wars film
const Film = ({ id, title, releaseDate }) => 
  <li key={id}>
    {title} (<em>{releaseDate}</em>)
  </li>

// Relay container for each film
const FilmContainer = createContainer(Film, {
  fragments: {
    film: () => Relay.QL`
      fragment on Film {
        id,
        title,
        releaseDate
      }
    `
  }
})               

// React component for listing films       
const FilmList = ({ films=[] }) => 
  <ul>
    {films.map(
      film => <Film {...film} />
    )}
  </ul>

// Relay container for Listing all Films
const FilmListContainer = createContainer(FilmList, {
  fragments: {
    films: () => Relay.QL`
      fragment on FilmsConnection {
        edges {
          node {
            ${ Film.getFragment('film') }
          }
        }
      }
    `
  }
})    

// The Home Route
class FilmHomeRoute extends Route {
  static routeName = 'Home'
  static queries = {
    allFilms: (Component) => Relay.QL`
      query AllFilmQuery {
        allFilms {
          ${Component.getFragment('allFilms')}
        }
      }
    `
  }
}

// Is this how you setup a network layer
// I am using CORS, and I testing the graphql service with fetch
// The graphql service works but Relay never seems to try to connect
Relay.injectNetworkLayer(
  new Relay.DefaultNetworkLayer('http://localhost:50515/graphiql')
)

render(
  <RootContainer
    Component={FilmListContainer}
    route={new FilmHomeRoute()}
  />,
  document.getElementById('react-container')
)

当我 运行 这个示例 (source | output) 时,我没有看到任何发出网络请求的尝试。我确实看到一个错误 "Cannot render map of null"。好像不能映射allfilms的数据。

我做错了什么?

根据 this document 的第 5.1 节,"Relay Object Identification Specification":

Relay‐compliant servers may expose root fields that are not plural identifying root fields; the Relay client will just be unable to use those fields as root fields in its queries.

根据此规范,Relay 无法在查询的根部查询多个字段,除非该字段采用精确映射到结果的参数列表。这意味着 allFilms 字段不能与 Relay 一起使用。您可以在其他 Whosebug 答案中阅读有关限制的更多信息:How to get RelayJS to understand that a response from GraphQL is an array of items, not just a single item

如果您希望 GraphQL 架构的根字段为 return 数组,您可能希望使用不同的 GraphQL 客户端,因为 Relay 在它使用的架构类型方面有特别的限制。 graphql.org 有一个列表:http://graphql.org/code/#graphql-clients