/ Perl

How to create Mojolicious template code for RESTful GET, POST, PUT, and DELETE requests

I am aware of many weak places in the BibSpace code. Not that they cause errors, (although they may of course[1]), but they could have been done better. Being a good programmer is a challenge because it is a goal that can never be reached. You should develop your skills continuously.

The routing is one of the aspects that could have done been better in the BibSpace code. Most of the people follow the RESTful best practices to design routing. This applies also to non-API applications (which yet may be turned into API applications).

BibSpace is my playground for all such novelties. Some time ago, I restfullized a part of BibSpace routes. The relevant part of the Mojolicious routes looks as follows

$r->get('/backups')->to('backup#index')->name('backup_index');
$r->put('/backups')->to('backup#save')->name('backup_do');
$r->get('/backups/:id')->to('backup#backup_download')->name('backup_download');
$r->delete('/backups/:id')->to('backup#delete_backup')->name('backup_delete');
$r->put('/backups/:id')->to('backup#restore_backup')->name('backup_restore');
$r->delete('/backups')->to('backup#cleanup')->name('backup_cleanup');

Looks great, only two urls /backups and backups/:id but how to easily create buttons for these actions in Mojolicious templates?

GET

Easy peasy, posted everywhere in the Internet. I show it with some Bootstrap elements.

<a class="btn btn-default btn-sm" href="<%= url_for('backup_download', id=>$id)%>">

POST

Also easy because very widely used. Not included in the example above.

<form class="form-inline" role="form" method="POST" action="<%= url_for('edit_backup_dummy', id=>$id) %>">
<button type="submit" class="btn btn-warning">Do it</button>
</form>

or better using template tag helpers.

%= form_for 'edit_backup_dummy' => {id => $id} => (role=>'form' class=>'form-inline') => begin
<button type="submit" class="btn btn-warning">Do it</button>
% end

The submit button could be also implemented using template tag helpers. The form would look like this:

%= form_for 'edit_backup_dummy' => {id => $id} => (role=>'form' class=>'form-inline') => begin
%= submit_button 'Do it', class => 'btn btn-warning'
% end

PUT

Not so popular as not all users follow RESTful guidelines. But maybe with this snippet some will start.

%= form_for 'backup_restore' => {id => $id} => (class=>'display-inline') => begin
<button type="submit" class="btn btn-warning">
    Yes, restore <span class="glyphicon glyphicon-import"></span>
</button>
% end

But wait, this is identical to POST! Yes, but only if you use the form_for tag helper. Spoiler: it is also identical to a form that handles DELETE requests. Without the tag helper, the code would look worse. An example for PUT:

<form action="/backups/<%=$id%>?_method=PUT" class="display-inline" method="POST">
  <button type="submit" class="btn btn-warning">
    Yes, restore <span class="glyphicon glyphicon-import"></span>
  </button>
</form>

Pretty ugly, isn't it? For the sake of completeness, I present the same code for DELETE.

DELETE

Using tag helpers

%= form_for 'backup_delete' => {id => $id} => (class=>'display-inline') => begin
<button type="submit" class="btn btn-warning">
  Delete <span class="glyphicon glyphicon-flash"></span>
</button>
% end

and without

<form action="/backups/<%=$id%>?_method=DELETE" class="display-inline" method="POST">
<button type="submit" class="btn btn-warning">
  Delete <span class="glyphicon glyphicon-flash"></span>
</button>
</form>

Conclusion

Shortly speaking, use tag helpers if they refer to variable parts of your application, for example, routes. The routes may change and these changes will affect your templates. Using tag helpers you delegate this work to Mojolicious.

When do not use the tag helpers? In my opinion, the static parts do not need the tag helpers. Example of an optional tag helper:

...
%= submit_button 'Do it', class => 'btn btn-warning'
...

This code is fragile to changes in Mojolicious, but is not to changes in your code. I leave the decision for you whether to use tag helpers in the static parts of your template.


  1. At the time of writing, the code coverage for BibSpace is still as low as 30%. Code coverage improvement is high priority. Update (Jun 2016): Code coverage has doubled and is now 60%. Still working to improve. ↩︎

Piotr

Piotr

IT specialist with 7 years of experience in research at four European universities and in private sector. I believe that good quality is always worth to invest few € and some free time.

Read More