Search code examples
scalaimplicitimplicit-parameters

On the readability of implicit parameters


All methods in my DAO class that handles folders (the web application is about cloud storage, like google drive) has User as first parameter. This parameter is used so that the current user may only access folders that he or she owns.

Some of examples:

class FolderDAO {
    def findRoot(user: User): Future[Option[DBFolder]] = { /* implementation */}

    def findById(user: User, folderId: Long): Future[Option[DBFolder]] = { /* implementation */}

    def findChildren(user: User, folder: DBFolder): Future[List[DBFolder]] = { /* implementation */}
}

and so on.

There is a possibility that one day I will need a method there that does not need a User parameter, but it will still be in minority.

As you might imagine, the use of such methods is quite cumbersome.

I identified 3 solutions to the problem:

  1. Leave it as it is as readability is above all
  2. User service store current user and is accessible to all other services (and DAOs) (this looks like a global variable, but the service is injectable, so tests are ok)
  3. Implicit user parameter for these methods

With implicits:

def findRoot()(implicit user: User): Future[Option[DBFolder]]

def findById(folderId: Long)(implicit user: User): Future[Option[DBFolder]]

def findChildren(folder: DBFolder)(implicit user: User): Future[List[DBFolder]]

What do you think is the best option here?

This StackOverflow post gives some insights on the question, but doesn't help a lot, unfortunately


Solution

  • I would probably use a fourth option:

    trait UserService {
      def findRoot(): Future[Option[DBFolder]]
      def findById(folderId: Long): Future[Option[DBFolder]]
      def findChildren(folder: DBFolder): Future[List[DBFolder]]
    }
    
    def userService(user: User): UserService = ???
    

    I'm generally skeptical to using implicit parameters just for saving some characters when calling the method. It decreases clarity for little benefit.