JSON to struct with upper-case field-names

Thanks to the previous help this works:

require "json"

struct Person
  include JSON::Serializable

  getter name : String
  getter email : String
end

json_str = %{{"name": "Bar", "email": "bar@foobar.com"}}
prs = Person.from_json(json_str)
p! prs
p! prs.name
p! prs.email

but I don’t know what to do when a field (e.g. Email) in the JSON starts with upper-case:

require "json"

struct Person
  include JSON::Serializable

  getter name : String
  getter Email : String
end

json_str = %{{"name": "Bar", "Email": "bar@foobar.com"}}
prs = Person.from_json(json_str)
p! prs
p! prs.name
p! prs.email
In struct_from_json_upper.cr:7:16

 7 | getter Email : String
                  ^
Error: unexpected token: :

Oh, I found it:

require "json"

struct Person
  include JSON::Serializable


  getter name : String

  @[JSON::Field(key: "Email")]
  getter email : String
end

json_str = %{{"name": "Bar", "Email": "bar@foobar.com"}}
prs = Person.from_json(json_str)
p! prs
p! prs.name
p! prs.email
1 Like

https://crystal-lang.org/api/master/JSON/Serializable.html#usage

@[JSON::Field(key: "Email")]
getter email : String

The downside is that this affects both (de)serialization contexts, so there isn’t currently a way to deserialize {"Email":"foo"}, but serialize {"email":"foo"}. However this would be resolved via Support for key transform in `JSON::Serializable::Options` · Issue #10793 · crystal-lang/crystal · GitHub.

EDIT It’s possible at the moment, but not really straight forward.

3 Likes