Recently I came across Timo von Holtz’s servant-JuicyPixels package. It describes servant
-compatible content-types for JuicyPixel’s DynamicImage
data type, and clocks under 100 airy lines.
Timo and I realized there is a pretty neat demonstration of the advantage of abstracting away content-type serialization and deserialization: the world’s most concise image-conversion web service. Essentially the same application is available as the image conversion
example in Timo’s package.
(If you want to know more about how content-types work in servant
, the content-type section of the tutorial has more information.)
The Application
Our goal is to provide a service that converts images between formats based on the Content-Type
and Accept
headers of the request:
$ curl localhost:8001 -H "Content-Type: image/png" \
-H "Accept: image/jpeg" \
--data-binary "@haskell-logo.png" \
> haskell-logo.jpeg
To get there, we need to do a couple of things. We need to of course run the application:
And describe the API:
type ConversionApi
= ReqBody '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
:> Post '[BMP, GIF, JPEG 50, PNG, TIFF, RADIANCE] DynamicImage
As you can see, we state that we accept and can return a variety of image formats.
The application is then:
And for the clincher, the handler:
And that’s it!
Conclusion
This is just the limit of the relative gain of abstracting content-types - there is nothing to the application besides them!
Essentially the same idea could of course be applied to other areas. Document conversion with Pandoc, video and audio formats, etc.