[Pharo-users] Understanding ZnJSONReader mapping?

Tim Mackinnon tim at testit.works
Thu Jun 7 16:58:20 EDT 2018

Hey thanks - so maybe there are more legs to this - although it’s the decoding I’m currently interested in (but I’m sure encoding will come up at some point on my journey).

So it seems that my mapper can have multiple entries (that bit I had missed - although seems obvious in retrospect now).

But then you have have to say #nextAs: and this is what I don’t get for anything more complicated - how do I choose as it could be any one of the patterns I want to map?

Sadly it’s not my scheme - it’s a prismic.io one so I’m trying to follow what the equivalent python/js/csharp libs do - but they are horrid, filled with tons on instanceof crap...

I’ve gotten reasonably far but as the structures can be recursive for a cms, I think I can do much better somehow.


Sent from my iPhone

> On 7 Jun 2018, at 21:44, Esteban A. Maringolo <emaringolo at gmail.com> wrote:
>> On 07/06/2018 17:21, Tim Mackinnon wrote:
>> Hi - is there something I can read/study to get a bit more familiar with Json mapping? I have read the Pharo enterprise book (chapter 8).
>> I’ve been using NeoJSONObject but then it occurred to me that maybe I could map better domain objects directly and simplify things. However it seems that the intent of mapping is just for simple things like an array of points - whereas if I have 15 different domain objects (albeit with a type key), then I’m wondering if I should just wrap json nodes on usage? 
>> In fact I’m wondering what the point of mapping is if it’s so simple - or maybe I’m missing an important concept?
> If your objects just hold data, then you can get very far with
> NeoJSONObject, but if you want to do more, you can get pretty extensible
> mappings with the use of the valueSchema: option in the mapper.
> For instance, to write a TsOrder (a model of an purchase order) I
> configured the mapper this way:
> mapper for: TsOrder do: [ :mapping |
>  mapping mapAccessors: #(id).
> (mapping mapAccessor: #date) valueSchema: Date.
> (mapping mapAccessor: #edd) valueSchema: #NamedModel.
> (mapping mapAccessor: #provider) valueSchema: #NamedModel.
> (mapping mapAccessor: #status) valueSchema: #NamedModel.
> (mapping mapAccessor: #customerCode).
> (mapping mapAccessor: #totalOriginalPrice to: 'total') valueSchema:
> #monetary.
> ].
> mapper for: Date customDo: [ :mapping |
>    mapping encoder: [ :date | date ddmmyyyy  ] ].
> mapper for: #monetary customDo: [ :mapping |
>    mapping encoder: [ :price | price printShowingDecimalPlaces: 2 ] ].
> mapper for: DateAndTime customDo: [ :mapping |
>    mapping decoder: [ :string | DateAndTime fromString: string ].
> ].
> mapper for: #NamedModel customDo: [ :mapping |
>    mapping encoder: [ :persona | persona displayString ] ].
> For decoding it might be trickier, because you might need more objects
> other than just deserializing from JSON, e.g. to avoid instantiating
> twice the same domain object, or if you need to lookup an entity in the
> database by ID, and then you need access to the database, etc.
> Throughout my journey of developing a few JSON-REST APIs I started using
> the NeoJSON approach, then JsonObject and then WAJsonCanvas.
> I found myself more confortable writing JSON with the latter (I like the
> canvas approach of Seaside) and instantiating NeoJSONObject/JsonObject
> and building my business objects from these cherry picking what I needed.
> What NeoJSON offers as a "differentiator" is that it is stream based, so
> there is no need to have intermediate "structures" (it is,
> dictionaries), and the mappers are orthogonal to the objects (unless you
> use the default class side #neoJsonMapping:)
> WAJsonCanvas offers stream based writing, but there are no mappings, but
> if you always serialize a proper hierarchy of renderJsonOn: implementors
> could prove to be effective, in particular if you have to build your
> objects manually from a JSON stream.
> Regards,
> -- 
> Esteban A. Maringolo

More information about the Pharo-users mailing list