Re: [Pharo-users] Understanding ZnJSONReader mapping?

2018-06-07 Thread Tim Mackinnon
Its sort of an awkward format, so maybe mapping is just not the way to go (but 
I’m still keen to learn how to properly use it when it is appropriate). For the 
record (if anyone is interested), an example json sample is here 
(https://sprintdemo.prismic.io/api/v1/documents/search?q=%5B%5Bat(document.tags,%20%5B%22demo%22%5D)%5D%5D=WxmMWCQAAFGEIbhe#format=json
 
).

It ends up giving you something like below (the names like heading, 
effectivefrom are names you define in your Prismic page type, but their values 
are then a standard format (almost) - so maybe those I can usefully map?

Or maybe I just stick to dictionaries and plough on.

Tim

page: {
--heading: {
type: "StructuredText"
--value: [
--{
type: "heading1"
text: "Sample Page"
spans: [ ]
}
]
}

--effectivefrom: {
type: "Timestamp"
value: "2018-06-20T23:00:00+"
}
--department: {
type: "Select"
value: “SMA"
}
- - content: {
type: "StructuredText"
--value: [
--{
type: "paragraph"
text: "This is a sample page with some content."
spans: [ ]
}
-+{ … }
--{
type: "paragraph"
text: "There are 4 rules:"
--spans: [
--{
start: 10
end: 17
type: "strong"
}
]
}


> On 7 Jun 2018, at 21:58, Tim Mackinnon  wrote:
> 
> 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.
> 
> Tim
> 
> Sent from my iPhone
> 
>> On 7 Jun 2018, at 21:44, Esteban A. Maringolo  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 ddmm  ] ].
>> 
>> 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 

Re: [Pharo-users] Understanding ZnJSONReader mapping?

2018-06-07 Thread Tim Mackinnon
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.

Tim

Sent from my iPhone

> On 7 Jun 2018, at 21:44, Esteban A. Maringolo  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 ddmm  ] ].
> 
> 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
> 




Re: [Pharo-users] Understanding ZnJSONReader mapping?

2018-06-07 Thread Esteban A. Maringolo
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 ddmm  ] ].

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



[Pharo-users] Understanding ZnJSONReader mapping?

2018-06-07 Thread Tim Mackinnon
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?

Tim

Sent from my iPhone