On 5 December 2017 at 20:44, Sven Van Caekenberghe <s...@stfx.eu> wrote: > > > > On 5 Dec 2017, at 13:33, Ben Coman <b...@openinworld.com> wrote: > > > @sven, I started reading Enterprise Pharo a couple of hours ago. > > I don't quite get your section references. I presume you > > don't mean "chapter 11 Persisting Objects with Voyage, 11.3 Enhancing > Storage" > > That seems off topic. And "chapter 4 Zinc HTTP: The Client Side, 4.11 > Headers" > > doesn't have a sub-part "3". > > I meant 11.3 in this page https://ci.inria.fr/pharo-contribution/job/ > EnterprisePharoBook/lastSuccessfulBuild/artifact/ > book-result/Zinc-HTTP-Server/Zinc-HTTP-Server.html a section called 11.3. > A Zinc Client. > > > I guess part of what I'm interested in are patterns for hooking > > NeoJSON up to parse a REST response into objects to build a wrapper > > around a REST service. I see a chapter in Enterprise Pharo, which I'll > > get to that soon. Perhaps I was premature asking before reading that, > > but its good to have a few paths to explore. > > Here is a recent example http://forum.world.st/Another- > example-of-invoking-a-REST-JSON-web-service-resolving- > User-Agent-strings-tt5017489.html
Thanks Sven. That helped a lot. I'd like to report success. It may be useful to others to see how to progressively build up to parsing a Nested JSON REST 1. First parse the JSON into simple Dictionaries... (ZnClient new url: 'https://bittrex.com/api/v1.1/public/getmarkets'; enforceHttpSuccess: true; accept: ZnMimeType applicationJson; contentReader: [ :entity | NeoJSONReader fromString: entity contents ]; get) inspect. ==>Dictionary( 'success' ==> true 'message' ==> '' 'result ' ==> an Array(a Dictionary('BaseCurrency'->'BTC' 'BaseCurrencyLong'->'Bitcoin') ... a Dictionary('BaseCurrency'->'ETH' 'BaseCurrencyLong'->'Ethereum') 2. Then parse the first level response into a real object... Object subclass: #BittrexResponse instanceVariableNames: 'success message result' classVariableNames: '' package: 'Bittrex' (ZnClient new url: 'https://bittrex.com/api/v1.1/public/getmarkets'; enforceHttpSuccess: true; accept: ZnMimeType applicationJson; contentReader: [ :entity | (NeoJSONReader on: entity readStream) mapInstVarsFor: BittrexResponse ; nextAs: BittrexResponse ]; get) inspect. ==>BittrexResponse success => true message => '' result => an Array(a Dictionary('BaseCurrency'->'BTC' 'BaseCurrencyLong'->'Bitcoin') ... a Dictionary('BaseCurrency'->'ETH' 'BaseCurrencyLong'->'Ethereum') Or alternatively... (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 ]. reader nextAs: BittrexResponse ]; get) inspect. ==>BittrexResponse success => true message => '' result => an Array(a Dictionary('BaseCurrency'->'BTC' 'BaseCurrencyLong'->'Bitcoin') ... a Dictionary('BaseCurrency'->'ETH' 'BaseCurrencyLong'->'Ethereum') 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)) WhooHoo! A couple of things remaining: * The instance variables of Market currently start with an upper-case to match the JSON fields. Lower-casing the first letter breaks things. What strategies can be used to conform here to Smalltalk conventions? Or is it easy enough to live with it? * In various posts I've seen mention of a class-side method #neoJsonMapping: but there is no explanation of this in the Enterprise Book. How might #neoJsonMapping: come into the picture for my use case above? cheers -ben