0

With Plug.Parsers, it is possible to configure the module that is used to parse JSON requests:

plug Plug.Parsers,
  parsers: [:json],
  json_decoder: Jason

However, with this syntax Jason.decode!/2 is called with an empty opts parameter.

How can we provide options to the specified json_decoder? For example, I would like to pass the keys: :atoms option to Jason.decode!/2.

Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
  • Please note that dynamically allocating atoms is always a bad thing as they are not garbage collected [https://engineering.klarna.com/monitoring-erlang-atoms-c1d6a741328e](https://engineering.klarna.com/monitoring-erlang-atoms-c1d6a741328e) – Mike Quinlan Aug 08 '19 at 21:45

1 Answers1

5

As well as the module name, it's possible to pass a {Module, :function, args} tuple as the :json_decoder argument. This can be used to customise the arguments to the decoder:

plug Plug.Parsers,
  parsers: [:json],
  json_decoder: {Jason, :decode!, [[keys: :atoms]]},

This will result in the parser calling Jason.decode!(data, keys: :atoms).

The [[]] list-in-a-list syntax is a bit strange, but it's necessary because of the way Plug.Parsers handles merging the options. For the same reason, an alternative way is to provide the empty list in the tuple, and include the option directly as an option to Plug.Parsers:

plug Plug.Parsers,
  parsers: [:json],
  json_decoder: {Jason, :decode!, []},
  keys: :atoms

I prefer the former because the options are better scoped, but the latter could be useful if some parsers share common parameters.

Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
  • 2
    Should also mention that this is risky, because it would be possible to overload the system with atoms if incoming requests are not controlled somehow. – Adam Millerchip Aug 02 '19 at 05:47
  • I also found out that this specific option (keys: :atoms) does not conform to Plug.Conn's [typespec for params](https://hexdocs.pm/plug/Plug.Conn.html#t:params/0), which requires the keys to be binaries, not atoms. – Adam Millerchip Aug 15 '19 at 12:26