Mojo Wonk Blog.

A semi-offical blog dedicated to the Mojolicious web framework

Mojolicious and DBIx::Class

Mojolicious (heart) database on a pink background. Original artwork by Doug Bell

Mojolicious is an MVC framework. But, unlike Catalyst, Mojolicious does not provide a model API. This is a good thing: Mojolicious works well with any model layer, including the existing models used by your current application.

DBIx::Class is a popular model layer for Mojolicious applications. DBIx::Class (or "DBIC") is an Object-Relational Mapper (ORM) to map objects onto a relational database. This allows for a well-organized model layer, and a standard API to access the data.

For those who read last month's posts on Writing Reusable Controllers and Writing Extensible Controllers, this post introduces the end result of those posts: The Mojolicious DBIC Plugin. This plugin makes it easier to start using DBIx::Class with Mojolicious.

Continue reading Mojolicious and DBIx::Class...

Writing Extensible Controllers

Clouds stacked inside clouds, mixed with gears. Original artwork by Doug Bell

Once I have a reusable controller, how do I extend it? Object-oriented programming gives me a couple ways of extending a controller through code: Inheritance and composition. But, we need to write our controller so that it's easy to inherit or compose.

Don't Render, Stash

First, this means we shouldn't call the render method ourselves (unless we have a good reason, but we'll get to that later). The render method can only ever be called once, so we should only call it after we've gathered all the data we want.

# This method cannot easily be used by a subclass, since it explicitly
# calls render()
sub list {
    my ( $c ) = @_;
    my $resultset_class = $c->stash( 'resultset' );
    my $resultset = $c->schema->resultset( $resultset_class );
    $c->render(
        resultset => $resultset,
    );
}

So, to make sure I don't call render too early, and to make sure subclasses can use the data from my superclass, I instead put all the data directly in to the stash with the stash() method.

Continue reading Writing Extensible Controllers...

Writing Reusable Controllers

Clouds with user icons raining gears

In all the web applications I've written with Mojolicious, one of the most mis-used features are controllers. Mojolicious is a Model-View-Controller framework, and the MVC pattern is intended to provide for code re-use.

Models can be interchangeable and used by the same controllers and templates. With a common, consistent model API, the right controller can list any data, update any data. If all of our models have a method named "search", I can make a single controller method that will run a search on any of them.

The easiest way to demonstrate this is with DBIx::Class. DBIx::Class provides a consistent API for a relational database.

The Problem

For this example, I'll use this DBIx::Class schema. My schema has a couple tables: notes for storing simple notes, and events for storing calendar events.

Continue reading Writing Reusable Controllers...

Day 12: Using Minion in Dancer Apps

Stylistic photograph of Disney-style minion toys

At $work, we have built an API with Dancer that generates PDF documents and XML files. This API is a critical component of an insurance enrollment system: PDFs are generated to deliver to the client in a web browser immediately, and the XML is delivered to the carrier as soon as it becomes available. Since the XML often takes a significant amount of time to generate, the job is generated in the background so as not to tie up the application server for an extended amount of time. When this was done, a homegrown process management system was developed, and works by fork()ing a process, tracking its pid, and hoping we can later successfully reap the completed process.

There have been several problems with this approach: - it's fragile - it doesn't scale - it's too easy to screw something up as a developer

In 2019, we have to ramp up to take on a significantly larger workload. The current solution simply will not handle the amount of work we anticipate needing to handle. Enter Minion.

Note: The techniques used in this article work equally well with Dancer or Dancer2.

Continue reading Day 12: Using Minion in Dancer Apps...

Day 7: MetaCPAN, Mojolicious and OpenAPI

Contract signing

During this years meta::hack 3, I was extremely fortunate to work with Joel Berger on integrating/documenting OpenAPI with the MetaCPAN API via Mojolicious.

What is it?

OpenAPI is a specification for designing, documenting, validating and driving your RESTful API. It can be used to provide documentation to an existing API, or when creating a new one.

The OpenAPI Specification originated as the Swagger specification and was renamed to separate the API description format (OpenAPI) from the open source tooling (Swagger). The specification moved into a new GitHub repository, but did not change.

In the case of the MetaCPAN API, we set out to provide documentation to the existing API, but quickly moved into supporting validation to API calls as well.

Continue reading Day 7: MetaCPAN, Mojolicious and OpenAPI...