in ,

A Dead-Simple Web Stack in Haskell, Hacker News


Haskell has a proliferation of libraries to choose from for all of your basic backend needs, from logging to database access to routing and web server definition. It’s nice to have the freedom of choice, but if you’re just starting out, the amount of decisions needed can be overwhelming. Maybe you’re not even confident enough yet that you’ll be able to discern important differences between all the choices out there. You need to query your database. Do you want the strong column name guarantees and deep SQL embedding thatSquealgives you, or would you prefer the relative simplicity ofOpaleyewhile still getting type safety? Or maybe it would be better to just usepostgresql-simpleand keep thingsreallyEasy? Or what about usingSelda? Or what about…

As a way to show that you don’t need to spend tons of agonizing about how advanced your stack is, as well as a learning opportunity for myself, I’ve written an example web application using the simplest libraries I could find. If you’re not sure how to go about building real applications in Haskell, why not try learning from it? I’ve deliberately tried to keep the codebase as simple as I could. You can find thesource code here.

Let’s go over what libraries I chose and what you should expect from them, as well as what the application is.

Okay, so what is this web app anyways?

It’s a site where users can create custom timers and notes for themselves.

For instance, one use case might be cooking: Someone might need to set up various different timers to track the progress of different reagents, as well as notes to themselves about things that they have to be careful of, things that can be improved for the next time they make a recipe, etc. Another use case might be someone playing a MOBA, like League of Legends or Dota 2, where they could have a page open in a second monitor to track key cooldowns, as well as notes to themselves about how to macro versus the enemy composition and cooldowns to keep in mind while teamfighting.

This lets me demonstrate:

  • Sessions, since users should be able to refresh the page , or leave and come back, and still see the same elements.
  • Persistence and database access, since we need to save the timers and notes for each user. Another subtlety is that timers should retain their remaining time. (What if it’s a 30 minutes timer and the user accidentally closes the page?)
  • Run-time configuration, since we can’t hardcode database connection info.
  • Logging. Self-explanatory for a web application.

Here’s the application source code.

Okay, so what are the libraries?

Routing and web server: Spock

Spockends up being the library of choice here because of its ease of use. If you’re ever used Ruby’s Sinatra, Spock should feel very similar.1Spock also comes with session handling out of the box, which is very nice.

For instance, defining a server with a few routes to send back HTML and JSON might look like this:

Database access: postgresql-simple

postgresql-simplebasically just lets you run raw SQL queries against your database, with minimum of extra frills, such as protection against injection attacks. It does what you would expect and nothing more.

Configuration: configurator

configuratorreads configuration files and parses them into Haskell datatypes. It’s a bit more featureful than your usual config file reader; if you’re used to flat configuration files, configurator has a few more tricks up its sleeves. Config attributes can be nested for grouping, and configurator also provides hot reloading on config file change, if you need that.

# An example config file.  app_name="The Whispering Fog"  db {   pool {     stripes=4     resource_ttl=300   }    username="pallas"   password="thefalloflatinium"   dbname="italy" }

Logging: fast-logger

fast-loggerprovides a reasonbly simple-to-use logging solution. In the example web application, I just use it to print to stderr, but it has options to log to files as well. While it has a lot of types, for the most part you’ll want to define helper functions that just take in a LoggerSet and the message you want to log.

Generating HTML: blaze-html

While there wasn’t much HTML that needed to be generated from the backend on this project, it’s worth mentioningblaze-htmlfor the parts that Ididneed.

It’s essentially just an shallow embedding of HTML into a Haskell DSL. If you can write HTML, you already know how to use this library.

Building and frontend: make npm

Yeah, yeah, these aren’t libraries. Still, we needed some sort of JavaScript frontend, since the timers have to update in realtime. Webpack produced the JS bundle, while Make assembled the final application output.

I won’t talk too much about these. There are plenty of resources about using both of these tools elsewhere.

Do I have to use these ?

No, of course not. If you’re exploring Haskell in the first place, you’re probably naturally curious. Don’t let me hold you down or dictate what you should do. While this applicationworks, many parts of it would be considered unidiomatic for production Haskell. For instance, many Haskellers would likely use Servant instead of Spock for defining the API endpoints. If you’re interested in other library choices, you should absolutely follow your inclinations.

Think of these libraries and this application as a starting point. I encourage you to use this code as a learning opportunity and figure out how it works, then start tinkering. One of the beautiful things about Haskell is how easy it is to refactor or upgrade without breaking things. Once you’ve got a handle on this application, why not try replacing parts of it with more advanced libraries that give you more guarantees, as a way of incrementally learning Haskell?

  • Upgrade the DB access to use a type-safe query library instead ofpostgresql-simple. I recommendOpaleye!
  • Upgrade the API definition to useServantinstead of Spock.
  • Add automated testing usingQuickCheck(orHedgehog. For instance, you could test the property that every error response from the server also sends back a JSON error message.

And you could even try replacing the frontend and build system.

  • Upgrade the frontend code to use(PureScript)orElminstead of vanilla JavaScript.
  • Upgrade the build system to useShakeinstead of Make to make things more robust.

Here’s the link to the example application source code if you missed it.

Want advice on where to start tinkering? Found this useful? Still have questions?


You might also like


↥1Which makes sense, since Spock’s documentation states that it was inspired by Sinatra!

  


      Before you close that tab …     

    

      Want to write practical, production-ready Haskell? Tired of broken       libraries, barebones documentation, and endless type-theory papers only a       postdoc could understand? I want to help. Subscribe below and you’ll get       useful techniques for writing real, useful programs straight in your       inbox.     

         

      Absolutely no spam, ever. I respect your email privacy. Unsubscribe anytime.     

  

Brave Browser
Read More
Payeer

What do you think?

Leave a Reply

Your email address will not be published. Required fields are marked *

GIPHY App Key not set. Please check settings

Distributed Denial of Secrets on Twitter, Hacker News

Distributed Denial of Secrets on Twitter, Hacker News

Apple releases iOS and iPadOS 13.2.3, Ars Technica

Apple releases iOS and iPadOS 13.2.3, Ars Technica