A new feature of Mojolicious, as of 7.49, is the implementation of the Promises/A+ specification. In this posting, we're going to use promises to implement non-blocking, parallel fetching of a number of web pages.
Before we get ahead of ourselves, what are roles? Briefly stated, roles enable composing functionality (usually methods) into a class without without implying a change of inheritence. Said another way, roles let you specify what a class does without changing what it is. For a better description, check out Toby Inkster's article Horizontal Reuse: An Alternative to Inheritance.
An important utility of roles is that you can easily use more than one role at the same time in the same consuming class. With inheritance, especially of third-party functionality, you have to choose one set of extensions to utilize. This is because the author of the subclass establishes the inheritance. In roles, the user determines which roles to compose into the base class.
Yesterday I ended the discussion of Mojo::Base before discussing the roles support. Added in several installments between Mojolicious versions 7.40 and 7.55, this role support is one of the most recently added features in the ecosystem (along with promises, which will be covered in an upcoming article). The role handling comes from Role::Tiny which is an optional dependency in Mojolicious, but is required in order to use the functionality that I will describe.
Through this series, you've seen the module Mojo::Base referenced several times, though briefly and mostly in passing. It shouldn't be taken lightly however, it packs a lot of punch in one import statement! Nearly every file in the Mojolicious distribution uses it, either directly or indirectly. So what is it?
First it imports several handy pragma that make your code safer and some features that are useful. Second, it can be a base class to the current package, or establish a parent class, or even define a role. Let's see how it does it.
We have already seen Mojo::UserAgent used to make HTTP requests in this series. In fact we've already seen how you can use Content Generators to build requests in tests. But we didn't look at how they work or how you can add new ones.
Writing an API can be as easy as taking the results of some database query and presenting it to the user. A more advanced one can often present the data in one of multiple formats. The user can then specify which format they want.
JSON is currently the most popular format for new APIs. XML is another common one and was certainly king before JSON hit the scene. An API might choose to make an HTML format of the data available, whether in some representation of the data or to render documentation about the API itself. Of course there are many others.
Mojolicious believes in Content Negotiation, as it is called, and supports it throughout the stack. Mojolicious makes it easy and convenient for users to pick a format they would like. Similarly it makes rendering the different formats easy on the site author, as you would expect.
Continue reading Day 10: Give the Customer What They Want...