sttp, curl, request logging and functional programming

Adam Warski
SoftwareMill Tech Blog
2 min readJun 13, 2019

--

A brand-new addition to sttp is the ability to convert the description of an HTTP request to a curl command. This was contributed by Kasper Kondzielski, and while the feature is small, it might be very useful during development and debugging.

Photo source

Here’s how it works. First, you describe the request using the sttp API; for example:

Then, you call the .toCurl method and get the command you can run from your terminal:

Debugging

How can this be useful during development? For example, you can DEBUG-log all requests, along with the curl commands necessary to reproduce them.

Request logging in sttp is best implemented using a backend wrapper, which separates the description of the request from its execution. For example, we can create the following logging backend:

And then use it as follows:

Any request will now be logged along with a way to reproduce it.

Functional programming

What does it have to do with functional programming? A lot!

With sttp, we first describe the request using sttp’s API. Then, we need to provide a backend, which knows how to send the request over the network. Finally, we have backend wrappers, which add some functionality to other backends, such as redirects, logging, metrics etc.

In other words: we have immutable values, which are descriptions of requests. The sttp API defines a number of functions, which add more detail to these values. Then, the backends are functions as well, which interpret the descriptions and send the requests over the network. Finally, backend wrappers are higher-order functions, which take functions (other backends) and return a function (a backend).

Such separation of description from interpretation is not only a very useful technique, but also at the core of many “functional” libraries. Creating descriptions, representing them as values and manipulating using functions allows equational reasoning and greater code reuse. Moreover, interpreters (and “higher-order” interpreters) naturally help in separating concerns.

Give it a try!

To see how this works in practice, all you need is the core sttp library. Either use Ammonite to try in a REPL, or add it to your project — there are no transitive dependencies. The docs contain a quick-start for both cases.

--

--

Software engineer, Functional Programming and Scala enthusiast, SoftwareMill co-founder