在同构通量应用程序中,是不是应该在操作中实现 REST api 调用?
Posted
技术标签:
【中文标题】在同构通量应用程序中,是不是应该在操作中实现 REST api 调用?【英文标题】:In an isomorphic flux application, should the REST api calls be implemented in the action?在同构通量应用程序中,是否应该在操作中实现 REST api 调用? 【发布时间】:2016-01-25 15:08:05 【问题描述】:应该在动作创建器中实现,还是在服务类或组件中实现?如果是同构 Web 应用,推荐是否会改变?
我见过两个不同的例子:
-
动作创建者在进行其余调用后调度一个动作 login_success/login_failure
组件首先调用 api 服务,该服务直接创建 login_success 或 failure 操作
示例 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
组件 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 架构中的更好/标准位置是什么?
【问题讨论】:
【参考方案1】:我使用带有 api 实用程序的 api.store。来自https://github.com/calitek/ReactPatternsReact.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(); ) ,
;
【讨论】:
【参考方案2】:根据我的经验,最好使用选项 1:
将 API 调用放在动作创建者而不是组件中可以让您更好地分离关注点:您的组件 (-tree) 只调用“登录”动作,并且可能不知道响应来自何处。如果登录详细信息已知,理论上可能来自商店。 对 API 的调用在操作中更加集中,因此更易于调试。选项 2 看起来仍然符合通量设计原则。
还有第三种选择的倡导者:从商店调用 webAPI。这使得服务器端和客户端数据结构的紧密耦合更容易/更有条理。如果在客户端和服务器之间同步独立数据结构是一个关键问题,可能会更好。我对第三种选择的经验并不乐观:让商店(间接)创建操作打破了单向通量模式。对我的好处永远不会超过调试中的额外麻烦。但您的结果可能会有所不同。
【讨论】:
以上是关于在同构通量应用程序中,是不是应该在操作中实现 REST api 调用?的主要内容,如果未能解决你的问题,请参考以下文章