如何使用Relay处理服务器端输入验证?

时间:2016-05-05 07:29:18

标签: relayjs

我有以下有效的GraphQL操作:

GraphQL Mutation:

mutation CreateUserMutation ($input: CreateUserInput!) {
  createUser(input: $input) {
    clientMutationId
    userEdge {
      node {
        email
        username
      }
    },
    validationErrors {
      id
      email
    }
  }
}

GraphQL突变响应:

{
  "data": {
    "createUser": {
      "clientMutationId": "112",
      "userEdge": {
        "node": {
          "email": "prasath112@example.com",
          "username": "soosap112"
        }
      },
      "validationErrors": {
        "id": "create-user-validation-errors",
        "email": [
          "Email looks not so good."
        ]
      }
    }
  }
}

到目前为止,我的GraphQL响应validationErrors是键值对的对象,其中始终是来自输出验证错误消息的数组服务器相对于特定的输入字段(即{'email': ['email is taken', 'email is on blacklist']})。

下一步(这是我需要帮助的地方) - 如何在中继客户端商店中使用该数据?换句话说,如何使我的组件中的validationErrors可用this.props.validationErrors

CreateUserMutation.js

import Relay from 'react-relay';

export class CreateUserMutation extends Relay.Mutation {
  getMutation() {
    return Relay.QL`
      mutation {
        createUser
      }
    `;
  }

  getVariables() {
    return {
      email: this.props.email,
      username: this.props.username,
      password: this.props.password,
    };
  }

  getFatQuery() {
    return Relay.QL`
      fragment on CreateUserPayload @relay(pattern: true) {
        userEdge,
        validationErrors,
        viewer { userConnection }
      }
    `;
  }

  getConfigs() {
    return [
      {
        type: 'FIELDS_CHANGE',
        fieldIDs: {
          validationErrors: 'create-user-validation-errors',
        },
      },
      {
        type: 'RANGE_ADD',
        parentName: 'viewer',
        parentID: this.props.viewer.id,
        connectionName: 'userConnection',
        edgeName: 'userEdge',
        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',
        },
      },
    ];
  }
}

以下是我的尝试:首先,我可以使用 getConfigs RANGE_ADD用户边消耗到我的Relay客户端商店中。由于我的validationErrors对象没有实现连接模型,FIELDS_CHANGE似乎是我案例中唯一合理的类型。我正在尝试模拟Relay似乎需要使用' create-user-validation-errors'来填充客户端商店的 dataID 。作为一个独特的身份。

以下是我的React组件的一个片段,用于完成示例。

class App extends React.Component {
  static propTypes = {
    limit: React.PropTypes.number,
    viewer: React.PropTypes.object,
    validationErrors: React.PropTypes.object,
  };

  static defaultProps = {
    limit: 5,
    validationErrors: {
      id: 'create-user-validation-errors',
    },
  };

  handleUserSubmit = (e) => {
    e.preventDefault();

    Relay.Store.commitUpdate(
      new CreateUserMutation({
        email: this.refs.newEmail.value,
        username: this.refs.newUsername.value,
        password: this.refs.newPassword.value,
        viewer: this.props.viewer,
      })
    );
  };
  • 如何使用Relay从React组件中的GraphQL响应中使用基于非连接模型的信息?最低工作范例很棒。

  • 您是否知道使用GraphQL和Relay进行服务器端输入验证的更好方法?

1 个答案:

答案 0 :(得分:2)

突变成功或失败。我通常设计客户端变异的胖查询和配置,记住成功案例。要处理失败案例,突变的回调函数就足够了。

如何使用Relay从React组件中的GraphQL响应中使用基于非连接模型的信息?

我知道两种方式

1)在FIELDS_CHANGE客户端变异代码函数中使用getConfigs类型当我们需要更新Relay存储中的数据以响应变异的结果时,通常使用。代码如下所示:

getFatQuery() {
  return Relay.QL`
    fragment on CreateUserPayload {
      ...
      ...
      viewer { 
        userCount,
      }
    }
  `;
}

getConfigs() {
  return [
    {
      type: 'FIELDS_CHANGE',
      fieldIDs: {
        viewer: this.props.viewer.id,
      },
    },
    ...
    ...
  ];
}

在您的情况下,如果您想将validationErrors作为中继商店的一部分进行更新,请将其作为道具传递给validationErrors: this.props.validationErrors.id

2)使用变异的回调函数:当我们只需要一些不会影响中继存储中数据的信息时,这是一个不错的选择。代码如下所示:

const mutation = new CreateUserMutation({
  email: this.state.email,
  username: this.state.username,
  password: this.state.password,
  viewer: this.props.viewer,
});
const onSuccess = (response) => {
  // If you have both successful data update and some other extra info, you
  // can have, say `response.warnings`. The server sends `warnings` in the
  // response object.
};
const onFailure = (transaction) => {
  // This is the most appropriate place for dealing with errors.
  var error = transaction.getError();
  // Get the errors!
};
Relay.Store.commitUpdate(mutation, {onSuccess, onFailure});

您是否知道使用GraphQL和Relay进行服务器端输入验证的更好方法?

GraphQL和Relay支持的基本输入验证目前仅限于使用GraphQLNonNull和预期类型,例如names: new GraphQLNonNull(GraphQLString)。因此,如果我们为name传递一个整数,则变异将失败并提供相应的错误消息。

对于其他类型的验证,服务器端变异中的mutateAndGetPayload函数是一个很好的地方,我们可以应用自己的逻辑。

Konstantin Tarkus对GraphQL突变中的输入验证有an excellent article