Liberator encourages a declarative programming style: the developer is
hidden from the algorithm and only provides callbacks at certain
decision points. This enables a compact and powerful style of
programming but, in case of an unexpected result, can make debugging a
pain: there is no step through.
So show me the traces!
Although the developer cannot step through the sequence of decisions,
liberator can be told to trace the execution and report to the
developer. The namespace liberator.dev contains helper
functions for this.
Let’s take this example resource and trace it:
To enable request tracing wrap the request handler in
liberator.dev/wrap-trace. You can wrap either a single
resource or any ring middleware stack. The later is recommended to
make the trace ui easily accessible:
The response will include a complete trace of the sequence of
decisions together with the individual outcome:
You can see that the media-type was negotiated and the decision
function returned a map with the representation definition. This map
was combined with the context at that time and makes the media-type
available for the handler.
Also visible is that the part for conditional request was skipped. Try
playing around with resources that use ETags (see Conditional Requests)
and different methods and look how the request was processed. This will
give you a good understanding of how to implement a more sophisticated resource.
Trace UI
When you payed attention you’ve noticed that we provided two additional
keyword arguments to wrap-trace: :header and :ui. The
first let’s liberator include the trace as response headers which is
nice in the console. Sometimes this is not enough or response
headers are not easily available. Liberator provides a web resource at
http://localhost:3000/x-liberator/requests/ (the trailing slash
is required) where a list of recent requests can be found. The trace
for a single request can be selected there.
For the trace-ui to be accessible it is
mandatory that the wrapped handler is invoked for trace ui resource.
The simplest way to make this is to add wrap-trace to the stack of
ring middleware outside the routing. This is how it's done in the
above example.
The trace ui shows for a single request the request including
parameters and headers, the trace of decisions and the decision graph.
It highlights the path that was taken for the request. The edges are
colored depending on the boolean value of the decision.