https://kotlinlang.org logo
Title
d

dimsuz

12/10/2021, 4:00 PM
Naming question. Maybe offtopic? (naming is hard) I have a computation which reads a DB value, and some scenarios permit reading it in a suspending manner, but in others it's better to represent this value as stream, so API provides both ways
suspend fun userList(): List<User>
fun userList(): Flow<List<User>>
Any idea on naming here, so that they don't conflict? in Rx we used to call the "blocking" one
userListSync
, and "sync" were rare beasts actually. But in coroutine world calling
suspend
function "sync" is not correct.
one could also use flow-version and do
userList().first()
, effectively removing the need for a separate suspending one, but this incurs setting up flow which in this case could be potenitally costly
j

Joffrey

12/10/2021, 4:02 PM
Which is the most commonly used? Because I guess the additional word(s) should be on the "rarely used" side
d

dimsuz

12/10/2021, 4:02 PM
yeah, just thought to add this too. most commonly used is the
Flow
one
j

Joffrey

12/10/2021, 4:03 PM
One option is
fetchUserList()
for the one-shot, and just
userList()
for the flow
d

dimsuz

12/10/2021, 4:03 PM
oh, nice idea. or
readUserList()
maybe
a

Adam Powell

12/10/2021, 4:05 PM
I find that using a plural for the flow tends to be more clear for a reader and avoids these conflicts
d

dimsuz

12/10/2021, 4:06 PM
userLists(): Flow<List<User>>
?
a

Adam Powell

12/10/2021, 4:06 PM
But also +1 to using a verb for the fetch operation. Using a noun for the flow tends to read well since a flow is a factory for future operations rather than a command to perform the operation right there. (The terminal operator of the flow is the verb.)
Yeah,
userLists
c

Casey Brooks

12/10/2021, 4:07 PM
I have a project where I needed to do this commonly enough, that I created a wrapper API that takes in a Flow, and consumers can then choose for themselves how to read values (rather than bloating the Repository interface)
class Query<T>(
    private val liveQuery: Flow<T>,
    private val defaultValue: T,
) {

    fun asFlow(): Flow<T> {
        return liveQuery
    }

    @Composable
    fun asState(): State<T> {
        return liveQuery.collectAsState(defaultValue)
    }

    suspend fun await(): T {
        return liveQuery.first()
    }
}
j

Joffrey

12/10/2021, 4:07 PM
I find that using a plural for the flow tends to be more clear for a reader and avoids these conflicts
That's a fair point, but at the same time it can be confusing. It's hard to tell whether there are multiple lists of users, or whether the flow represents updates to the same list
@Casey Brooks the problem is that creating a flow and getting the first element can be costly on the implementation side. You need to register something to listen to updates, only to unregister it right away
1
a

Adam Powell

12/10/2021, 4:09 PM
Sometimes, but it's usually clear from context whether you're talking about progressive chunked data or a sequence of state replacements over time. The latter tends to be more common
r

rudolf.hladik

12/13/2021, 8:26 AM
we use
getUserList()
for suspend and
observeUserList()
for flow, beacause you are basically observing changest to db
👍 1