Source operations vs Flow

I have a beginner’s query regarding operations available on Source.
Take for example map method. I can use it to transform elements. But then we also have Flow block to do same.

Why do we have Flow as well as operations on source for transformations?

The map operation transforms elements that are going from the output port. Since both Source and a Flow has an output port, map operation is available on both of these types.

You might find the Akka Stream documentation page on the “Modularity, Composition and Hierarchy” interesting.

When it comes to organizing code, both of the definitions of source1 and source2 define the same Source:


val source1 = Source.single(1).map(_.toString)

val flow = Flow[Int].map(_.toString)
val source2 = Source.single(1).via(flow)

If the transformation of the elements is to be reused in other stream definitions, then it makes sense to have it as a separate reusable Flow. Otherwise defining transformation directly on the Source is fine.