Versions and compatibility
One published bundle of .proto files works against servers of many versions. The API grows by
addition, and the server tells you what it supports.
How the API changes
The gRPC API is the API that the M-Files clients themselves use, so it evolves with the product. Almost all changes are additions that follow the compatibility rules below, and code written for one version usually keeps working with newer servers. M-Files may also change the API in other ways as the product evolves, including deprecating and removing methods. Methods documented as "For M-Files components only" are internal and can change without notice.
To see what a new version changes, compare its bundle with the one you built against: a diff of
the .proto files shows the added, changed and removed methods and fields, and a coding agent can
update your code from it.
What the server tells you
QueryVersion (anonymous) returns packed 64-bit versions, 16 bits each for major, minor, build and revision (Connecting shows the decoding):
| Field | Example | Meaning |
|---|---|---|
server_version |
7318397729964032 = 26.11.16645.0 | The server's version. |
oldest_compatible_client_version |
5348033629585408 = 19.2.7357.0 | The oldest client version that the server currently accepts. |
oldest_compatible_admin_client_version |
19.2.7357.0 | The same for administrative clients. |
oldest_compatible_replica_server_version |
19.2.7357.0 | The same for replica servers. |
GetServerCapabilities (anonymous) returns
ServerVaultCapabilities: one boolean per optional feature
(for example search_results_sorting, vault_login_accounts). A feature is available when its
flag is true; a flag that the server's version does not know arrives as false. After login,
session_data.server_vault_capabilities gives the same flags for the server and the vault.
Prefer capability flags to version comparisons where a flag exists. Use server_version for
behavior that has no flag, and to report the server version in your logs.
What you tell the server
ClientData goes with LogIn:
| Field | Send |
|---|---|
type |
CLIENT_TYPE_SERVER_API for a service or script; it is recorded with the session. |
version |
Optional. A packed version, as in QueryVersion: the version of the server that the bundle you generated your stubs from was published for, for example 26.11.0.0. |
capabilities |
ClientCapabilities: set a flag only for a newer behavior your code handles. Unset flags keep the server's older behavior. |
language |
The language for server texts, for example en. |
Why version matters: some administrative operations check it and refuse clients that report an
older version (or none) with an "operation not supported by old client" error, and an
administrator can make the server refuse logins from clients older than a configured version
(E_MFILES_INCOMPATIBLE_SERVER_VERSION). A login with version unset works on a server with
default settings.
Compatibility rules
M-Files evolves the gRPC contract by these rules. They describe current practice and what the product aims for, not a guarantee:
- Methods are bound by name (
/MFiles.<Service>/<Method>). New methods are added; existing ones keep their names. Calling a method that the server does not have fails withUNIMPLEMENTED, so a client built from a newer bundle generally works against an older server as long as it does not call newer methods. - Fields are bound by number. New fields get new numbers. Field numbers are not reused, and fields keep their names (the mf-http-grpc gateway binds by name; see HTTP access).
- Unknown fields are ignored. Protobuf skips fields it does not know, so an older server ignores a newer field you set, and your client ignores fields a newer server adds.
- Missing fields have default values: empty string, zero, false, the enum's zero value, or an unset message. New fields are defined so that the default keeps the old behavior. Where a difference matters, a capability flag tells the two sides apart.
- Enums can grow. Handle enum values your code does not know (proto3 keeps them as numbers).
- A changed method keeps its name. When a method needs new parameters, its request message gets new fields under the rules above. Where that is not enough, a new method is added and the old one is marked as superseded. Superseded methods are left out of the published bundle and can later be removed from the server.
The published bundle and server versions
The bundle is generated from the server's interface definitions and is named after the server
version it comes from (for example 26.11). Its wire contract is identical to what that server
serves. Against an older server, the methods and fields added after that server's version are
missing: methods answer UNIMPLEMENTED, fields are ignored or arrive with default values. Check
server_version or the capability flags before using a recent feature on a server you do not
control, such as an on-premises installation.