Tx for your report :) https://wordpress.com/post/pharoweekly.wordpress.com/2347
Did you look at SmartShackles? on our inria github repo. Because Santiago is extracting information from blockchains. On Sun, Dec 10, 2017 at 4:45 AM, Ben Coman <b...@openinworld.com> wrote: > > 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 >