Using Akka Http to create a test server

In a recent post we explored akka http, how to define routes, handle requests/responses, and deal with json marshalling/unmarshalling using spray.
Once you know the syntax for defining routes and manage json, is pretty straightforward to run a local server:
val server = Http().bindAndHandle(routes, host, port)
One interesting application I found for this is to create a local embedded server for component testing: when test a serivce that does http calls to other services (the most common situation when using microservices), you can mock all the REST calls but that usually ignores many tricky details  (like connection, protocol, authentication, etc. ), alternatively, you can do integration test, but normally involves either connecting to a vpn to access the test environment or start a bunch of docker images with the external services.
As an intermediate solution, we can use a local akka http server that behaves like the services we depend on, avoiding mocking the http calls and the complexity of running the full serivices.The Code
Let’s create a small trait that we can add to our tests and manage the local server.
First, we want a nice syntax… something like:

withEmbeddedServer { test code }

Although we need to pass the routes, so we’ll have

withEmbeddedServer(routes){ test code }

The bindAndHandle method that starts the server needs port and the host name, we can pick some defaults (“localhost” and 8080 maybe?) but we probably want the possibility of override them:

withEmbeddedServer("myserver", 8888, routes){ test code }

The block must be evaluated lazily and we might want to capture the output of the execution, so we’re going to assign the block a type of “=>T” (so we need T as a type parameter too)
Finally, to run akka http server we need to pass an implicit ActorSystem, an ActorMaterializer, and an ExecutionContext, so we’ll add those parameters too
So, the signature of the method will look like:

def withEmbeddedServer[T](host: String = "localhost", port: Int = 8080, routes: Route)(block: => T)
   (implicit system: ActorSystem, mat: ActorMaterializer, ec: ExecutionContext): T  = ???

Now, the actual implementation is pretty straightforward: start the server, evaluate the block, stop the server, and return the value.
To keep things simple, we’re going to surround the block evaluation with a try-finally block:

def withEmbeddedServer[T](host: String = "localhost", port: Int = 8080, routes: Route)(block: => T)
  (implicit system: ActorSystem, mat: ActorMaterializer, ec: ExecutionContext): T  = {
  val server = Http().bindAndHandle(routes, host, port)
  try {
    block
  } finally {
    server.flatMap(_.terminate(shutdownDeadline))
  }
}

The terminate method requires a timeout parameter, and for more flexibility, let’s define it as member value so it can be overridden if you don’t like the default value:

trait EmbeddedHttpServer {

  val shutdownDeadline: FiniteDuration = 10.seconds

  def withEmbeddedServer[T](host: String = "localhost", port: Int = 8080, routes: Route)(block: => T)
    (implicit system: ActorSystem, mat: ActorMaterializer, ec: ExecutionContext): T  = {
    val server = Http().bindAndHandle(routes, host, port)
    try {
      block
    } finally {
      server.flatMap(_.terminate(shutdownDeadline))
    }
  }

}

Now you can mix the trait in your test class and have access to the “withEmbeddedServer” method, but we don’t need to mix it, we can create an object providing that method and we can import it anywhere we need it:

object EmbeddedHttpServer extends EmbeddedHttpServer

As an example, let’s simulate a  service that respond  with “hello” when you do a GET to /hi path and write test code that verifies that.

Our code to test will look like:

def callHiService(): Future[Seq[ByteString]] = {
  val url = "http://localhost:8989/hi"
  val result = Http().singleRequest(HttpRequest(uri = Uri(url))).futureValue
  val HttpResponse(StatusCodes.OK, _, entity, _) = result
  entity.dataBytes.runWith(Sink.seq)
}

(In a real case you probably will call a Swagger generated client Api overriding the host and base path properties in your test config)

And our test (using ScalaTest) will be:

"The embedded server" should "respond with hello" in {
  //create a route that responds with "hello" to a GET to /hi
  val hiRoute = path("hi") { get { complete("Hello")} }
  
  //start the embedded server and run the test
  withEmbeddedServer(port = 8989, routes = hiRoute){
    val body = callHiService().futureValue
    body.head.utf8String shouldBe "Hello"
  }
}

 

And that’s it, thanks for listening.
NOTE: You can find the code for this project at: https://github.com/Scalents/embedded-http-server

Basic Category Theory for (Scala) Programmers (Part I)

“Aren’t you tired of just nodding along when your friends starts talking about morphisms? Do you feel left out when your coworkers discuss a coproduct endofunctor?

From the dark corners of mathematics to a programming language near you, category theory offers a compact but powerful set of tools to build and reason about programs. If you ever wondered what’s a category or a functor and why care, this series might be just what are you looking for.

But don’t wait! If you call now, you’ll get this explanation of dual categories!

Next time, you too can be the soul of the party and impress your friends with category theory!*”

*(results may vary)

Intro

Category theory is a branch of abstract math. Why it gets so much attention from (functional) programmers?

As it happens, modeling programs using category theory allows us to apply theoretical results directly to our code, explore new approaches to existing problems, and increase our confidence on the solutions. At first, category theory might seem impenetrable, but one can go far by learning the basic vocabulary

But let’s go to the beginning

What’s one of the most important technique for programming?

ABSTRACTION!

 

Removing unnecessary detail and keeping the essence is an extremely powerful tool for programming.

What if we dial it to eleven?

Let’s abstract over all the characteristics of the things we want to model, and just end with “things” (called objects) and the connections between them (called arrows, or if you want to get really fancy, morphisms).

Just things and the connections between them:

 

 

To make a category, we are going to require only two things: every object is connected with itself (identity) and if object A is connected with object B which in turn is connected with object C, we can consider that object A is connected with object C (composition)

If we formalize the definition:

A category Cat is structure consisting of:

Obj(Cat): collection of objects.

For each A,B ∈ Obj(Cat), there’s a set C(A,B) of morphisms from A to B

f:A→B means f ∈ C(A,B)

(In other words, for every pair of objects A and B, there’s a bunch of arrows connecting them… or not)

A composition operation between arrows:

if f:A→B and g:B→C, then g∘f:A→C

(I can make a “new” arrow connecting the end of f with the beginning of g )

For each object X, exists an identity arrow:

IdX:X→X

We’re going to have only two requirements (laws) for the identity and composition of a category:

Identity as unit

For any arrow f:A→B,

f∘IdA = f = IdB∘f

(f composed with identity on A is equal to f and is equal identity on B composed with f)

Composition is associative

f∘(g∘h) = (f∘g)∘h

(it doesn’t matter if I compose f and g first or g and h first, the resulting composition is the same)

Some mathematical examples of categories are:

Set:  the category where the objects are sets and the arrows are functions from one set to another

Pfn: the category of sets and partial functions

How is related to programming?

Yes, most examples in category theory are from math, but what about programming? If we consider the types of a program and the functions between those types, we can form a category: function composition will be our arrow composition and the identity function applied to each type will be our identity morphism. (with the caveat that we have to consider all our functions total and ignore non-termination [infinite loops, exceptions, etc],  also known as bottom ‘_|_’ ).

This is a toy program that takes a String, parses it as Int, divides by two, and gets the byte value of the result.

In Scala:

def toInt(s: String) = s.toInt

def divByTwo(i: Int): Float = i/2f

val program: String => Byte = (toInt _) andThen (divByTwo _) andThen (_.byteValue)

Scala provides an identity function,  so we know that identity[String] , identity[Int], identity[Float], and , identity[Byte] exists. Also, andThen acts as function composition in Scala

Now, is easy to see that (toInt _) andThen (divByTwo _) andThen (_.byteValue) == (toInt _) andThen ((divByTwo _) andThen (_.byteValue)) == ((toInt _) andThen (divByTwo _)) andThen (_.byteValue)

Since identity is defined as def identity[A](x: A): A = x , we can verify identity andThen f == f == f andThen identity is true for any f

So, if we squint and pretend the functions are total, we have:

Objects:  String, Int, Float, Byte

Arrows: toInt _divByTwo _ , _.byteValue

Id: identity

composition:  andThen

identity is neutral and andThen is associative.

So we can model our program with category theory, and take advantage of it.

That’s where the applicability of concepts like Functor, Monad, Natural transformations, etc.  come from.

In our next articles we’re going to expand on why that’s useful… stay tunned.