Mojolicious: Do It For The Candy!
In this article I will show you some of those extras, like accessing your generated pages and even app itself direcly from the command line. I will also show how testing can be easy, powerful, expressive and yet still readably beautiful.
Revisiting the WebSocket Example
A while back I demonstrated a simple Mojolicious WebSocket app. This app simply:
- renders a page with the current state of a database table
- takes input from a form
- sends the data as JSON over a WebSocket
- inserts the data into the database table
- renders a new HTML row and sends it to the client for insertion in the HTML table
I am going to use this app for two reasons, first it will demonstrate the candy I want to show off and second it gives me a chance to brush the app up for recent (and even not so recent) Mojolicious updates. So lets take a look:
The app only requires Mojolicious and a few DBI modules to run it, so with cpanm run
cpanm Mojolicious DBI DBD::SQLite DBIx::Connector
And then to run the app (called
perl websocket.pl daemon
From there you can open a browser to either
127.0.0.1:3000 to use the app yourself.
Improvements to the App
Since you last saw this app, I have tweaked just a few things:
- It uses the JSON-over-websocket architecture that Mojolicious now provides
- It uses DBIx::Connector to maintain the DB connection
- It uses the new
render_to_stringmethod rather than the now-removed
Command Line Candy: The get Command
Of course when you are developing your application, you often run some simple tests by hand as you go. To do so you find yourself switching between your editor and your browser, refreshing and scrolling to find out if your change worked.
Mojolicious provides you with another option. From a command line, just as you would start your application, you can instead use Mojo::UserAgent to get a page straight from your app itself. For example you can run
perl websocket.pl get /
to see what your landing page HTML looks like.
You can then use Mojo::DOM to inspect, say, the
head tag to make sure it looks ok,
perl websocket.pl get / head
After you use the app to add a few records, you might want to see the state of the table
perl websocket.pl get / '#table'
or even examine a certain row (say, the second one)
perl websocket.pl get / '#table tr' 1
Command Line Candy: The eval Command
get command is great for inspecting the output of your app.
Sometimes, though, you really want deeper access to your app.
For example, if you want to see the current state of the database, you can of course drop to the db shell to do the query yourself, but is that the way the app sees the data? How often do people forget to update hand-rolled administration scripts when schemas change or servers get moved? What happens when someone tries to insert data by hand and forgets that new piece of necessary info?
eval command will startup a local instance of the app, much like the
get command does, but then rather than getting a page, it lets you run a command or even series of commands against the running app.
This is really useful for interacting with the app in the same way that it would behave on its own.
In the example app, I can see what data the
select helper returns, just by running
perl -MData::Dumper websocket.pl eval 'print Dumper app->select'
Then again, since you often want to print output or even dumped structures, we have shortcuts for that too.
-v to print the last statement result or
-V to dump that same result via
In that way the previous example can be
perl websocket.pl eval -V 'app->select'
Eval can be handy for initialization too. The app does have a line that will self-initialize, but you could manually initialize the database by doing
perl websocket.pl eval 'app->create_table'
And then maybe inject some data
perl websocket.pl eval 'app->insert( Joel => 30 )'
Or clear it out again
perl websocket.pl eval 'app->empty_table'
Beyond just the convenience of these commands, you actually know that it is using the same mechanisms that your app actually uses, not just the way that you remember your schema/configuration/workflow from the last time you looked at it.
And if it turns out that you really like the
eval command and find yourself administering your app with it, you can even codify those into your own commands.
As an example, I provide a setup command for my Mojolicious-based Galileo CMS.
Testing Candy Too
The other piece of candy that has attracted the eyes of onlookers at my recent events is the wonderful testing provided by Test::Mojo library.
Just like the
get command, testing with Test::Mojo is done by instantiating the app and then making requests of that app via Mojo::UserAgent.
Also like the
get command, returned responses can be inspected using CSS selectors, this time wrapped into Test::More-friendly chainable methods.
When testing apps that use WebSockets, Test::Mojo comes through for you too! It can send and receive WebSocket messages so you aren’t tied to using browser-driven testing for the interaction with the WebSocket.
Check out how wonderfully readable the tests for our example app can be!
Do it for the Candy!
So if Mojolicious’ non-blocking capabilities are more power than you need, or you just aren’t interested in them, you just might want to use it for the other nice features that come along for free!
Then again, if non-blocking does appeal to you, you might want to see the fully non-blocking websocket-capable Golf Scoreboard App I recently put together for a company outing. It was built off the base code from the example app above, and it shows off some of the non-blocking candy too :-)