Symbol SDK 2.x系と3.x系
Symbol SDK は3.x系からガラッと実装が変わっています。というか作り直されています。
大まかな点で変化をまとめると、
2.x | 3.x |
---|---|
WEB APIアクセスクラスがある | WEB APIに関与しない |
RxJSでストリームを扱える | RxJSに依存しない |
TypeScript | JavaScript |
(全部隅々まで見たわけではないので若干間違っているかもしれませんが)
SDK 2.xの大部分はAPIアクセスクラスを占めていたと言っても過言ではなく、その部分がごっそりなくなりました。
また、全体的な実装ボリュームも削減されたので、機能としても大幅に削減されています。
RxJSはWeb APIクラスが依存していましたが、それが無くなったので依存から無くなりました。
理由はコアデブなどに確認したわけではないので、憶測ですが、
- 規模が大きくなりすぎていて、メンテが行き届かなくなり、必要な機能だけに絞り込んだ小さなSDKを目指している
- 他の言語と同様のインターフェイスと使い心地を維持するため、リアクティブを止めた
という狙いがあるように思えます。
参考までに公開されているパッケージのリンクを張っておきますが、この記事においては、SDKの利用については触れません。
SDK 2.x
SDK 3.x
WEB API エンドポイント
エンドポイントの定義はここで確認できます。
そして、API定義はOpen APIフォーマットで定義されており、リポジトリはこちらです。
例えば、次のようにアクセスします。
$ curl -k https://001-joey-dual.symboltest.net:3001/node/info | jq .
{
"version": 16777987,
"publicKey": "AAA1922FA60DB681092CBE70A9A1BAB85745025310AE7567F95EA7FD05B3D3FC",
"networkGenerationHashSeed": "7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836",
"roles": 7,
"port": 7900,
"networkIdentifier": 152,
"host": "001-joey-dual.symboltest.net",
"friendlyName": "001-joey-dual",
"nodePublicKey": "05E5C0841720AE9DA737C184429002E917F74FF7A3BF8E11AC2862C4875B3D7E"
}
よくあるJSON
を返却するWEB APIです。
ここではcurl
でアクセスしてみましたが、要するにSymbolのWEB APIは単なるHTTPアクセスで扱えるということです。
API アクセスの悩み
2.x系のAPIアクセスクラスでは、リクエストやそれに関するパラメタの処理に加え、レスポンスには型を付けて(RxJSのObservalなので)ストリームに流してくれていました。
const factory = new RepositoryFactoryHttp(NODE_GATEWAY_URL)
const nodeRepo = factory.createNodeRepository()
nodeRepo.getNodeInfo()
.subscribe((resp: NodeInfo) => console.info(resp))
> NodeInfo {
> publicKey: 'AAA1922FA60DB681092CBE70A9A1BAB85745025310AE7567F95EA7FD05B3D3FC',
> networkGenerationHashSeed: '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836',
> port: 7900,
> networkIdentifier: 152,
> version: 16777987,
> roles: [ 1, 2, 4 ],
> host: '001-joey-dual.symboltest.net',
> friendlyName: '001-joey-dual',
> nodePublicKey: '05E5C0841720AE9DA737C184429002E917F74FF7A3BF8E11AC2862C4875B3D7E'
> }
しかし、3.xではそれらが無くなってしまったので、WEB APIアクセスは実装者に委ねられるようになります。
HTTPアクセスについてはnode-fetch
、axios
、superagent
など、好きなライブラリを使えばいいでしょう。
でも、レスポンスオブジェクトの型はどうしましょう…。
Aspida で解決するアプローチ
自分も最近ちょっと触っただけなので、あまり語れないので、他の解説記事を確認してもらいたいんですが、簡単に言うと、WEB APIに型付きでアクセスするできるようになるライブラリです。
結論から書くと、こんな感じでAPIレスポンスを得られるようになります。
const info: NodeInfoDTO = await client.node.info.$get()
console.info(server)
> {
> version: 16777987,
> publicKey: 'AAA1922FA60DB681092CBE70A9A1BAB85745025310AE7567F95EA7FD05B3D3FC',
> networkGenerationHashSeed: '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836',
> roles: 7,
> port: 7900,
> networkIdentifier: 152,
> host: '001-joey-dual.symboltest.net',
> friendlyName: '001-joey-dual',
> nodePublicKey: '05E5C0841720AE9DA737C184429002E917F74FF7A3BF8E11AC2862C4875B3D7E'
> }
めちゃくちゃいいですね…。
レスポンスだけでなく、呼び出しも型補完できるので、型の力の恩恵を存分に受けることができます。
openapi2aspida
APIの定義はOpenAPIドキュメントから生成することができます。
openapi2aspida
を使って、定義からクラスを生成します。
$ npx openapi2aspida -i openapi3.yml
Symbol APIのOpenAPI定義の修正
公式で公開されている定義ではエラーになってしまうので、動作するように自分の方で修正を施しました。
一応自分なりにOpenAPIの仕様を確認した上で修正をしましたが、そんなに真面目に定義を書いたことがないので、これが正解かまではわかりません。
こちらからclone
して、npm run build
して、openapi3.yml
を生成してください。
$ git clone -b fix https://github.com/44uk/symbol-openapi.git
$ npm install && npm run build
> symbol-openapi@1.0.4 build
> swagger-cli bundle ./spec/openapi.yml --outfile _build/openapi3.yml --type yaml
Created _build/openapi3.yml from ./spec/openapi.yml
Aspida API ソース生成
ビルドしたAPI定義を指定して、クラスを生成します。
$ npx openapi2aspida -i _build/openapi3.yml
api/$api.ts was built successfully.
api/account/$api.ts was built successfully.
.
.
api/transactions/partial/$api.ts was built successfully.
api/transactions/unconfirmed/$api.ts was built successfully.
api/
にクラスが生成されます。
実装
import axios from 'axios'
import axiosClient from '@aspida/axios'
import api from './api/$api'
import { NodeInfoDTO } from './api/@types'
;(async () => {
const client = api(
axiosClient(axios, {
baseURL: 'https://001-joey-dual.symboltest.net:3001',
})
)
const info: NodeInfoDTO = await client.node.info.$get()
console.info(server)
})()
> {
> version: 16777987,
> publicKey: 'AAA1922FA60DB681092CBE70A9A1BAB85745025310AE7567F95EA7FD05B3D3FC',
> networkGenerationHashSeed: '7FCCD304802016BEBBCD342A332F91FF1F3BB5E902988B352697BE245F48E836',
> roles: 7,
> port: 7900,
> networkIdentifier: 152,
> host: '001-joey-dual.symboltest.net',
> friendlyName: '001-joey-dual',
> nodePublicKey: '05E5C0841720AE9DA737C184429002E917F74FF7A3BF8E11AC2862C4875B3D7E'
> }
おまけ(OpenAPI定義からモックサーバを立てる)
せっかくなので、モックサーバも立ててみましょう。
docker run --rm -p 3000:4010 stoplight/prism:4 mock -h 0.0.0.0 https://symbol.github.io/symbol-openapi/v1.0.4/openapi3.yml
色々とモックサーバを立てるDockerイメージが公開されていましたが、定評がありそうなstoplight/prism
にしてみました。
直接URLを指定して動かすことができたので、お手軽でいいですね。
立ち上がったらhttp://localhost:3000/node/info
にアクセスしてみましょう。
symbol-bootstrap
を使えば簡単にローカルにノードを立ち上げたり、プライベートネットワークを立ち上げることもできますが、かなりの容量やスペックを必要とします。
ダミーレスポンスで用が足りる場合や、開発時・テスト時に活用して見てください。
まとめ
WEB APIアクセスクラスが無くなったことで、symbol-sdk
単体ではAPIからデータの取得をできなくなってしまいました。
その分だけハードルが上がってしまったかもしれませんが、RxJS
の学習もなかなかに難儀でした。
むしろより一般的な知識で実装すればいいので、プログラミング初学者としてはSymbol APIを扱うために学習したことの応用が効きやすく、習熟者であれば既存の知識で実装することができるでしょう。
今回はAspida
を用いた一例の記事でしたが、OpenAPIを利用した型付与の方法は他にもあるようですし、型が必要ないならどうぞ任意のHTTPクライアントをご利用ください。
キミだけのWEB APIアクセスノウハウを構築しよう!