Open arojunior opened 7 years ago
Hi! Thanks for your feedback! You're right!
User
is an external reference and, in this case, the right way to deal with it would be isolating everything in an isolate module and using partial application. The dependency injection methodology, however, can still be replaced by partial application:
lib/db.js
import { curry } from 'ramda'
// Remember the nice way to deal with null values is with monads and
// not undefined' nor
null'. I'm using the classic way here just for the sake
// of clarity of the original purpose of the issue
export const find = curry((collection, query) => collection.find.bind(collection, query))
- `db/find-user.js`
```js
import { find } from '../lib/db'
import User from '../model/user'
export default find(User)
index.js
import { IO } from 'ramda-fantasy'
import findUser from './db/find-user'
const logUserWithId10 = IO(() => { findUser({ id: 10 }).tap(console.log) })
logUser.runIO()
Of course, this is a model to only find the user. In a CRUD application, the generated model probably will already do that for you. Mongoose does something similar, but is full of failures. This would be a good abstraction to, for example, Mongo driver directly.
Thus, a function to list users could be easily written as:
```js
import findUser from '../db/find-user'
export const listUsers = findUser.bind({}) // {} is the query
These patterns, in general, work great together, but may present issues individually. For example, if you try to use monads individually in Java without even dealing with the rest of the effects and avoiding mutability, you'll have problems. Functional programming is all about composition :heart:
In user.js example:
The
listUsers
method is using an external reference. WhereUser
come from?Is it not a good practice to pass what the method gonna need as argument?
Considering that
User
is something like:Then you can inject to
listUsers
And then you can call
listUsers(User)
What if you expect an
id
to filter the users list? (i'm not going to implement anotherUsers
) but you can do something like:You got everything you need inside the method.
Thank you for this repo, I learned a lot.