React native 的中继突变返回 400 错误请求?

Posted

技术标签:

【中文标题】React native 的中继突变返回 400 错误请求?【英文标题】:Relay mutation for React native returning 400 bad request? 【发布时间】:2018-03-28 14:04:00 【问题描述】:

我在尝试让突变发挥作用时遇到了很多麻烦。 鉴于此 GraphQL Schema,任何人 PLEASE 都可以帮我创建一个简单的 create User 突变吗?我不明白我错过了什么。我得到了它从 GraphQL 服务器抛出 400 错误并且它不会触发解析功能的地步。

var userType = new GraphQLObjectType(
  name: 'User',
  description: 'User creator',
  fields: () => (
    id: 
      type: new GraphQLNonNull(GraphQLString),
      description: 'The id of the user.'
    ,
    email: 
      type: GraphQLString,
      description: 'The email of the user.'
    ,
    business: 
      type: GraphQLString,
      description:
        'The name of the business of the user as the app refers to it.'
    ,
    businessDisplayName: 
      type: GraphQLString,
      description: 'The name of the business of the user as they typed it in.'
    ,
    trips: 
      type: new GraphQLList(tripType),
      description: 'The trips of the user, or an empty list if they have none.',
      resolve: (user, params, source, fieldASTs) => 
        var projections = infoToProjection(fieldASTs)
        return Trip.find(
          
            _id: 
              // to make it easily testable
              $in: user.trips.map(id => id.toString())
            
          ,
          projections,
          function(err, docs) 
            return docs
          
        )
      
    
  )
)


var schema = new GraphQLSchema(
  query: new GraphQLObjectType(
    name: 'root',
    fields: 
      trips: 
        type: new GraphQLList(tripType),
        resolve: function() 
          return Trip.find()
        
      ,
      users: 
        type: new GraphQLList(userType),
        resolve: function() 
          return User.find()
        
      ,
      user: 
        type: userType,
        args: 
          id: 
            name: 'id',
            type: new GraphQLNonNull(GraphQLString)
          
        ,
        resolve: (root,  id , source, fieldASTs) => 
          return User.findOne(
             _id: id ,
            infoToProjection(fieldASTs),
            function(err, doc) 
              return doc
            
          )
        
      ,
      trip: 
        type: tripType,
        args: 
          id: 
            name: 'id',
            type: new GraphQLNonNull(GraphQLString)
          
        ,
        resolve: (root,  id , source, fieldASTs) => 
          var projections = infoToProjection(fieldASTs)
          return Trip.findOne( _id: id , projections, function(err, doc) 
            return doc
          )
        
      
    
  ),

  // mutation
  mutation: new GraphQLObjectType(
    name: 'Mutation',
    fields: 
      createUser: 
        name: 'createUser',
        type: userType,
        args: 
          input:  type: new GraphQLInputObjectType(
            name: 'user',
            fields: 
              business:  type: GraphQLString ,
              email:  type: GraphQLString ,
              businessDisplayName:  type: GraphQLString 
            
          )
        ,
        resolve: (parentValue, args) => 
          let user = new User( ...args.input )
          user.save()
          return user
        
      
  )
)

export var getProjections = infoToProjection
export default schema

这适用于使用以下查询或突变的 GraphiQL:

mutation 
  createUser(input:business:"business", email: "e@mai.l", businessDisplayName: "businessDN") 
    id
    email
    business
    businessDisplayName
  


fragment UserFragment on User 
    id
    business
    businessDisplayName
    trips
      title
    



    hideya: user(id: "someid") 
    ...UserFragment
    

【问题讨论】:

【参考方案1】:

我终于解决了这个问题。试图了解问题的根源,因此我使用了新的 NetworkLayer 来启用适当的日志记录和有意义的错误消息。然后当我的突变失败时抛出错误。错误消息是:“无法查询字段 clientMutationId”。查找并发现要能够改变对象,您需要在 GraphQL 类型上具有该字段。所以我添加了它。

经验教训:我强烈推荐使用 react-relay-network-layer


更多详情:

这是我的代码:

import 
  RelayNetworkLayer,
  urlMiddleware,
  batchMiddleware,
 from 'react-relay-network-layer';

Relay.injectNetworkLayer(new RelayNetworkLayer([
  batchMiddleware(
    batchUrl: 'http://localhost:3000/graphql',
  ),
  urlMiddleware(
    url: 'http://localhost:3000/graphql',
  ),
]));

注意:这会启用日志记录,默认情况下它是一个简单的 console.log。

这是我抛出错误的方式:

const params = 
        email: email.toLowerCase(),
        businessDisplayName: business,
        business: business.toLowerCase()
      
      var onSuccess = () => 
        console.log('Mutation successful!')
      
      var onFailure = transaction => 
        var error = transaction.getError() || new Error('Mutation failed.')
        console.error(error)
      

      Relay.Store.commitUpdate(new FindOrCreateUser( user:  ...params  ),  onFailure, onSuccess )

当然,您总是需要清理缓存并重新启动打包程序。

【讨论】:

以上是关于React native 的中继突变返回 400 错误请求?的主要内容,如果未能解决你的问题,请参考以下文章

Graphql 突变返回 Post 400 错误,不知道如何解决

突变返回 400 错误,但在 GraphiQL 中有效

React Native axios 总是返回“请求失败,状态码 400”

中继或 Apollo-react 如何解决涉及多个关系的突变

axios.post 返回 400 React Native 的错误请求

Apollo + React 在执行突变时给了我 400 错误。可能的 httpLink 错误