When building JSON APIs you often find yourself in a situation when you have part of the JSON already encoded and want to embed it in a bigger structure. A common solution is to decode the encoded part and embed the outer structure just to encode it back again. It’s obvious how that back-and-forth decoding and encoding is wasteful. Fortunately with poison we have a much better alternative.
Poison encoding is based on protocols, this means we can define how a particular
Elixir struct should be encoded - and it doesn’t have to be a structural
encoding - it can be something completely unrelated to the internal
representation. We’re going to leverage that here, by creating a JSONFragment
struct and implementing the Poison.Encoder
for it to return the encoded JSON
“fragment”.
And that’s all. Simple, wasn’t it? That’s the power of protocol-based encoding.
How do we use it? Let’s see couple examples how we could use it in Phoenix. We can use it for a part of response in a Phoenix view:
Or to respond directly in a Phoenix channel:
Or in any other place that’s going to encode our data with poison. One thing you may have noticed, is that I accept a binary or a list instead of a string, and call the value “iodata” - it’s an optimisation for constant-time string concatenation common in Elixir and Erlang libraries. You can read more about it in the excellent article by Nathan Long.