Home

Kay Sievers edited this page Jan 17, 2018 · 41 revisions

Varlink is an interface description format and protocol that aims to make services accessible to both humans and machines in the simplest feasible way. See the Ideals page for more. And everybody likes Screenshots.

Interface

A varlink interface has a reverse-domain name and specifies which methods the interface implements. Each method has named and typed input and output parameters. Complex types can be aliased with the type keyword to allow reusing them and to make method signatures easier to read. The interface also specifies the errors that may be returned from its method calls.

Everything can be documented by adding a comment immediately before it. The documentation is provided to clients as structured data on a well-known service interface.

See the Interface Definition for how to parse an interface file.

# Interface to jump a spacecraft to another point in space. The 
# FTL Drive is the propulsion system to achieve faster-than-light
# travel through space. A ship making a properly calculated
# jump can arrive safely in planetary orbit, or alongside other
# ships or spaceborne objects.
interface org.example.ftl

# The current state of the FTL drive and the amount of fuel
# available to jump.
type DriveCondition (
  state: (idle, spooling, busy),
  tylium_level: int
)

# Speed, trajectory and jump duration is calculated prior to
# activating the FTL drive.
type DriveConfiguration (
  speed: int,
  trajectory: int,
  duration: int
)

# The galactic coordinates use the Sun as the origin. Galactic
# longitude is measured with primary direction from the Sun to
# the center of the galaxy in the galactic plane, while the
# galactic latitude measures the angle of the object above the
# galactic plane.
type Coordinate (
  longitude: float,
  latitude: float,
  distance: int
)

# Monitor the drive. The method will reply with an update whenever
# the drive's state changes
method Monitor() -> (condition: DriveCondition)

# Calculate the drive's jump parameters from the current
# position to the target position in the galaxy
method CalculateConfiguration(
  current: Coordinate,
  target: Coordinate
) -> (configuration: DriveConfiguration)

# Jump to the calculated point in space
method Jump(configuration: DriveConfiguration) -> ()

# There is not enough tylium to jump with the given parameters
error NotEnoughEnergy ()

# The supplied parameters are outside the supported range
error ParameterOutOfRange (field: string)

Protocol

Varlink can operates on any transport that supports the concept of connections. All messages are encoded as JSON objects and terminated with a single NUL byte.

For simplicity reasons and to minimize the state the client needs to track, a single connection allows only one single pending method call at the time. Apart from pipelining, a connection is busy until the method call has returned. Replies on the same connection are always received in the order of the calls.

The common case is a simple method call with a single reply. To support monitoring calls, subscriptions, chunked data, calls may carry instructions for the server to not reply, or to reply multiple times to a single method call. See the Method-Call page for a detailed description.

In common programming languages, varlink clients do not require complex modules or libraries, already existing JSON and socket communication facilities are used to integrate natively into the programming language's object model. See the examples in the Clients page.

Requests specify the fully-qualified method that should be called, along with its input parameters:

{
  "method": "org.example.ftl.CalculateConfiguration",
  "parameters": {
    "current": {
      "longitude": "27.13",
      "latitude": "-12.4",
      "distance": "48732498234"
    },
    "target": {
      "longitude": "-48.7",
      "latitude": "12.9",
      "distance": "354667658787"
    }
  }
}

A service replies with an object that contains the output parameters:

{
  "parameters": {
    "configuration": {
      "speed": "32434234",
      "trajectory": "686787",
      "duration": "13256445"
    }
  }
}

Errors contain the fully-qualified error and optional parameters as specified and documented in the varlink interface file:

{
  "error": "org.example.ftl.ParameterOutOfRange",
  "parameters": { 
    "field": "current.distance"
  }
}

Service

Every varlink service offers the org.varlink.service interface, which describes all interfaces the service provides and provides information about the service implementation itself. See the Service page for details.

Address

Varlink services are expressed in URI form:

Type Example Comment
IP ip:127.0.0.1:12345 hostname/IP address and port
SSH ssh://example.org optional port number [:PORT]
UNIX socket unix:/run/org.example.ftl optional access ;mode=0666 parameter
UNIX abstract namespace socket unix:@org.example.ftl
executed binary exec:/usr/bin/org.example.ftl
device node device:/dev/org.kernel.example

See the transport screenshot for examples.

Resolver

Public varlink interfaces are registered system-wide by their well-known address, by default /run/org.varlink.resolver. The resolver translates a given varlink interface to the service address which provides this interface.

Multiple services can implement and offer the same interface, but only one of the services is registered with the resolver. The set of registered interfaces becomes the globally visible system interface, its actual configuration is usually defined by the operating system and not managed by the services themselves.

See the org.varlink.resolver interface for details.

Bridge

The varlink command line tool supports a bridge mode to bridge a single connection to the resolver and its registered services. It intercepts the calls to the org.varlink.service interface and replies with the information the resolver supplies.

If the bridge is used over SSH, all the interfaces of the locally running services appear to the remote ssh client as if they were implemented by the bridge.

See a the remote screenshot for an example.