On 13 December 2017 at 14:40, Sven Van Caekenberghe <sven@stfx.eu> wrote:
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.
Thats cool. I'm not looking for one global mapping to simultaneously handle getmarkets and getticker together. I'm just looking to handle getticker in isolation. I can't work that part out. cheers -ben
On 13 Dec 2017, at 05:37, Ben Coman <btc@openinworld.com> wrote:
Hi Sven (et al),
On 10 December 2017 at 11:45, Ben Coman <btc@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