メインコンテンツへスキップ

セレクター

セレクターは、どのデバイスとどのセッションを、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 は(曖昧であるため)ワイルドカードセレクタを拒否します → 400
  • POST と 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 または 123ID 123 のセッション
:0インデックス指定による最初のセッション
:-1インデックス指定による最後のセッション
profile_nameこのプロファイルを持つ最初のセッション(曖昧になる場合があります)
profile_name:0プロファイルを指定した上で、インデックス 0 のセッション
:default:0プロフィール default を持つセッションのうち、インデックス 0 の最初のセッション
co.haply.hub::*:0プロファイル名が co.haply.hub:: で始まる最初のセッション(グロブのワイルドカード)
:co.haply.hub::*:-1co.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 のセッションにはセレクタは必要ありません

WebSocket の接続では、接続そのものがセッションとなります。configure と commands このエントリは、現在のセッションのデバイスを自動的に対象とします。セッションセレクタが必要となるのは、HTTP リクエストのみです(セッションをまたぐリモート操作を含みます。詳細は セッション を参照してください)。