Simple Front-End Development
with Pedestal
Chad Taylor, @tessellator
Slide 2
Slide 2 text
What is Pedestal?
(http://pedestal.io)
Slide 3
Slide 3 text
A collection of libraries for web development in
Clojure and ClojureScript
A collection of tools to help ease the development
by keeping concerns separated
Slide 4
Slide 4 text
Two pieces:
pedestal-service & pedestal-app
(inc ring) front-end framework
Slide 5
Slide 5 text
Today, we discuss pedestal-app
Slide 6
Slide 6 text
pedestal-app tutorial is...
available at https://github.com/pedestal/app-tutorial/
dense
complete
sometimes hard-to-follow due to the number of concepts
presented
Slide 7
Slide 7 text
My goals are two-fold:
Prepare you for the tutorial if you haven’t tried it
Clarify some of the fuzzier details if you have
Slide 8
Slide 8 text
How is Pedestal different from X.js?
Slide 9
Slide 9 text
These are mostly view-concerned.
Pedestal provides more infrastructure for building
large applications, supporting separation of
concerns throughout the development cycle.
Pedestal decouples the concept of rendering from
the DOM and even decouples event registration.
Slide 10
Slide 10 text
This results in more flexibility - ranging from
automatic rendering to building tools that record
and playback application events.
Since the application model is decoupled from the
DOM, the application is also more testable.
Slide 11
Slide 11 text
These break an application down into the familiar MVC model.
Mutation is handled locally within services and controllers.
Complexity begins to ramp when dealing with dynamic data (e.g.,
from web sockets).
Pedestal breaks the problem down differently. It constrains
mutation to be localized within the Pedestal library and keeps
complexity low, even with highly interactive applications.
Slide 12
Slide 12 text
Another way to say this is that X.js makes
development easy, while Pedestal makes it simple.
Complexity with X.js can ramp quickly - especially
when building highly interactive applications.
Complexity with Pedestal stays relatively flat.
Slide 13
Slide 13 text
Just remember:
Simple ain’t easy.
Slide 14
Slide 14 text
(Whew.)
Slide 15
Slide 15 text
Okay, I’m convinced. Now what?
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
That’s it!
Slide 18
Slide 18 text
Whelp...my job here is done.
Slide 19
Slide 19 text
Okay, okay. I kid.
Slide 20
Slide 20 text
Before we get started,
a quick Clojure syntax tutorial:
Collects messages to be processed by
the application
Slide 25
Slide 25 text
Messages can theoretically come from anywhere,
such as an AJAX call resolving or an event in the
UI occurring
Slide 26
Slide 26 text
Messages are just data
Slide 27
Slide 27 text
Messages have a type and a topic
type - The type of the message
topic - The data with which the message is concerned
path in data model
Slide 28
Slide 28 text
No content
Slide 29
Slide 29 text
root node
:my
:counter
Slide 30
Slide 30 text
Messages can also have additional data elements.
Add whatever you need - it’s just data!
Slide 31
Slide 31 text
When a message is being handled, we want to
transform the data element in the data model
based on the message.
To do this, we write a pure function and let
Pedestal handle the data model mutation for us.
Slide 32
Slide 32 text
No content
Slide 33
Slide 33 text
current value in data model
the transform logic
protect against nil
behavior.clj
A Transform Function
the message from the
input queue
Slide 34
Slide 34 text
First Run
Slide 35
Slide 35 text
Second Run
Slide 36
Slide 36 text
I don’t actually care about the message!
indicates “don’t care”
HINT
Slide 37
Slide 37 text
But...how do I tie the message to use that
transform?
You configure the application Dataflow
Slide 38
Slide 38 text
Dataflow is...
described implicitly in the tutorial
the app wiring, connecting functions & data
sometimes used as a proper noun, sometimes not
(I will strive to use it as a proper noun)
defined with a map
Slide 39
Slide 39 text
I think of the Dataflow as the arrows...
HINT
Slide 40
Slide 40 text
Dataflow definition
Since the definitions are in a vector, order matters.
A message is handled by the first matching transform.
behavior.clj
Slide 41
Slide 41 text
the message type to
match against
the topic
the transform function
Slide 42
Slide 42 text
No content
Slide 43
Slide 43 text
No content
Slide 44
Slide 44 text
No content
Slide 45
Slide 45 text
That was a lot of work. Let’s see our progress!
Slide 46
Slide 46 text
...but I {{ mustache }}, what about templates?
No worries, we don’t need any right now.
Why the HTML not?!
Pedestal provides some pretty cool tools that help
keep application logic and rendering separated.
Slide 47
Slide 47 text
To show the aspects, move the cursor to the page’s lower-right.
http://localhost:3000
Slide 48
Slide 48 text
No content
Slide 49
Slide 49 text
Cool tooling, bro.
Slide 50
Slide 50 text
Hmm, I’m not sure what happened there...
Slide 51
Slide 51 text
Wait, I’ve got it!
If the input queue started out empty,
then the data model must be empty!
Slide 52
Slide 52 text
Let’s add a message to the queue during
application startup...
Slide 53
Slide 53 text
start.cljs
the input queue
the message to enqueue
Slide 54
Slide 54 text
No content
Slide 55
Slide 55 text
Okay, so we’ve set up a data model. Now what?
Slide 56
Slide 56 text
Well, now we need to define an application model.
• distinct model for rendering concerns
• derived from data model
Slide 57
Slide 57 text
The application model is defined by emitted deltas
generated from functions that observe changes
to the data model.
The deltas are passed to the renderer.
Slide 58
Slide 58 text
No content
Slide 59
Slide 59 text
Most of the time, this is just a pass-through.
Pedestal provides a default emitter for this case.
Slide 60
Slide 60 text
Dataflow Emitter Configuration
behavior.clj
Slide 61
Slide 61 text
a set of paths in the data
model to watch for changes
a function to generate application model
deltas from the data model changes
Slide 62
Slide 62 text
a higher-order function that
creates an emitter function
a prefix to attach to changed nodes
(e.g., [:my :counter] in the data model becomes
[:main :my :counter] in the application model)
Slide 63
Slide 63 text
HINT
The term Data UI is somewhat misleading.
It renders the application model, not the data
model.
It took me awhile to pick up on this little detail...
Now, an aside:
Slide 64
Slide 64 text
No content
Slide 65
Slide 65 text
If you look at your browser’s developer tools, you
can see the rendering deltas in the console.
Slide 66
Slide 66 text
Can you guess what each step is doing?
Slide 67
Slide 67 text
No content
Slide 68
Slide 68 text
Okay, this is cool and all, but I’m bored.
When can make it do something?
Slide 69
Slide 69 text
To do this, we need to tell the renderer that it can
initiate a transform to the application model by
sending messages to the input queue.
We achieve this by sending a delta to the renderer
informing it about the transform.
Slide 70
Slide 70 text
behavior.clj
Slide 71
Slide 71 text
No content
Slide 72
Slide 72 text
indicates that the delta should be
sent at application startup
the function that will provide the deltas
Slide 73
Slide 73 text
(Technically, the deltas will be sent when Focus
changes, but that’s a topic for later...)
Slide 74
Slide 74 text
Meanwhile, in the Data UI renderer...
Slide 75
Slide 75 text
this is what causes the button
to appear in the Data UI
Slide 76
Slide 76 text
It’s a button...Push it!
What’s the worst that could happen?
Slide 77
Slide 77 text
No content
Slide 78
Slide 78 text
No content
Slide 79
Slide 79 text
Now we’re getting somewhere!
Now, if only we could make it so that my
designer won’t puke when she sees it...
Slide 80
Slide 80 text
tutorial-client.html
Okay, let’s start with some HTML:
Slide 81
Slide 81 text
Now, let’s look at the design without the app
Slide 82
Slide 82 text
Click “Design” to view the template
Slide 83
Slide 83 text
http://localhost:3000/design.html
Slide 84
Slide 84 text
http://localhost:3000/design/tutorial-client.html
Slide 85
Slide 85 text
Okay, so the markup appears fine...but how can I
make sure that everything is wired up correctly?
Slide 86
Slide 86 text
Well, let’s record the application model deltas and
play them back to a renderer.
Slide 87
Slide 87 text
In the Data UI, press Alt-Shift-R. (Yes, even on OS X.)
Press the button a few times, then press Alt-Shift-R again.
When prompted, provide a :keyword and a description of what you
did during the recording session.
Slide 88
Slide 88 text
This creates a file with all the deltas saved into it.
The deltas can be replayed later.
Slide 89
Slide 89 text
Now go to the “Render” aspect.
runs all deltas
immediately
runs one transaction
at a time
(press -> to advance)
runs one delta at a time
(use <- and -> to update)
Slide 90
Slide 90 text
How in the world is this useful?
Slide 91
Slide 91 text
Let me start by showing you the generated file:
Slide 92
Slide 92 text
No content
Slide 93
Slide 93 text
It’s just data!
Slide 94
Slide 94 text
Now, imagine a really hard-to-duplicate sequence
of events that you want to ensure are rendered
properly.
This tool lets you write that sequence, and then
step through it!
Slide 95
Slide 95 text
No more wasting time attempting to generate
the situation in the browser.
No more succumbing to non-repeatability.
No more crying yourself to sleep while wondering
how to duplicate that bug deep down in the dark
asynchronous abyss in your project.
Slide 96
Slide 96 text
No content
Slide 97
Slide 97 text
(I am skipping Template Slicing here to save time.
Check it out in the tutorial!)
Slide 98
Slide 98 text
Configuring the renderer
rendering.cljs
Slide 99
Slide 99 text
the delta operation
to handle
the application model path
to watch
the handling function
Slide 100
Slide 100 text
(This pattern should be feeling familiar now.)
Slide 101
Slide 101 text
Send the messages from the previously
defined :transform-enable to be sent to the input
queue when “#inc-button” is clicked.
Slide 102
Slide 102 text
Now we’re nearing the end of the presentation.
What have we covered?
Slide 103
Slide 103 text
No content
Slide 104
Slide 104 text
So...Pedestal is a big subject.
...and I ramble.
Slide 105
Slide 105 text
Please check out the tutorial. It is super awesome.
But keep this presentation handy, too!
It will help with some of the tricky bits.
Slide 106
Slide 106 text
Special thanks to Eric Pritchett
for guiding me through some edge cases...