はじめに
PDS(Personal Data Store) の OSS 「Personium」ですが、
肝心の個人データ管理には OData
と WebDAV
という標準化されたプロトコルを使用します。
今回はODataについて触り方を紹介します。Personium特有の制約事項などもあるので、
詳細はドキュメントを読むべきなのですが、
全部読んでいると日が暮れてしまいますので(例)、
ライブラリなどを使用して簡単に入門してみます。
Personiumについてはこちら → Personium とは何か?を個人的にまとめてみた
準備
o.js
を使う前に今回使用する環境を準備します。
Personiumのデータ構造
Personiumでは、ユニット
の中にセル
というものを作成し、
1人1人がそれを管理します。
管理にあたって、セルの中には用途ごとにボックス
を作成し、
ボックスの中には画像データなどの非構造データや、表データのような構造データを保存できます。
ボックス内の構成の管理に使用するプロトコルが WebDAV
で、
ボックス内のコンテンツの1つとして、OData
で管理できる表データがある形です。
セルの管理
Personiumのデモサーバーでは、いくつかのアプリがデフォルトでインストールされていて、
その中の「セルマネージャ」を使用すると簡単なセル管理が体験できます。
セルの管理の詳細については、セル管理(いずれ書きたい)の記事に任せるとして、ODataを作成していきます。
ODataの作成
今回はセルマネージャを使用して自分のセルに「odata-test」というボックスを作り、
その中に「sample」という名前で OData を作成しました。
EntityTypeの作成
ODataが作成できたら、次はその中に保存するデータの型(スキーマ)を定義していきます。
型「sampletype」
名前 | 型 |
---|---|
title | Edm.String |
description | Edm.String |
num | Edm.Int32 |
price | Edm.Double |
o.js
で OData に触れてみよう
それでは触っていきます。
インストール
まずは o.js
をインストールします。
npm install --save odata
準備
ここから先は oHandler
というインスタンスを使い回します。
const {o} = require('odata');
const token = "<YOUR_TOKEN>";
const defaultHeaders = { "Content-Type": "application/json" }
const oHandler = o('https://<YOUR_CELL_FQDN>/odata-test/sample/', {
headers: { "Authorization": `Bearer ${token}` , ...defaultHeaders },
});
こんな感じです。 <YOUR_TOKEN>
に入るトークンはセルマネージャから取得することもできます。
(ROPCなどで認証して取ってくるのが正当な手順ですが・・・)
EntityType取得
まずはEntityTypeを取得してみます。EntityType取得
$metadata/EntityType
を叩けばいいらしい。
const response = await oHandler
.get('$metadata/EntityType')
.query({
$format:"json"
});
console.log(JSON.stringify(response, null, 2)
{
"d": {
"results": [
{
"__metadata": {
"uri": "https://<YOUR_CELL_FQDN>:443/odata-test/sample/$metadata/EntityType('sampletype')",
"etag": "W/\"1-1588926355822\"",
"type": "ODataSvcSchema.EntityType"
},
"Name": "sampletype",
"__published": "/Date(1588926355822)/",
"__updated": "/Date(1588926355822)/",
"_AssociationEnd": {
"__deferred": {
"uri": "<略>/odatatest/sample/$metadata/EntityType('sampletype')/_AssociationEnd"
}
},
"_Property": {
"__deferred": {
"uri": "<略>/odata-test/sample/$metadata/EntityType('sampletype')/_Property"
}
}
}
]
}
}
ちゃんと定義されていることが伺えますね。
なお、下記スクリプトでプロパティ一覧を取得すると
const response = await oHandler
.get("$metadata/EntityType('sampletype')/_Property")
.query({
$format:"json"
});
console.log(response.d.results.map(x => `${x.Name}: ${x.Type}`));
[
'title: Edm.String',
'description: Edm.String',
'num: Edm.Int32',
'price: Edm.Double'
]
いい感じです。
Entity作成
続いて、先程定義した型でEntityを登録してみます。Entity作成
const dat = {
title: 'hoge',
description: 'fuga',
price: 100,
num: 5
}
const response = await oHandler
.post('sampletype', dat)
.query({
$format:"json"
});
セルマネージャで確認してみます。
たくさん作ってみます。
できてる!!
なお、 num: 0.325
など、本来 Int32 型のプロパティに Double を入れたりすると、
「400 Bad Request」が返ってきます。
Entity取得
const response = await oHandler
.get('sampletype')
.query({
$format:"json"
});
console.log(response.d.results.map(x => ({ title: x.title, price: x.price})));
結果
[
{ title: 'hoge', price: 100 },
{ title: 'hoge1', price: 100 },
{ title: 'hoge2', price: 100 },
]
クエリももちろん書けます。
const response = await oHandler
.get('sampletype')
.query({
$format:"json",
$filter: "title eq 'hoge' and num eq 0"
});
console.log(response.d.results.map(x => ({ title: x.title, num: x.num})));
結果
[ { title: 'hoge', num: 0 } ]
いいですね。
おまけ
使用した上でいくつか引っかかったポイントを紹介。
Proxy配下で使用する
o.js
内部で使用している node-fetch
はデフォルトでは
プロキシ環境変数(http_proxy, https_proxy)は読んでくれません。
そこで、上記のモジュールを使用させてもらいます。
npm install --save node-fetch-with-proxy
でもって、
const oHandler = o('<ODATA_ENDPOINT>');
global.fetch = require('node-fetch-with-proxy');
const response = await oHandler.get('hoge').query({});
といった形で、o
関数を実行した後にfetchを上書きします。
o
関数ではこのように、呼ばれた際にブラウザか否かを判定して、
fetch
がなければ polyfill を実行するようになっています。
// https://github.com/janhommes/o.js/blob/master/src/o.ts#L27
// polyfill fetch if we have no fetch
const env = typeof window !== "undefined" ? window : global;
if (!("fetch" in env) && !config.disablePolyfill) {
require("cross-fetch/polyfill");
}
自前で polyfill して、 config.disablePolyfill を true にするでも良いのですが、
今回はとりあえずこれで。
終わりに
今回は o.js
というライブラリを使用して ODataというプロトコルでデータを
触ってみる、という記事を書いてみました。
伝えたかったことは、ODataという標準化されているプロトコルを採用していることで、
既存のライブラリを使用することが可能であるという点です。
Personiumを使ってみたい、もっと知りたい、開発に参加したい、という方は
Personiumコミュニティ までお願いします!