File upload using akka-http in Scala

Lets begin with some introduction of Akka-http first.

Akka HTTP is a layer to expose Actors to the web via HTTP and to enable them to consume HTTP services as a client. It is not an HTTP framework, it is an Actor-based toolkit for interacting with web services and clients. This toolkit is structured into several layers:

  • akka-http-core: A complete implementation of the HTTP standard, both as client and server.
  • akka-http: A convenient and powerful routing DSL for expressing web services.
  • akka-http-testkit: A test harness and set of utilities for verifying your web service implementations.

For more information, see here.

Now its time to go into some code.

To use akka-http, we need to add library in our application.  So to do the same, add following dependencies in build.sbt file.:

"com.typesafe.akka" %% "akka-stream-experimental" % "2.0.2",
"com.typesafe.akka" %% "akka-http-core-experimental" % "2.0.2",
"com.typesafe.akka" %% "akka-http-experimental" % "2.0.2"

Now we will write a route to which we can send our file upload request :

package com.rishi

import java.util.UUID

import akka.http.scaladsl.model.{HttpResponse, Multipart, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.util.ByteString

trait FileUpload {

  implicit val system = ActorSystem()
  implicit val executor = system.dispatcher
  implicit val materializer = ActorMaterializer()

   * Route for uploading file
  def uploadFile: Route = {
    path("user" / "upload" / "file") {
      (post & entity(as[Multipart.FormData])) { fileData =>
          complete {
              val fileName = UUID.randomUUID().toString
              val temp = System.getProperty("")
               val filePath = temp + "/" + fileName
              processFile(filePath,fileData).map { fileSize =>
              HttpResponse(StatusCodes.OK, entity = s"File successfully uploaded. Fil size is $fileSize")
              }.recover {
               case ex: Exception => HttpResponse(StatusCodes.InternalServerError, entity = "Error in file uploading")

  private def processFile(filePath: String, fileData: Multipart.FormData) = {
    val fileOutput = new FileOutputStream(filePath) { bodyPart ⇒
      def writeFileOnLocal(array: Array[Byte], byteString: ByteString): Array[Byte] = {
        val byteArray: Array[Byte] = byteString.toArray
        array ++ byteArray
    }.runFold(0)(_ + _.length)

  val routes = uploadFile

Here, what we have done is, as route will get file upload request, it will take the file data as multipart and will create a file at our local machine in system’s temp folder.

That’s it. Hope you enjoyed. Happy Blogging. !!!

About Rishi Khandelwal

Lead Consultant having more than 6 years industry experience. He has working experience in various technologies such as Scala, Java8, Play, Akka, Lagom, Spark, Hive, Kafka, Cassandra, Akka-http, Akka-Streams, ElasticSearch, Backbone.js, html5, javascript, Less, Amazon EC2, WebRTC, SBT
This entry was posted in Akka, Future, knoldus, Scala. Bookmark the permalink.

13 Responses to File upload using akka-http in Scala

  1. Pingback: File upload using akka-http in Scala | Arpit Suthar

  2. Hi, I am getting an error in the function processFile() – not enough arguments for method runFold: (implicit materializer:[Array[Byte]]. Unspecified value parameter materializer. I tried adding these:

    implicit val system = ActorSystem(“Sys”)
    implicit val materializer = ActorMaterializer()

    Then I started getting error in the uploadFile function in line : processFile(filePath, fileData).map { fileSize =>

    ◾Cannot find an implicit ExecutionContext. You might pass an (implicit ec: ExecutionContext) parameter to your method or import

    Can you pls help me resolve this, so that the async nature is not lost

    • Hi Anand. Thanks for pointing me the error.

      I have updated the blog. I missed to include some implicit variables.
      Now please give it a try one more time and let me know if you get any error.

  3. Hello Rishi,
    One other thing I noticed is that, when I try to upload a file of size 150 MB, the POST request is failing after around 8-9 seconds. Any idea how to fix it?

  4. A.G. says:

    Hello Anand,
    150MB issue may be related to akka-http config. Default incoming request size is 8MB. Have you tried increasing akka.http.server.parsing.max-content-length ?

  5. avis says:

    Looks good, How do we get form-data inside multipart?

  6. Pingback: Test cases for file upload using akka-http in Scala | Knoldus

  7. Pingback: A basic application to handle multipart form data using akka-http with test cases in Scala | Knoldus

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s