Even for modern solutions like Clickhouse, we have internal RPC proxies, and KPHP is still an RPC client.
TL-schema is a .tl file. It consists of types and functions:
---types---
...
---functions---
...
A function looks like this:
messages.createChat creator_id:int invited_ids:%(Vector int) name:string = Int;
This describes, that an engine can handle a query for creating chat, and several parameters are required.
A type is a set of constructors and type name. Having one constructor is intuitively simple:
audio.audioId user_id:int tag:string = audio.AudioId;
This describes the type audio.AudioId with one constructor having two arguments.
Multiple constructors are more powerful. Say, we have a Memcache engine with a function to query a value:
memcache.get key:string = memcache.Value;
But Memcache can store either string or numeric value at a key, just as a key might not exist. Describe it as:
memcache.not_found = memcache.Value;
memcache.str_value value:string = memcache.Value;
memcache.numeric_value value:long = memcache.Value;
A type usage can be marked “bare”. This influences binary serialization format: only a value needs to be stored, without any prefix (“magic” in TL terms, similar to “field index” in Protobuf). Bareness can be triggered:
This can be used only for types with one constructor, except it is a result of a function.
It should not be used, when other constructors are likely to be added in the future and there is no need for binary size reduction (for example, a single value, not a vector).
A type can have external arguments. There are two primary cases: another type or a “numeric variable”.
resultFalse {t:Type} = Maybe t;
resultTrue {t:Type} result:t = Maybe t;
Maybe here is a dependent type to add “value absence” to any type t. For example, Maybe int is either a concrete integer or not a value at all.
Types depending on numeric variables are described like
fileStorage.localCopy {fields_mask:#}
cached_at:fields_mask.0?int
available:fields_mask.1?Bool
last_sync_info:fields_mask.2?(Maybe %fileStorage.SyncInfo)
= fileStorage.LocalCopy fields_mask;
Once passed, a bitmask controls binary serialization: which fields should be stored/fetched. This helps omit transferring fields you don't need at the exact invocation.
TL is described on the MTProto page, with examples and advanced topics — read it here.
There is a plugin for PhpStorm. It highlights .tl files and supports symbols navigation: