在同构通道应用程序中,是否应在操作中实现REST api调用?

时间:2015-10-26 13:32:40

标签: reactive-programming reactjs-flux flux

它应该在动作创建者或服务类或组件中实现吗?如果它是一个同构的Web应用程序,建议会改变吗?

我见过两个不同的例子:

  1. 操作创建者在进行其余调用后调度操作login_success / login_failure
  2. 组件首先调用api服务,该服务直接创建login_success或failure操作
  3. 示例1

    https://github.com/schempy/react-flux-api-calls

    /actions/LoginActions.js

    操作本身会触发对api的调用,然后调度成功或失败

    var LoginActions = {
        authenticate: function () {
            RESTApi
                .get('/api/login')
                .then(function (user) {
                       AppDispatcher.dispatch({
                         actionType: "login_success",
                         user: user
                       });
                })
                .catch(function(err) {
                       AppDispatcher.dispatch({actionType:"login_failure"});
                });
        };
    };
    

    示例2

    https://github.com/auth0/react-flux-jwt-authentication-sample

    enter image description here

    组件onclick调用authservice函数,然后在获取验证结果后创建一个操作

    /services/AuthService.js

    class AuthService {
    
      login(username, password) {
        return this.handleAuth(when(request({
          url: LOGIN_URL,
          method: 'POST',
          crossOrigin: true,
          type: 'json',
          data: {
            username, password
          }
        })));
      }
    
      logout() {
        LoginActions.logoutUser();
      }
    
      signup(username, password, extra) {
        return this.handleAuth(when(request({
          url: SIGNUP_URL,
          method: 'POST',
          crossOrigin: true,
          type: 'json',
          data: {
            username, password, extra
          }
        })));
      }
    
      handleAuth(loginPromise) {
        return loginPromise
          .then(function(response) {
            var jwt = response.id_token;
            LoginActions.loginUser(jwt);
            return true;
          });
      }
    }
    

    此次呼叫存在于Flux架构中的更好/标准的位置是什么?

2 个答案:

答案 0 :(得分:0)

我使用带有api实用程序的api.store。来自https://github.com/calitek/ReactPatterns React.14 / ReFluxSuperAgent。

import Reflux from 'reflux';

import Actions from './Actions';
import ApiFct from './../utils/api.js';

let ApiStoreObject = {
	newData: {
		"React version": "0.14",
		"Project": "ReFluxSuperAgent",
		"currentDateTime": new Date().toLocaleString()
	},
	listenables: Actions,
	apiInit() { ApiFct.setData(this.newData); },
	apiInitDone() { ApiFct.getData(); },
	apiSetData(data) { ApiFct.setData(data); }
}
const ApiStore = Reflux.createStore(ApiStoreObject);
export default ApiStore;

import request from 'superagent';

import Actions from '../flux/Actions';

let uri = 'http://localhost:3500';

module.exports = {
	getData() { request.get(uri + '/routes/getData').end((err, res) => { this.gotData(res.body); }); },
	gotData(data) { Actions.gotData1(data); Actions.gotData2(data); Actions.gotData3(data); },
	setData(data) { request.post('/routes/setData').send(data).end((err, res) => { Actions.apiInitDone(); }) },
};

答案 1 :(得分:0)

根据我的经验,最好使用选项1:

  • 将API调用放入操作创建者而不是组件中可以让您更好地区分关注点:您的组件(-tree)只调用"登录我"行动,并且可以对响应的来源保持无知。如果已知登录详细信息,理论上可以来自商店。
  • 对API的调用在操作中更集中,因此更容易调试。

选项2看起来仍然符合助焊剂设计原则。

还有第三种选择的拥护者:从商店调用webAPI。这使得服务器和客户端上的数据结构的紧密耦合更容易/更具区域性。如果在客户端和服务器之间同步独立的数据结构是一个关键问题,那么可能会更好。我的经验对第三种选择并不积极:有商店(间接)创造行动打破了单向通量模式。对我来说,好处从来没有超过调试中的额外麻烦。但是你的结果可能会有所不同。