Skip to content

api: new endpoint that dynamically generate openapi from varlink IDL#27

Open
mvo5 wants to merge 1 commit intosystemd:mainfrom
mvo5:openapi-support
Open

api: new endpoint that dynamically generate openapi from varlink IDL#27
mvo5 wants to merge 1 commit intosystemd:mainfrom
mvo5:openapi-support

Conversation

@mvo5
Copy link
Copy Markdown
Contributor

@mvo5 mvo5 commented Mar 24, 2026

This commit adds an endpoint for that generates openapi descriptions from the varlink IDL for a given interface. It is located under /openapi/{socket}/{interface} and is created dynamically.

This is useful to bridge the gap between varlink and the wide openapi ecosytem. This allows to e.g. create fully typed interfaces for tyescript/react/go etc.

This is using openapi 3.1 because it seems to be the most widely used one currently.

Note that this seems to work well for most of the IDL and it maps nicely. The thing that does not map well is errors. The varlink IDL does only specify errors per interface but not per method. So currently errors are added as components but not part of the potential methods returns because we would have to add all errors as potential returns to all methods which feels a bit too much. Nullable is also added a bit simplistic.

The other gap is "more" support, currently this is not discoverable from the IDL so we cannot make it part of the openapi output. We may need to have a convention in the method description or something, but that can be done in a followup. Only a small subset of calls uses "more" currently.

E.g.

$ curl -s http://localhost:1031/openapi/io.systemd.MuteConsole/io.systemd.MuteConsole|jq
{
  "info": {
    "description": "API for temporarily muting noisy output to the main kernel console",
    "title": "io.systemd.MuteConsole",
    "version": "0.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/call/io.systemd.MuteConsole/io.systemd.MuteConsole.Mute": {
      "post": {
        "description": "Mute kernel and PID 1 output to the main kernel console\n[Requires 'more' flag]",
        "operationId": "Mute",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "kernel": {
                    "description": "Whether to mute the kernel's output to the console (defaults to true).",
                    "type": "boolean"
                  },
                  "pid1": {
                    "description": "Whether to mute PID1's output to the console (defaults to true).",
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {},
                  "type": "object"
                }
              }
            },
            "description": "Successful response"
          }
        }
      }
    }
  }
}

GET /sockets → list available sockets (c.f. valinkctl list-registry)
GET /sockets/{socket} → socket info (c.f. varlinkctl info)
GET /sockets/{socket}/{interface} → interface details, including method names (c.f. varlinkctl list-methods)
GET /openapi/{socket}/{interface} → OpenAPI 3.1 description generated from varlink IDL
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, maybe this should follow the convention from /call ? i.e. by /openapi/{interface} and an optional ?socket= ?

@mvo5 mvo5 force-pushed the openapi-support branch 2 times, most recently from f3f7365 to bc283f1 Compare March 25, 2026 11:00
This commit adds an endpoint for that generates openapi descriptions
from the varlink IDL for a given interface. It is located under
/openapi/{socket}/{interface} and is created dynamically.

This is useful to bridge the gap between varlink and the wide
openapi ecosytem. This allows to e.g. create fully typed interfaces
for tyescript/react/go etc.

This is using openapi 3.1 because it seems to be the most widely
used one currently.

Note that this seems to work well for most of the IDL and it maps
nicely. The thing that does not map well is errors. The varlink
IDL does only specify errors per interface but not per method. So
currently errors are added as `components` but not part of the
potential methods returns because we would have to add all errors
as potential returns to all methods which feels a bit too much.
Nullable is also added a bit simplistic.

The other gap is "more" support, currently this is not discoverable
from the IDL so we cannot make it part of the openapi output. We
may need to have a convention in the method description or something,
but that can be done in a followup. Only a small subset of calls uses
"more" currently.

E.g.
```json
$ curl -s http://localhost:1031/openapi/io.systemd.MuteConsole/io.systemd.MuteConsole|jq
{
  "info": {
    "description": "API for temporarily muting noisy output to the main kernel console",
    "title": "io.systemd.MuteConsole",
    "version": "0.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/call/io.systemd.MuteConsole/io.systemd.MuteConsole.Mute": {
      "post": {
        "description": "Mute kernel and PID 1 output to the main kernel console\n[Requires 'more' flag]",
        "operationId": "Mute",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "kernel": {
                    "description": "Whether to mute the kernel's output to the console (defaults to true).",
                    "type": "boolean"
                  },
                  "pid1": {
                    "description": "Whether to mute PID1's output to the console (defaults to true).",
                    "type": "boolean"
                  }
                },
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {},
                  "type": "object"
                }
              }
            },
            "description": "Successful response"
          }
        }
      }
    }
  }
}
```
@mvo5 mvo5 force-pushed the openapi-support branch from bc283f1 to ef39da6 Compare March 25, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant