The text/plain codec should stringify maps
Cantido opened this issue · 0 comments
Is your feature request related to a problem? Please describe.
This kind of a cross between a feature and a bug. The functions later in the evaluation pipeline assume that the handlers return some sort of data structure that is then serialized. For example, handle_ok/1
should return a map, that will then be converted into a JSON string if the accepts
header is application/json
. If you do the same thing while the accept
header is text/plain
, the request crashes. Specifically, the compression step crashes, because the argument is not a binary.
Describe the solution you'd like
Stringify maps in a pretty-printed format. If you returned a map
%{a: "value a", b: %{nested: "nested value b"}`
Then the text/plain codec should return
a: value a
b:
nested: nested value b
This almost seems like a YAML format, which TBH would be pretty nice. I might consider that.
Describe alternatives you've considered
Just calling Kernel.inspect/1
on the result. That would be ugly but it would get the job done.
Additional context
While we're in there, we should also make sure that the value returned from the media codec is a binary, so that we don't pass invalid data to the compression codecs.
For anyone who would want to help me with this change request, Liberator.MediaType.TextPlainCodec
is where you'll want to be working. Make encode!/1
always return a string, or raise if there's an error.
To implement the check for a binary, add something at line 190 in Liberator.Evaluator that just checks if the return value from the codec is a binary, then throw an exception with a nice error message, and point to the module that failed.
Liberator.Codec also needs to be split into a MediaTypeCodec
which is typespecced for any -> binary
, then an EncodingCodec
which is typespecced for binary -> binary
.