Adding a very naive in-memory cache to my Haskell web app

How I added very naive in-memory caching to my haskell webapp

vados

28 minute read

tl;dr - I added some caching to an app I’m writing in Haskell using Servant. The implementation is pretty naive, but I’ve seen some speedups (as one would expect from skipping a database access), and am glad I was able to build such a simple solution in a language as expressive as haskell. Skip to the end TLDR section to see all the code laid out! FAIR WARNING - this will is NOT an interesting article about caching algorithms or a quirk in GHC or optimization strategies.

Adding Sqlite Powered Fts Search To A Servant Powered Haskell App

Adding light and easy Full Text Search with SQLite3 to my servant-powered web app

vados

17 minute read

tl;dr - You may not need a big robust beautifully crafted DB like Postgres every time you build an app. Sometimes SQlite is probably enough. SQLite even provides Full Text Search addons in the way of FTS3/4 and FTS5, so that’s cool too – skim through the article for code snippets on the why/how I’m using SQLite + FTS3/4. If you’re unfamiliar with SQLite, it’s a pretty awesome light-weight SQL-compliant RDBMS.

Moving From Server Side Sessions To Client Side Session Tokens with Servant

Documenting my move from Network.Wai.Session to Web.ClientSession

vados

12 minute read

tl;dr - I moved from server-side stored sessions provided by Network.Wai.Session to client-side signed+encrypted session tokens provided by Wai.ClientSession for my Servant-powered webapp, it’s pretty easy, skim through to see the setup code, /login and /logout code that was required. UPDATE After posting to r/haskell, user u/cocreature pointed out the existence of the servant-auth package – it looks like an awesome solution so also make sure to give that a try before rolling your own.

End To End Testing With Hspec (Almost)

Setting up E2E testing with HSpec and PhantomJS.

vados

10 minute read

tl;dr While the setup works, the most mature haskell library for dealing with webdrivers that I could find wasn’t able to keep up with the changes in Selenium Webdriver :(. Skim through the post to check out the relevant code snippets and tech that made it all (almost) work. If you’re not familiar with Haskell, check it out. This isn’t an introductory type post so it might not be for you, but the language is amazing.

Adding A Merge Patch Content Type To Servant

How to add a content type for HTTP spec compliant merge-patching in Servant

vados

6 minute read

*tl;dr See the code at the end Very often when developing a web application I run into the age-old problem of how to do partial updates. Doing the “U” (Update) in CRUD is actually a little more complicated than just accepting PUTs at some endpoint if you dont’ want to replace the object as a whole. I’ve often worked around this while maintaining somewhere-near spec complicance by just using the catch-all that is POST, and taking whatever object represented the update and doing whatever needed to be done.

Case Study: Building A URL Bouncer

Building a URL bouncer for a servant-powered web application

vados

19 minute read

tl;dr - Building a simple URL bouncer with Servant isn’t that hard, and the usual warm fuzzies you get from well-typed functions, interfaces, and code still apply If you’re not familiar with Haskell or Servant, the former is a programming language that focuses on pure functional concepts and the latter is one of the most interesting/popular frameworks for it that specializes in exposing your API as a type itself. A brief taste of both of these things is below:

vados

9 minute read

tl/dr; I tried to expand the cookie-based auth I implemented in servant and failed. While I’ll probably try again some other day, for now I just resorted to writing functions to get the functions for a user and do checking directly in my handlers Here’s the tale of how I tried to add Role checking (based on my application’s defined Role type) to my servant app, and ran into a few issues and things I didn’t understand and ultimately failed.