# WIP over HTTPS WIP over HTTPSは、**WIP Core ProtocolをHTTPS上へ対応付ける標準Transport Binding**である。 ## 目的 Core Protocolの意味論を変えずに、既存のWebインフラを利用してClientとHostを接続する。 ## 方針 初期の標準bindingはHTTPS上のrequest / responseのみを規定する。TLS、認証、Proxy、Gateway、Observability、Caching、connection reuse、multiplexing、compression等の既存機構を利用してよいが、特定のHTTP versionや実装方式を必須にしない。 OperationがWebSocket等のendpointを通常のdomain valueとして返すことは妨げない。そのendpoint上のprotocol、状態、lifecycleはWIPの規定対象外であり、ClientとHost固有実装の責務とする。 双方向socket transportをWIP bindingとして標準化する場合は、将来の独立した拡張として定義する。 ## Binding対象 少なくとも、Core Protocolの以下の操作をHTTP request / responseへ対応付ける。 - `fetch` - `fetch_tree` - `fetch_interface` - `call_operation` 具体的なHTTP method、endpoint、content type、error mapping、認証方式、batch表現などは、このbinding仕様側で定義する。 ## Interfaceの取得 Objectの公開情報はOperation定義を直接含まず、[WIP IDL](wip-idl.md) documentで定義されたInterfaceへの参照を持つ。`fetch_interface`は、その参照に対応するInterfaceのlanguage identifier、source、digestを返す。 HTTPS response全体をJSON envelopeにする場合、IDL sourceをJSON stringとして格納してよい。ただし、これはIDLをJSON ASTへ変換するものではない。BindingはIDL sourceを専用resourceおよびcontent typeで直接取得する方法を定義してもよい。 ClientはObjectのInterface参照をcacheと比較し、未知のInterfaceだけを`fetch_interface`する。HostはClientのcache状態を推測せず、`fetch`や`fetch_tree`のresponseへInterface定義を先行同梱しない。複数のInterface取得はHTTP batchingでまとめられる。 ## Operation valueのJSON encoding WIP over HTTPSでは、`call_operation`のargumentsとresultを、選択したOperation declarationに従うJSON valueとしてencodeする。JSONはHTTPS binding上の値表現であり、WIP CoreのInterface定義形式ではない。 `arguments`はOperationのparameter名をfield名とするJSON objectとする。位置引数は用いず、引数を持たないOperationには空のobjectを渡す。 概念的なrequest bodyは次の形になる。 ```json { "target": "/items/current", "operation": "get_related_item", "arguments": { "relation": "sibling", "limit": 10 } } ``` IDL型からJSONへのmappingはbindingで一意に定める。少なくとも次の規則を持つ。 - `boolean`、`string`、`number`、record、listは対応するJSON valueで表す。 - optionalなparameterまたはrecord fieldはfieldの省略で表し、`null`とは区別する。 - unit形式のenumはstring、payloadを持つunionは明示的なdiscriminatorを持つobjectで表す。 - `bytes`はbase64でencodeしたstringとして表す。 - 通常のJSON numberで表す`integer`は相互運用可能な安全範囲に制限する。それを超える整数型を設ける場合はdecimal string等のlosslessな表現を定義する。 - WIP IDLの`entry`は、同じWorldspace内のcanonical absolute pathをJSON stringとして表す。 ClientはWIP IDLに従ってvalueをdecodeし、IDL上で`entry`と宣言された位置にある文字列だけをエントリとして認識する。通常の`string`や任意JSON値に含まれるpathらしい文字列を、エントリとして推測してはならない。 ## HTTP batching WIP over HTTPSは、複数の独立したCore取得requestを一つのHTTP requestへまとめるbatch形式を提供する。Batchingは通信上のpackagingであり、Core Protocolへ新しい操作や意味論を追加しない。 Clientは、Known SpaceとInterface cacheをもとに必要なrequestだけを選択してbatchを構成する。HostはClientの既知状態を推測して、要求されていないentry公開情報やInterface定義をresponseへ追加しない。 Batch endpointは概念的に`POST {wip-endpoint}/batch`とし、bodyに一意な`id`を持つsubrequestの配列を格納する。 ```json { "requests": [ { "id": "entry-123", "method": "fetch", "arguments": { "entry": "/items/123" } }, { "id": "entry-456", "method": "fetch", "arguments": { "entry": "/items/456" } }, { "id": "item-interface", "method": "fetch_interface", "arguments": { "interface": "sha256:item-interface" } } ] } ``` Hostは各subrequestを、単独で受け取った場合と同じ規則で処理する。Responseは同じ`id`で対応付けたsubresponseの配列を返す。 ```json { "responses": [ { "id": "entry-123", "result": { "name": "123", "description": "First item", "interface": "sha256:item-interface" } }, { "id": "entry-456", "error": { "code": "not_found", "message": "Entry not found" } }, { "id": "item-interface", "result": { "interface": "sha256:item-interface", "language": "wip-idl/1", "digest": "sha256:item-interface", "source": "..." } } ] } ``` Batchには次の規則を適用する。 - Request内の`id`は一意なstringとする。 - Responseの順序に意味を持たせず、`id`でcorrelateする。 - 各subrequestは独立して成功または失敗し、一つの失敗によって他のresultを破棄しない。 - Batch全体はtransactionではなく、atomicity、共通snapshot、実行順序を保証しない。 - Hostはsubrequestを直列または並列に実行してよい。 - Subrequest間で、先行requestのresultを後続requestのargumentsとして参照できない。 - 各`result`は対応するCore操作を単独で呼んだ場合と同じvalueとする。 - 各`error`は通常のProtocol errorと同じschemaを使用する。 - HostはClientが要求していないsubresponseを追加してはならない。 初期のbatch形式に格納できるのは`fetch`、`fetch_tree`、`fetch_interface`とし、`call_operation`は含めない。将来、WIP IDLのEffect annotationを採用する場合に、副作用を持たないと明示されたOperationをbatch対象へ加えるかを改めて検討する。 Batch件数、request / response byte size、timeoutの上限、およびbatch envelope自体が不正な場合のHTTP statusはbindingの詳細として定める。 ## 非目標 WIP over HTTPSはHost内部のAPIやデータソース接続方式を規定しない。また、WIP Core ProtocolそのものをHTTP依存のモデルへ変えることも目的としない。