2016-08-01 4 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 
     } 
    } 
    } 
    } 

} 

응답이 있습니다.

로직을 작성하기 위해 릴레이를 통해 내 서버 유효성 검사 오류 메시지를 다시 클라이언트로 가져올 수 있습니까?

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" 
+0

'뷰어 : {ID : "00000000-0000-0000-0000-000000000000"}'<- (GraphQL 유형이 아니라 GraphQL 유형이 연결된 객체) 뷰어 객체에 'id'를 지정했는지 확인할 수 있습니까? –

+0

예, 현재 앱을 제작하는 동안 앱을 할당하고 있습니다. – jackncoke

+0

graphiql 인터페이스에서 다음 쿼리를 실행할 때 어떤 결과가 발생합니까? '쿼리 XYZ { 뷰어 { ID (첫번째 : 1) 후보 { 가장자리 { 노드 { 아이디, 이름, 설명 } } } } 은}' –

답변

0

당신을 그들을 원해. GraphiQL 변이와 중계 변이의 뚱뚱한 질문을보십시오. 전자에는 Errors이 포함되었지만 후자에는 포함되지 않았습니다.

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

는 답변 주셔서 감사합니다 . 나는 또한 노력했다. 내가 겪는 문제는 여전히 똑같습니다. Nomination_AddPayload에 Relay.QL'에게 '단편을 반환 { NominationsEdge 노드 {{{ 오류 메시지 }}} , 뷰어 { 후보 (제 500) {{ 에지 노드 { ID, 이름, 설명 } } } } } '는, '당신은'node' 필드 안에'Errors' 필드를 넣어 – jackncoke

+0

같은 응답을 반환 'NominationsEdge' 내부에 있습니다. 그것이 예상 된 응답을 얻지 못한 이유입니다. 내 대답,'오류 '필드는 직접'NominationsEdge' 안에 있습니다. –

+0

다시 도움을 주셔서 감사합니다! 나는 그것이 나의 스키마가 정의 된 방법이기 때문에 목적에 따라 그렇게했다. 오류는 nominationType에 따라 다릅니다. 그것은 움직여야 하는가? – jackncoke

0

내가 mutateAndGetPayload에 오류가 발생 할 수 있습니다 :

아래처럼 릴레이 돌연변이의 (Nomination_addMutation) 지방 쿼리에 Errors 포함이가 가진 돌연변이의 onFailure 콜백에 오류 메시지로 배송됩니다 오류 메시지는 내가 던지는 것입니다.

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

오류가 발생하여 클라이언트 쪽에서 하나 이상의 유효성 검사 오류를 수신 할 수 있습니다. 이것은 내가 알 수있는 유일한 제한 사항입니다. –

+0

처음에는 (귀하의 queston에서) [이 기사] (https://medium.com/@tarkus/validation-and-user-errors-in-graphql-mutations-39ca79cd00bf#)에서와 같은 방식을 따랐습니다. .e4p4rfw8x). 실제로 이것은 매우 좋은 접근 방법입니다. –

+0

예, 저는 그 기사를 즐겼고 저의 graphql 돌연변이는 똑같이 작동합니다. 그것은 내가하는 것처럼 돌연변이를 사용하는 릴레이를 얻고 있습니다, 내 문제입니다! – jackncoke

관련 문제