-
Notifications
You must be signed in to change notification settings - Fork 26
JSONEncoder cannot encode structs #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It's actually stated in code comments:
|
@Grantovich I, too, had the same realization as you did, and I'm replying with the hopes that perhaps this helps someone else that stumbles upon this useful library but is at a loss momentarily for how to leverage it. I agree with your assessment that encoding, then decoding so that you can perform the casing transformations, and then encoding again is something that you'd like to avoid for every request if you could. Trying to avoid that pattern lead me down this approach, though note I'm using In my structs, I've defined a an implementation of I've only played around with it a bit, but the rough idea is defmodule MyApp.MyStruct do
use Ecto.Schema
import Ecto.Changeset
alias MyApp.Common
defimpl Jason.Encoder, for: [MyApp.MyStruct] do
def encode(struct, opts) do
map =
struct
|> Map.take([:key_1, :key_2])
|> Common.map_from_struct()
|> ProperCase.to_camel_case()
Jason.Encode.map(map, opts)
end
end
schema "my_structs" do
field :key_1, :integer
field :key_2, :integer
timestamps()
end
end The call to Though you have to write a bit more code, you have as much control as you want over the encoding behavior, and can perform the casing transformations without having to write your own library to do it. |
Oops, I think I should have closed this a while ago, as we realized the way we were doing JSON rendering did not (did no longer?) align with Phoenix best practices. Specifically, I asserted that
...was a "typical case", which I'm not sure is accurate. The current Phoenix guides, at least, recommend using view modules in a way that results in plain maps being passed to the encoder, which of course works fine with the I'll close this now since, for me, it is not an issue. If anyone is in a situation that prevents using view modules for whatever reason, the workarounds documented above should help. |
In the typical case where data being encoded from Phoenix is a struct (using
@derive Poison.Encoder
or similar),ProperCase.JSONEncoder.CamelCase
does nothing. This doesn't seem well-documented in the README, and makes this encoder not particularly useful out of the box, although it does make sense: the struct-ness cannot be preserved if the keys are changed, but it must be preserved in order to be encoded as desired by Poison/Jason/etc.To work around this, we're using a custom format encoder that encodes the struct, decodes it back into a map (now with filtered/stringified keys), runs that through
ProperCase
, and re-encodes it. This would probably be inefficient for large JSON responses, but it's acceptable for our application.I'm not sure off-hand how this issue could be addressed within
ProperCase
— there is nowhere in e.g. Poison to insert a "key transform" (although see devinus/poison#44). I think this library could at least be explicit in the README thatJSONEncoder.CamelCase
only works in the unusual case where the data being encoded is plain maps all the way down, with no structs.The text was updated successfully, but these errors were encountered: