[UPDATE: Notes on Part 2]

I’ve been working through the excellent Pedestal tutorial and I am genuinely excited about Pedestal.

So excited about @pedestal_team – the last time I was this excited about a new technology was Ruby on Rails in 2005. Giddy! — Peter Christensen (@christensenp) January 18, 2014

lol @pedestal_team event delta playback is bi-directional, like database migrations in Rails. So awesome it’s silly — Peter Christensen (@christensenp) January 18, 2014

It’s such a simple, Clojure-y approach to single-page web apps. I expect it to face slow and limited adoption because it’s a very different and strongly opinionated approach with a steep learning curve. It’s not possible to sip Pedestal, you have to swallow it whole. But whether or not you use it for any projects, it’s worth working through to experience its design principles. (Kind of like Lisp.)

Some of the key principles:

The application is split into data, application model (the structure of how the data will be rendered), and the rendering.

No callbacks – every function does some simple work and puts a message on a queue.

Server and client code should be separate, and indeed are in different projects.

Apps should handle 2-way data from multiple sources.

There are a few minor changes from Pedestal 0.1 to 0.2, and this affects the tutorial. They’re mostly called out in the wiki but here’s another heads up:

Configuration changed from config/config.clj (referred in text and present in the code repo) to config/config.edn. I think the file contents are the same, as EDN is a subset of Clojure.

When running a repl for a v0.2 app, you do not need to run (use ‘dev)

The test files started in a separate directory (tutorial-client/test/tutorial_client/test/behavior.clj) in v0.1 but moved to the same directory as code files and using a naming convention in v0.2 (tutorial-client/test/tutorial_client/behavior_test.clj)

Here are my notes on the 15 sections of Part 1. Next up, Part 2!

Getting Started Separate projects for client and server (?) lein new pedestal – app [project-name] lein repl (start) Index page has links http://localhost:3000/ Dev homepage has hidden nav links in bottom-right http://localhost:3000/tutorial-client-dev.html Pedestal projects product a set of deployable front-end files for single-page apps. Not a back-end

Making a Counter How to trigger changes in a pedestal-app application: A pedestal-app application is essentially one big object. It contains state, and that state is changed when it receives a message. Messages are data. At a minimum, each message has a type and a topic. the message’s type is a dispatch value often used to determine which state transition function should be called the topic determines the location in the data model where the function will be applied (may also be used for dispatch) The code for behavior is located in tutorial-client/app/src/tutorial_client/behavior.clj (this project layout is not required – Pedestal-app projects do not enforce a specific source code layout) Path matching One element: [:inc [:*] inc-transform] Any path: [:inc [:**] inc-transform]

Incrementing the Counter Each emitter vector has two elements: a set of inputs and an emitter function. [ # {[:*]} ( app/default-emitter [])] The vector passed to default-emitter is a prefix which will be added to all emitted deltas. The emitted deltas can be seen in the JavaScript console. The Data UI receives these changes and draws them for you as a nested tree. :transform-enable format: [:transform-enable [:main :my-counter] :inc [{msg/topic [:my-counter]}]] Transforms are part of the application model but not the data model Why use transforms? :transform-enable provide an abstraction for messages Tests can be written that discover which actions may be performed by responding to :transform-enable deltas. having a standard way to describe messages allows for renderers to be created which can automatically render user interfaces during development , generate administrator user interfaces and leverage lots of standard library functions for wiring up events.

Simulating Service Push Lets you continue work on the client side of the application and delay work on the service until it is actually required The io.pedestal.app.util.platform namespace contains functions which require platform-specific implementations The app starts the [project-name].simulated.start (configured in config/config.edn if you generate the project, or config.clj if you follow their repo), and that main function is what starts the app in [project].start. The simulated services start in the same method.

