Flavio Poletti

Some time ago one of the rites of passage for a wannabe Perl programmer
was having its own take on a templating system. I duly complied with
Template::Perlish, which I’m quite happy about and I use anywhere
I can. Later, it seems that many people thought they would have a take at
building the next cool web service/application framework; here, I set
quite low expectactions, but it’s still useful!

What is it about?

When building real stuff, quite often I have to interact with some
external API, usually provided as a webservice of some sort. Not always
I have direct access to it (especially from my laptop in some casual
place), or want to hammer the service while doing development. The classic
use case where a mock can be useful.

It’s quite easy to setup such an example application by directly using one
of the available web frameworks. Among them, Mojolicious is probably
best suited for the job, as it has a really low entrance fee for setting
it up (a basic installation takes only two distributions and is usually
very, very quick). If you already have Dancer around, anyway, it’s
also very easy to setup a simple application with it too. So, this is the
perfect scenario for reinventing the wheel and have a personal shot to
the problem.

I’m actually cheating a lot in this, because WebService::Fake uses
Mojolicious behind the scenes. But hey, what did you expect from
something with Fake in its name?!?

So there you go, WebService::Fake is my personal take to having
something that lets you build your webservice (or web application, for
what it’s worth) in some way. I’ve not prove it formally, but it should
let you do almost anything, in some strange and skewed perlish way: easy
things are easy, complicate things are somehow possible but you’d better
do them with something different!

Care to show an example?

Sure! The web service definition is provided via a YAML file, like this:

routes:-path:'/'body:'{"message":"Hello,World!"}'

Suppose it’s saved as hello-world.wsf. You can then start the faker in
a shell (assuming wsf is in PATH):

It’s just slightly more complicated but still quite compact.
Mojolicious provides a few headers shortcuts but you have somehow to
remember them, although you can fallback with the generic header method
for both known and custom ones.

The real difference is actually that Mojolicious provides a complete
(and consistent) set of tools as part of the toolkit, while
WebService::Fake tries to optimize for the case where you somehow
already know the shape of the answer you want to get, and want to
describe it as quickly as possible.

Craft your answer

As a last example for this section, suppose you also want to provide
a different return code, e.g. 203 Non-Authoritative Information. It’s
easy to do this in our definition YAML:

Things get a bit more complicated. To set the custom HTTP status code, we
have to take a different route for rendering the body (I hereby declare my
ignorance with respect to how keep the json => {...} alive, but it’s not
essential), because render is not useful here.

Again, it’s a matter of understanding what shortcuts are most useful in
the general case: in a real application/service, Mojolicious takes
sane defaults, in this whole faking someone else’s webservice context
WebService::Fake goes for a different optimization route.

I’ve only 2 minutes left…

So let’s go fast. If you already have the right answers to the requests
you want to fake, then you should be all set. If you need to add a bit of
logic though…

Using Templates

Body and headers are actually defined in terms of Template::Perlish
templates, so this does what you think:

routes:-path:'/'body:'{"now":"[%=scalarlocaltime%]"}'

Accessing variables

You can spice up your fake answers including a few elements from the
request too, e.g. parameters:

routes:-path:'/'body:'{"name":"[%params.name%]"}'

Placeholders

Did I mention that there’s Mojolicious providing features? You can
define routes with placeholders, and later access them:

As you can see from the last route, you can selectively disable the
wrapper on a per-route basis.

Time’s up!

You have surely noticed that there’s no specific support for security and
the like, there’s no explicit support for sanitizing your inputs, escaping
your output, etc. etc. i.e. all those goodies that help you build
something robust to put into the wild.

So what’s it good for?!? I told you in the beginning… fake web services,
that’s it! It’s meant to be a sparring partner for your programs to
excercise against something that can actually answer them something, not
to put in front of your “customers” (so don’t try to do that!).

We didn’t go too much in depth, and you might find a few additional tricks
if you’re curious enough to take a look at the docs.

It would be great to hear from you! Comment below, or abuse the code and
find bugs, or file suggestions on GitHub but whatever you decide to
make of it… happy faking!