首页 文章

使用服务器端验证进行中继突变

提问于
浏览
1

我正在尝试编写一个允许服务器端验证的中继突变 . 例如具有该名称的记录已经存在 .

下面是我的GraphQL变异 .

/* @flow weak */
import {mutationWithClientMutationId,offsetToCursor} from "graphql-relay";
import {GraphQLString, GraphQLList, GraphQLNonNull} from "graphql";
import NominationConnection from '../NominationsConnection';
import ViewerType from '../../../types/ViewerType';
import Helper from '../../../helper/helper';
import Nomination from '../../../model/Nomination';


const mongo = require('mongodb');

/**
 * mutationWithClientMutationId()
 *
 * This helper function helps us create Relay-compliant GraphQL mutations it takes an object with the following params
 * { name: "", inputField: { }, outputFields: {},  mutateAndGetPayload: function({}) }
 *
 */
export default mutationWithClientMutationId({

  // Name of the Mutation
  name: "Nomination_Add",

  // Describes the fields that should be used when invoking the mutation
  inputFields: {
    name: {
      type: new GraphQLNonNull(GraphQLString)
    },
    description: {
      type: new GraphQLNonNull(GraphQLString)
    },
    books: {
      type: new GraphQLList(GraphQLString)
    }

  },

  // response that will be sent back when the mutation is complete
  outputFields: {
    NominationsEdge: {
      type: NominationConnection.edgeType,
      resolve: ( {local_id}, { ...args }, context, { rootValue: objectManager } ) =>
      {
        //RT: local_id is the object that was inserted into DB.;
        let nomination = local_id[0];
        console.log("nomination: ", nomination);
        if(nomination.Errors.length > 0){

          return objectManager.getListBy('Nomination', nomination, {}, {})
              .then((arr) => {

                return ( {
                  cursor: null,
                  node: nomination,
                } )
              })
        }else {

          let an_Object;
          return objectManager.getOneByParam('Nomination', nomination, {_id: nomination.id})
              .then((retrieved_Object) => {


                an_Object = retrieved_Object;

              })

              .then(() => objectManager.getListBy('Nomination', an_Object, {}, {}, objectManager.getViewerUserId()))
              .then((arr) => {


                return ( {
                  cursor: Helper.cursorForObjectInConnection(arr, an_Object, "id"),
                  node: an_Object,
                } )
              })
              ;
        }
      }
    },

    Viewer: {
      type: ViewerType,
      resolve: (parent, args, context, {rootValue: objectManager}) => objectManager.getOneById('User', objectManager.getViewerUserId())
    }
  },

  mutateAndGetPayload: ({name, description, books}, context, {rootValue: objectManager}) => {
    if(!books){
      books = [];
    }

    return objectManager.add('Nomination', {
      name,
      description,
      books
    }, {name: name}).then((local_id) => ( {local_id} ));
  }
});

以下是我的接力突变 .

/* @flow weak */

import Relay from 'react-relay';

export default class Nomination_addMutation extends Relay.Mutation {
  // static fragments = {
  //   Viewer: () => Relay.QL`
  //     fragment on Viewer {
  //       id,
  //     }
  //   `,
  // };
  getMutation() {

    return Relay.QL`mutation{Nomination_Add}`;
  }
  getFatQuery() {


    return Relay.QL`
      fragment on Nomination_AddPayload {
      NominationsEdge,
        Viewer {
         Nominations(first:500){
         edges{
          node{
             id,
            Name,
            Description
            }
          }
         }
        }
      }
    `;
  }
  getConfigs() {

    return [{
      type: 'RANGE_ADD',
      parentName: 'Viewer',
      parentID: this.props.Viewer.id,
      connectionName: 'Nominations',
      edgeName: 'NominationsEdge',
      rangeBehaviors: {
        // When the ships connection is not under the influence
        // of any call, append the ship to the end of the connection
        '': 'append',
        // Prepend the ship, wherever the connection is sorted by age
       // 'orderby(newest)': 'prepend',
      },
    }];
  }
  getVariables() {

    return {

      name: this.props.name,
      description: this.props.description,
      books: this.props.books,
    };
  }
  getOptimisticResponse() {


    return {
      Nomination: {

        name: this.props.name,
        description: this.props.description,
        books: this.props.books,

    },
      Viewer: {
      id: this.props.Viewer.id,
    },
    };
  }
}

这是我如何呼吁它 .

Relay.Store.commitUpdate(
        new Nomination_Add( {name: fields.name , description: fields.desc ,Viewer:this.props.Viewer}),
          {
            onSuccess: response => {
             console.log(response);
              console.log(response.Nomination_Add);
            },
          }
      );

我的响应对象只有Viewer.id和clientmuationID . 当我通过graphql调用此突变时,它看起来像这样 .

mutation{
  Nomination_Add(input:{name:"test", description:"test", clientMutationId:"2"}){
  NominationsEdge{
    node{
      Name,
      Description,
    Errors {
      Message
    }
      Books{
        Title
      }
    }
  }
  }

}

对此作出回应 .

{
  "data": {
    "Nomination_Add": {
      "NominationsEdge": {
        "node": {
          "Name": "test",
          "Description": "test",
          "Errors": [
            {
              "Message": "Nomination Already Exists"
            }
          ],
          "Books": []
        }
      }
    }
  }
}

如何通过中继写入逻辑来将我的服务器验证错误消息返回给客户端?

也试过这个作为我的胖查询

return Relay.QL`
      fragment on Nomination_AddPayload {
      NominationsEdge {
        node{
            Errors {
              Message
            }
          }
        },
        Viewer {
         Nominations(first:500){
         edges{
          node{
             id,
            Name,
            Description
            }
          }
         }
        }
      }
    `;

响应看起来像这样:

{,…}
data
:
{Nomination_Add: {clientMutationId: "0", Viewer: {id: "00000000-0000-0000-0000-000000000000"}}}
Nomination_Add
:
{clientMutationId: "0", Viewer: {id: "00000000-0000-0000-0000-000000000000"}}
Viewer
:
{id: "00000000-0000-0000-0000-000000000000"}
id
:
"00000000-0000-0000-0000-000000000000"
clientMutationId
:
"0"

2 回答

相关问题