Grabbing JSON from some url is very easy.
strandio
includes the fetch-json
function which will handle the HTTP request, response, and parsing, producing json
.
The following thread fetches the current Bitcoin price from the CoinGecko API in the specified currency and prints it to the terminal.
btc-price.hoon
/- spider/+ *strandio=, strand=strand:spider=, dejs-soft:format=, strand-fail=strand-fail:libstrand:spider^- thread:spider|= arg=vase=/ m (strand ,vase)^- form:m=/ url"https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies="=/ cur !<((unit @tas) arg)?~ cur (strand-fail %no-arg ~)=. u.cur (crip (cass (trip u.cur)))?. ((sane %tas) u.cur) (strand-fail %bad-currency-format ~);< =json bind:m (fetch-json (weld url (trip u.cur)))=/ price=(unit @ta) ((ot ~[bitcoin+(ot [u.cur no]~)]) json)?~ price ((slog 'Currency not found.' ~) (pure:m !>(~)))%- (slog leaf+"{(trip u.price)} {(cuss (trip u.cur))}" ~)(pure:m !>(~))
Save it as /ted/btc-price.hoon
in the %base
desk of a fake ship, |commit %base
and run it with -btc-price %usd
. You should see something like:
> -btc-price %usd49168 USD
You can try with other currencies as well:
> -btc-price %nzd72455 NZD> -btc-price %aud68866 AUD> -btc-price %gbp37319 GBP
Analysis
The thread takes an @tas
as its argument, which the dojo wraps in a unit
. We extract the vase
and check it's not empty:
=/ cur !<((unit @tas) arg)?~ cur (strand-fail %no-arg ~)
We then convert it to lowercase and check it's a valid @tas
:
=. u.cur (crip (cass (trip u.cur)))?. ((sane %tas) u.cur) (strand-fail %bad-currency-format ~)
Next, we use the fetch-json
function in strandio
like so:
;< =json bind:m (fetch-json (weld url (trip u.cur)))
We convert the currency to a tape
and weld
it to the end of the url
, which we give as an argument to fetch-json
. The fetch-json
function will make the request to the URL, receive the result, parse the JSON and produce the result as a json
structure.
The JSON the API produces looks like:
{"bitcoin": {"usd": 49477}}
Since it's an object in an object, we decode them using nested ot:dejs-soft:format
functions, and the price itself using no:dejs-soft:format
to produce a (unit @ta)
:
=/ price=(unit @ta) ((ot ~[bitcoin+(ot [u.cur no]~)]) json)
Finally, we check if the unit
is null and either print an error or print the price to the terminal with slog
functions (the thread itself produces ~
):
?~ price ((slog 'Currency not found.' ~) (pure:m !>(~)))%- (slog leaf+"{(trip u.price)} {(cuss (trip u.cur))}" ~)(pure:m !>(~))
For more information about working with json
, see the JSON Guide.