Notes from the Relevance Postcast episode about Pedestal

The Relevance Podcast episode 27 featured Tim Ewald talking about the Clojure web framework Pedestal. Here are my raw notes that I took while listening to that. I figured they might be useful for somebody else too.

What is it?

Separation between app (clojurescript) and services (clojure). Pedestal is a set of libraries, try not to use the word framework. Rich browser-based apps with back-end services. CLJS – CLJ. Why doing this? There are already many web frameworks.

  • They like building stuff in Clojure. Found issues that they wanted to address, so they are using it themselves.
  • There is an advantage in working with one language end-to-end. Dev/test tools, cross-compiling code, etc.
  • App model separates the logic from the rendering, but all can be built in Clojure. Behaviour cross-compiled and then rendered in the browser.

Browser based apps are more exposed than server based ones. Anyone can pry it open, presents an interesting challenge. If you make a decision in the browser and updates the screen, it needs to send something to the server. If it sends a result, how does the server know this is an acceptable result? E.g. sending $1000 to someone. So don’t send the side-effect/decision, send information so that the server can make the decision. If you want a fast app and a secure server, having the same language simplifies it. No having to rewrite validation checking for decisions in two languages. Is going to be pretty important.

Server side

Services are based on an abstraction called an interceptor. Ran into limitations of Ring. Ring has a lot of work behind it, cookies, sessions, parameter mapping, flash, file info, etc. But the execution model is bound to a single thread, a request follows a thread and then returns a result. But if you want long polling or other techniques where you don’t hold but keep the connection open, without blocking a thread. Interceptors are not bound to a thread, they can release a thread and then resume processing on another one. Have worked hard to keep interceptors compatible with Ring, worked with Ring team to refactor Ring to accommodate both the classical and the interceptor approach. Can still use all Ring middleware and so on. There are leiningen templates with basic routing and interceptor plumbing.

Client side

Imagine creating a word processor as a web app. If you try to do that through event handlers and DOM handling in js, it will get messy really fast. If the possible states of the DOM explodes, you need another way of doing that, you can’t reload the world every now and then by refreshing the page. So if we maintain a separate data structure to maintain state, and javascript to render just the parts of the DOM that have changed. You don’t want to write the code that does all of that though, since the state changes might be big, so Pedestal solves that problem. Comparing the data structures and rendering based on the delta, helped by immutable data structures (?). Data model, app model (a tree) which is a list of deltas, and a renderer that uses that list of changes to change the DOM.

Why giving this away?

Still far from done. Altruism, they like open source. Relevance has a long record of contributing stuff back. Plus, a web framework these days that is not open source doesn’t have much of a chance. You also want input from the people who use it to see if it solves their problems. If they want Pedestal to grow and have a broad user base, it needs to be free. Started work on it around Halloween. Sometimes full-time of 4-5 people, some times only 20 % time (Fridays). They want to use it themselves for client work.

Ring and interceptors

Interceptor is more complex than ordinary Ring model. Don’t want to let ease of use trump flexibility. E.g. Rails has an ambient database, it’s just there. But if you want to use 2 dbs, it is not easy at all. It is a limitation. As an app grows, you want to do more and more complex things, and Pedestal has been made with that in mind. There is capability and flexibility that they feel from experience that they need.

Linking and routing

Route table maps requests onto the interceptor path. More dynamic than Ring. Anyone in the middle of the path can know where the request is going, or change it. Can read meta-data from path and make some decision based on that.

Documentation

Working on it. Chat example demonstrates pretty much all the pieces of both apps and services. App has mock service so you can run stand-alone and work on UI. Services can be worked on without app, just curl.

Debugging

Debugging is easy, you can verify from command line using curl to see if the problem is client-side or server-side. Dev-mode, going back and forth in history. Since the service is sending deltas to the app, you can debug rendering on a delta by delta basis. It is super useful for pinpointing bugs.

CORS

Support for CORS, cross-origin resource sharing (see sample here https://github.com/pedestal/samples/tree/master/cors), which makes it easier having 10 different apps using 20 different services. The coupling between apps and servers become looser.

The name “Pedestal”

Tim has a background in building architecture. A pedestal is near the bottom of classical buildings, something that you base stuff on. A good, solid base to build apps on top of.