{"action":"created","issue":{"url":"https://api.github.com/repos/ReSwift/ReSwift/issues/175","repository_url":"https://api.github.com/repos/ReSwift/ReSwift","labels_url":"https://api.github.com/repos/ReSwift/ReSwift/issues/175/labels{/name}","comments_url":"https://api.github.com/repos/ReSwift/ReSwift/issues/175/comments","events_url":"https://api.github.com/repos/ReSwift/ReSwift/issues/175/events","html_url":"https://github.com/ReSwift/ReSwift/issues/175","id":194228306,"number":175,"title":"Simplification of Middleware and Separation of Concerns","user":{"login":"Qata","id":1232443,"avatar_url":"https://avatars.githubusercontent.com/u/1232443?v=3","gravatar_id":"","url":"https://api.github.com/users/Qata","html_url":"https://github.com/Qata","followers_url":"https://api.github.com/users/Qata/followers","following_url":"https://api.github.com/users/Qata/following{/other_user}","gists_url":"https://api.github.com/users/Qata/gists{/gist_id}","starred_url":"https://api.github.com/users/Qata/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Qata/subscriptions","organizations_url":"https://api.github.com/users/Qata/orgs","repos_url":"https://api.github.com/users/Qata/repos","events_url":"https://api.github.com/users/Qata/events{/privacy}","received_events_url":"https://api.github.com/users/Qata/received_events","type":"User","site_admin":false},"labels":[{"id":302043314,"url":"https://api.github.com/repos/ReSwift/ReSwift/labels/Breaking%20API%20Change","name":"Breaking API Change","color":"eb6420","default":false},{"id":302043379,"url":"https://api.github.com/repos/ReSwift/ReSwift/labels/Needs%20Discussion","name":"Needs Discussion","color":"fbca04","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":13,"created_at":"2016-12-08T02:04:59Z","updated_at":"2016-12-14T22:21:03Z","closed_at":null,"body":"I think that `Middleware` as it is right now is very complex and confusing to new users. I propose that we deprecate the current method of creating `Middleware` and instead have `Middleware` be a struct that is generic over the type of your state and provides functions such as `map`, `filter` and `flatMap`.\r\n\r\n[Here is what I've written for ReactiveReSwift](https://github.com/ReSwift/ReactiveReSwift/blob/master/ReactiveReSwift/CoreTypes/Middleware.swift)\r\n\r\nHere's an example of how you'd use it:\r\n\r\n```swift\r\nlet middleware = Middleware<AppState>().sideEffect { getState, dispatch, action in // you can only dispatch new actions from `sideEffect`\r\n    print(action)\r\n    dispatch(PopupAction(description: \"new action\"))\r\n}.map { getState, action in // `map` cannot return `nil`\r\n    return action\r\n}.flatMap { getState, action in // `flatMap` can return `nil` to drop the action before it reaches the store\r\n    if action is PopupAction {\r\n        show(action.description)\r\n        return nil\r\n    } else {\r\n        return action\r\n    }\r\n}.filter { getState, action in\r\n    return action is AppAction\r\n}\r\n```\r\n\r\nIf you create multiple `Middleware` instead of using transformative functions you can then use `Middleware(firstMiddleware, secondMiddleware, [...])` to instantiate a single `Middleware` from multiple."},"comment":{"url":"https://api.github.com/repos/ReSwift/ReSwift/issues/comments/267175355","html_url":"https://github.com/ReSwift/ReSwift/issues/175#issuecomment-267175355","issue_url":"https://api.github.com/repos/ReSwift/ReSwift/issues/175","id":267175355,"user":{"login":"agentk","id":117041,"avatar_url":"https://avatars.githubusercontent.com/u/117041?v=3","gravatar_id":"","url":"https://api.github.com/users/agentk","html_url":"https://github.com/agentk","followers_url":"https://api.github.com/users/agentk/followers","following_url":"https://api.github.com/users/agentk/following{/other_user}","gists_url":"https://api.github.com/users/agentk/gists{/gist_id}","starred_url":"https://api.github.com/users/agentk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agentk/subscriptions","organizations_url":"https://api.github.com/users/agentk/orgs","repos_url":"https://api.github.com/users/agentk/repos","events_url":"https://api.github.com/users/agentk/events{/privacy}","received_events_url":"https://api.github.com/users/agentk/received_events","type":"User","site_admin":false},"created_at":"2016-12-14T22:21:03Z","updated_at":"2016-12-14T22:21:03Z","body":"I ended up having a long conversation with some frontend devs - a couple just learning Redux/React and a one with a lot of experience with Redux.\r\n\r\nThe 'loudest' question the new devs had is - Why do we need so many f*%ing packages on top of Redux? Why do we need redux-thunk, redux-promise and redux-saga? Arn't we just logging events?\r\n\r\nAnd they are completely right.\r\n\r\nThe problem as @DivineDominion pointed out, is that people are using Redux as a command bus. The whole purpose of UDSF (used here to refer to the pattern of Unidirectional State Flow as opposed to libraries) is to derive State from a transaction log of events. Which are intended to be taken for granted that they are a record of things that have happened in the past, and as such should never change (unless you actually have a time machine).\r\n\r\nPlugins for Redux have been adding functionality around UDSF, such as our AsyncActionCreators because the outcomes of those Commands have direct influences on the State with the Events they generate. The two have become so blurred in the Redux world that there is no clear separation anymore in almost all JS projects that use Redux. They are all just a tradeoff of useful functionality and clear separations.\r\n\r\nThe only time I have ever seen it useful for middleware to modify actions or dispatch to return an action, is when ReSwift is treated as a CommandBus.\r\n\r\nI guess I'm asking if anybody has good usage examples of dispatch return values and middleware action interference within strict UDSF?\r\n\r\nIt would make usage a lot clearer if Middleware was renamed to CommandBus and separated out of the Store.\r\n\r\n----\r\n\r\nTL;DR IMO dispatch should return Void, and I would be in favour of the Middleware from ReactiveReSwift if it was renamed to CommandBus and separated out into it's own Store.\r\n"}}
{"actor":{"display_login":"agentk"}}