Yeah, that is the main problem with JSON. It cannot capture that variability in 
its own spec. Sure, there are tons of extensions on top of JSON to address 
these aspects, but NeoJSON only deals with the raw spec. And any server can use 
its own version.

Simple answer is indeed: getmarkets and getticker return different schema, 
since you know what you call, you can map accordingly. (And hope the server 
does not do further variability). There cannot be one global mapping. 

> On 13 Dec 2017, at 05:37, Ben Coman <b...@openinworld.com> wrote:
> 
> Hi Sven (et al),
> 
> On 10 December 2017 at 11:45, Ben Coman <b...@openinworld.com> wrote:
> 
> 3. Finally parse into real objects the nested level holding the data you 
> really want...
> 
> Object subclass: #Market
>       instanceVariableNames: 'MarketCurrency BaseCurrency MarketCurrencyLong 
> BaseCurrencyLong MinTradeSize MarketName IsActive Created Notice IsSponsored 
> LogoUrl'
>       classVariableNames: ''
>       package: 'Bittrex'
> 
> (ZnClient new 
>       url: 'https://bittrex.com/api/v1.1/public/getmarkets';
>       enforceHttpSuccess: true;
>       accept: ZnMimeType applicationJson;
>       contentReader: [ :entity | |reader|
>               reader := (NeoJSONReader on: entity readStream).
>               reader for: BittrexResponse do: [:m| 
>                       m mapInstVar: #success.
>                       m mapInstVar: #message.
>                       (m mapInstVar: #result) valueSchema: #ArrayOfMarkets].
>               reader for: #ArrayOfMarkets customDo: [ :mapping | mapping 
> listOfElementSchema: Market ].
>               reader mapInstVarsFor: Market. 
>       reader nextAs: BittrexResponse ];
>    get) inspect.
> 
> ==>BittrexResponse
>       success => true
>       message => '' 
>       result => an Array(a Market(LTC) a Market(DOGE) a Market(VTC) a 
> Market(PPC) a Market(FTC) a Market(RDD) 
> ... Market(POWR) a Market(BTG) a Market(BTG) a Market(BTG) a Market(ADA) a 
> Market(ENG) a Market(ENG))
> 
> So the code of [3.] above works fine when the raw response looks like this...
> (ZnClient new 
>       url: 'https://bittrex.com/api/v1.1/public/getmarkets';
>       get) inspect.
> ==> {"success":true,
>           "message":"",
>           "result": [{"MarketName":"BTC-LTC},{"MarketName":"BTC-NXT}]
>         }
> 
> But of course [3.] doesn't work when the raw response looks like this...
> (ZnClient new 
>       url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LTC';
>       get) inspect.
> ==> {"success":true,
>            "message":"",
>            "result":{"Bid":0.01765465,"Ask":0.01769000,"Last":0.01763350}
>        }
> 
> since result is a json-object not a json-array.  But I can't work out 
> how to map the JSON object into the 'result' instance variable of 
> BittrexResponse, 
> where...
> 
> BittrexObject subclass: #BittrexTicker
>       instanceVariableNames: 'Bid Ask Last'
>       classVariableNames: ''
>       package: 'Bittrex'
> 
> 
> My best guesses so far are uncommenting either [A.] or [B.] below...
> 
> (ZnClient new 
>       url: 'https://bittrex.com/api/v1.1/public/getticker?market=BTC-LTC';
>       enforceHttpSuccess: true;
>       accept: ZnMimeType applicationJson;
>       contentReader: [ :entity | |reader|
>               reader := (NeoJSONReader on: entity readStream).
>               reader for: BittrexResponse do: [:m| 
>                       m mapInstVar: #success.
>                       m mapInstVar: #message.
>                       (m mapInstVar: #result) valueSchema: #BittrexTicker].
> "A.           reader for: BittrexTicker do: [ :m|
>                        m mapInstVar: #Bid]."
> "B.           reader for: #BittrexTicker customDo: [ :mapping |
>                       mapping mapWithValueSchema: BittrexTicker]."
>       reader nextAs: BittrexResponse ];
>    get).
> 
> 
> Can you advise what formulation is required? 
> cheers -ben


Reply via email to