セレクター
セレクターは、どのデバイスとどのセッションを、HTTP リクエストまたは WebSocket コマンドの対象として指定します。
デバイスセレクター — URL パス
すべてのデバイスレベルのHTTP ルートで、/{device_type}/{id_or_index}/… の形式で使用されます。
| ルートの例 | セレクターの意味 |
|---|---|
inverse3/0 | インデックス(0始まり)で指定した最初のInverse3 |
inverse3/A14 | デバイス ID A14 のInverse3 |
inverse3/* | すべてのInverse3デバイス(ワイルドカード) |
*inverse/* | Inverse ファミリーのすべてのデバイス(Inverse3、Inverse3x、Minverse) |
inverse3:left/0 | インデックス(0始まり)で指定した最初の左利きのInverse3 |
*inverse:right/0 | インデックス(0始まり)で指定した最初の右利きの Inverse ファミリーのデバイス |
verse_grip/0 | インデックス(0始まり)で指定した最初の有線のVerseGrip |
wireless_verse_grip/* | すべてのワイヤレス VerseGrip |
*verse_grip/* | VerseGrip ファミリーのすべてのデバイス(有線、ワイヤレス、カスタム) |
*verse_grip:custom/0 | インデックス(0始まり)で指定した最初のカスタムVerseGrip(custom_verse_grip/0 と同じ) |
インデックス付けの前にクラスフィルターを解決
<type>:<class>/<N> 形式のセレクターは、まずクラスフィルターを適用し、その後、フィルター後の集合に対してインデックスを付けます。<N> は、生のデバイス一覧ではなく、フィルター後の一覧における位置を指します:
*inverse:left/0— 0番目の左利きの Inverse ファミリーのデバイスです。Inverse が3台接続されている場合(右、左、右の順)、これは2台目のデバイスに解決されます。インデックス0を「left である必要がある」でフィルターした結果を指すわけではありません。inverse3:right/0— 0番目の右利きのInverse3です。*inverse:left/3— 接続されている左利きの Inverse が4台未満の場合は、Inverse が全体で4台を超えていても404を返します。
ワイルドカードセレクターにも同じルールが適用されます。*inverse/* と *verse_grip/* はファミリー内のすべてのデバイスに一致し、これらのセレクターを対象とする POST および DELETE リクエストは、最初の1台だけでなく、一致したすべてのデバイスに操作を適用します。
ルール:
GETはワイルドカードセレクターを(曖昧であるため)拒否します →400POSTとDELETEはワイルドカードを受け付けます。操作はすべての一致に適用されます404レスポンスはno device matches selector '<sel>'の形式を使用します。<sel>は受信した元のセレクター式です
対応する {device_type} の値: inverse3、verse_grip、wireless_verse_grip、またはファミリーのワイルドカード *inverse、*verse_grip。
セッションセレクター — ?session=<expr> クエリパラメーター
セッションスコープのHTTP エンドポイント(basis、mount、preset、filters、navigation、SDF)では、操作対象となるセッションのコンテキストを特定するために ?session=<expr> クエリパラメーターが必要です。
| 式 | 意味 |
|---|---|
| (省略) | すべてのセッション(DELETE でのみ許可) |
#123 または 123 | 数値 ID 123 のセッション |
:0 | インデックス指定による最初のセッション |
:-1 | インデックス指定による最後のセッション |
profile_name | このプロファイルを持つ最初のセッション(曖昧になる場合があります) |
profile_name:0 | プロファイルを指定したうえで、インデックス 0 のセッション |
:default:0 | プロファイル default を持つセッションのうち、インデックス 0 の最初のセッション |
co.haply.hub::*:0 | プロファイル名が co.haply.hub:: で始まる最初のセッション(グロブのワイルドカード) |
:co.haply.hub::*:-1 | co.haply.hub:: 名前空間内の最後のセッション |
例:
GET /inverse3/0/config/navigation?session=:default:0
プロファイル名のワイルドカード
プロファイルパターンでは、2種類のグロブのメタ文字を使用できます:
| メタ文字 | 意味 |
|---|---|
* | 空文字列を含む、任意の長さの文字列に一致 |
? | ちょうど1文字に一致 |
上記以外のすべての文字(:、.、-、[、] を含む)は、リテラルとして一致します([abc] のような文字クラスはサポートされていません)。大文字と小文字は区別されます。
単独の *(または all)は、従来どおりすべてのセッションを意味します。名前が * で始まるプロファイルに一致させるには、ほかに少なくとも1文字を含めてください(例: *foo)。
よく使われるパターン:
co.haply.hub::*—co.haply.hub::名前空間内の任意のプロファイル*-update—-updateで終わる任意のプロファイルco.haply.*:*— 名前空間がco.haply.で始まる任意のプロファイルdefaul?—defaulで始まる7文字の任意のプロファイル
ワイルドカードパターンは単独では曖昧です(複数のセッションに一致する可能性があります)。GET / POST エンドポイントで使用するには、末尾に :<index> を付けて曖昧さを解消してください:
# First session in the Haply Hub namespace
GET /inverse3/0/config/basis?session=co.haply.hub::*:0
# Last session in a Unity namespace
GET /inverse3/0/config/mount?session=:co.haply.unity::*:-1
曖昧なワイルドカード(インデックスなし)は、GET/POST では 400 で拒否されます。これらは、複数セッションへの一致を明示的に受け付けるルートでは許容されます。具体的には、GET /sessions/<sel>(一致したすべてを返す)と、DELETE エンドポイント(すべての一致に適用)です。
セッションセレクター — URL パス
/sessions/{selector} エンドポイントは、パスパラメーターと同じ式を受け付けます。単一のセッションを検索したり、そのセッションが存在するかどうかを確認したりする際に便利です:
GET /sessions # list all active sessions
GET /sessions/:default:0 # one session by profile + index
GET /sessions/:-1 # last active session
GET /sessions/#42 # session id 42
GET /sessions/co.haply.hub::* # every session in the co.haply.hub:: namespace
GET /sessions/co.haply.hub::*:0 # first session in that namespace
これは機能的には GET /sessions?session=<selector> と同等です。どちらのルートも同じハンドラーを呼び出します。GET /sessions/<sel> は、:<index> のサフィックスなしで曖昧なワイルドカードパターンを許容する、数少ないエンドポイントの1つです。GET /sessions と同じリスト形式のラッパー構造で、一致したすべてを返します。
上記のすべてのセレクター形式(#42 や * を含むプロファイルパターンを含む)は、標準のHTTPクライアント(Python requests、libhv、curl、fetch)によってそのまま送信されます。クライアント側での URL エンコードは不要です。シェルでは、# や * を含むトークンを引用符で囲んでください(例: --session "#42"、--session "co.haply.hub::*:0")。そうしないと、シェルがそれらをコメントとして扱ったり、ローカルファイルに対してグロブ展開したりします。
例外が1つあります: ? のグロブのメタ文字は、パスにおいては URL のクエリの区切り文字です。パス形式のセレクター(例: /sessions/defaul?:0)では、%3F としてパーセントエンコードする必要があります(例: GET /sessions/defaul%3F:0)。クエリ形式のセレクター(?session=defaul?:0)では、最初の ? だけがクエリを分割し、以降の ? 文字はそのまま渡されます。
WebSocket の接続では、接続そのものがセッションになります。configure と commands のエントリは、現在のセッションのデバイスを自動的に対象とします。セッションセレクターが必要なのは、HTTP リクエストのみです(セッションをまたぐリモート操作を含みます。詳しくは セッション を参照してください)。