2016-08-01 14 views
0

サーバー側の検証を可能にするリレー突然変異をコード化しようとしています。その名前のレコードはすでに存在します。サーバーサイド検証によるリレーの突然変異

以下は私の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": [] 
     } 
     } 
    } 
    } 
} 

サーバーの検証エラーメッセージをリレー経由でクライアントに返信する方法はありますか?

{,…} 
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" 
+0

'ビューア:{ID: "00000000-0000-0000-0000-000000000000"}' < - あなたがあなたのビューアオブジェクト(GraphQL型ではなく、GraphQL型が関連付けられているオブジェクト)に 'id'を割り当てているかどうかチェックできますか? –

+0

はい、現在、アプリケーションのビルド中に割り当てています。 – jackncoke

+0

graphiqlインターフェイスで次のクエリを実行するとどうなりますか? 'クエリのxyz { ビューア{ ID、(最初:1) ノミネート{ エッジ{ ノード{ ID、 名、 説明 } } } } }' –

答えて

0

あなたはそのリレーに語っていないので、あなたは、サーバー側の検証エラーメッセージを受信して​​いない:私の脂肪クエリ

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

応答は次のようになりますよう

もこれを試してみましたそれらを欲しい。あなたのGraphiQL突然変異とあなたのリレー突然変異の太った質問を見てみましょう。前者にはErrorsが含まれていますが、後者には含まれていません。私はmutateAndGetPayloadにエラーをスローすることができます

fragment on Nomination_AddPayload { 
    NominationsEdge { 
     node { 
     Errors { 
      Message 
     } 
     } 
    }, 
    Viewer { 
    Nominations(first:500){ 
     edges{ 
     node{ 
      id, 
      Name, 
      Description 
     } 
     } 
    } 
    } 
} 
+0

は、あなたの答えをありがとう。私もやってみました。私が遭遇する問題はまだ同じです。 (:500最初の){ 縁{ ノード{ID、 Nomination_AddPayload {NominationsEdge { ノード{{エラーメッセージ }}} 、 ビューア{ノミネートにRelay.QL' '断片を返します名前、 説明 }} }} } 'は、' 'あなたがnode'フィールド内' Errors'フィールドを置く – jackncoke

+0

同じ応答を返します。 'NominationsEdge'の内部にあります。だからあなたは期待された反応を得られなかったのです。私の答えでは、 'Errors'フィールドは' NominationsEdge'の中に直接あります。 –

+0

もう一度お世話になりました!それは私のスキーマがどのように定義されているので、私はそれを目的にしました。エラーはnominationTypeにあります。それは動かされるべきか? – jackncoke

0

::これはと突然変異のONFAILUREコールバックにエラーメッセージとして出荷されます

は、あなたのリレー突然変異の(Nomination_addMutation)以下のような脂肪クエリでErrorsを含めますエラーメッセージは私が投げるものです。

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

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

     //RT: readability 
    let nomination = nominations[0]; 

     //RT: if Mongo id is not assigned. 
     // No records where created. 
     if(nomination.id == null) 
      throw nomination.Errors[0].Message; 

     return ({nomination} 

    )}); 
    } 

これは正しい方法ではありません。誰か良い例を見たことがありますか?

編集:コードをクリーンアップし、これらの例に基づいてこれを行うことにしました。正しいとは思わない。

https://medium.com/@fcpgate/i-think-what-eslam-mentioned-is-more-on-the-right-track-cdd07519bf97#.na73ulbxj(コメントを読む。)

https://facebook.github.io/relay/docs/api-reference-relay-store.html

http://stackoverflow.duapp.com/questions/37044914/how-to-tackle-server-side-input-validation-using-relay?rq=1

https://github.com/facebook/relay/issues/696

+0

エラーをスローすると、クライアント側で最大で1つの検証エラーを受け取ることができます。これは唯一の制限です。 –

+0

最初は(あなたのクエストオンで)[この記事](https://medium.com/@tarkus/validation-and-user-errors-in-graphql-mutations-39ca79cd00bf#)と同じアプローチに従っているようです.e4p4rfw8x)、これは実際には非常に良いアプローチです。 –

+0

はい、私はその記事を楽しんで、私のgraphqlの突然変異はまったく同じように動作します。それは、私のやり方で突然変異を使用するためにリレーを取得している、私の問題です! – jackncoke

関連する問題