Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: strategies for a global workflow (redux style data store) for data that is central to the app? #1209

Open
gregkerzhner opened this issue Jul 13, 2020 · 3 comments

Comments

@gregkerzhner
Copy link

gregkerzhner commented Jul 13, 2020

Thanks for open sourcing this awesome library. It seems like an awesome port of the React framework for iOS. The natural question to ask is - what about a global data store?

The hierarchical nature of Workflow makes a lot of sense for some state that closely mirrors the view hierarchy. However, other types of state is usually global to the app and independent of any view stack. Something like currentUser or authentication state is a good example of this kind of state. Where does workflow encourage me to keep such state?

It seems like out of the box I would be encouraged to keep such global data in a "root workflow" that's parent to all other workflows. However, this quickly becomes cumbersome because state from this parent workflow needs to be passed through all unrelated layers of the workflow hierarchy to get to the child workflow that actually needs it.

This issue is often called "prop drilling" in the React world and Redux exists (in part) to address it. The same problem exists with outputs - intermediary workflows would need to mindlessly pass outputs up the hierarchy leading to a lot of extra code.

Curious if you have ran into these kinds of issues while building on top of Workflow and what strategies you use to overcome them. I've only played with Workflow a bit so please excuse me if I am missing something.

@gregkerzhner gregkerzhner changed the title Question: strategies for a global workflow (data store) for data that is central to the app? Question: strategies for a global workflow (redux style data store) for data that is central to the app? Jul 13, 2020
@dhavalshreyas
Copy link
Contributor

Hey there @gregkerzhner!

Good question. We do not have a solution for this right now. For the most part, we've been passing in the dependencies at each level. We have considered different solutions for "prop drilling", however we have not settled on anything yet.

For passing objects purely on the "View" side, we have ViewEnvironment. However, we have been hesitant to build something like this at the Workflow level. The concerns have revolved around testability/maintainability.

@rjrjr
Copy link
Contributor

rjrjr commented May 4, 2022

If you're still listening, dependency injection is very practical in Workflow. Our Kotlin apps use Dagger like crazy, for example.

It's a little more natural to think about in the Workflow Kotlin API because our PropsT parameter type is separate from general constructor args. So we put @Inject on constructors, and use PropsT for runtime configuration only.

But there's no reason Swift can't work the same way. We didn't break out PropsT in Kotlin because we're bigger on DI, we did it because Kotlin has nothing like Swift's self types, so we couldn't specialize our equivalent of workflowDidChange.

To get the same effect in Swift, use the factory pattern when dealing with a child workflow that needs access to services or model objects that the parent should be ignorant of. So a call like this:

  return AuthenticationWorkflow(authenticationService: AuthenticationService())
      .mapOutput { /* ... */ }
      .rendered(in: context)

becomes this:

    return authenticationWorkflowFactory.build()
      .mapOutput { /* ... */ }
      .rendered(in: context)

If you apply changes like that all the way up the call chain, presto, you have achieved DI, and none of the 25 ancestors of this workflow that uses the AuthenticationWorkflow know anything about its use of AuthenticationService. Nor of this workflow's use of AuthenticationWorkflow, since its parent will have called someChildWorkflowFactory.build().rendered(in: context).

tl;dr: DI is a pattern, not a framework, and Workflow is very friendly to it out of the box. We have no plans to introduce a service provider mechanism for it.

@rjrjr
Copy link
Contributor

rjrjr commented May 4, 2022

Keeping this ticket open to serve as the seed of proper documentation on this theme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants