The Interledger Community 🌱

Andrea Peruffo
Andrea Peruffo

Posted on

Ruby Language Support for Kiota — ILF Grant Progress Report

Brief Project Description

Kiota is Microsoft's open source generator that turns an OpenAPI description into a typed API client. Its Ruby target existed but was classified as Experimental: the integration test was broken, Ruby carried 15 test suppressions (more than every other language combined), composed types and several response shapes were not handled, and the runtime gems were scattered across pre-1.0 repositories. This grant closes those gaps so that Kiota produces correct, idiomatic Ruby clients from standard OpenAPI descriptions, with the Open Payments APIs as the reference use case, and moves the Ruby target from Experimental toward Preview. All work is merged upstream.

Project Update

Two of the three funded months are done and the project is on the original timeline.

The headline is that a payment now goes end to end through Open Payments using only Kiota-generated Ruby clients. The demo at https://github.com/andreaTP/kiota-ruby-op-poc generates the three clients (wallet address, auth server, resource server) from the official Open Payments 1.4.0 descriptions and runs the flow from interledger/open-payments-example: read both wallets, incoming payment grant, incoming payment, quote grant, quote, interactive outgoing payment grant approved in the browser, grant continuation, outgoing payment, then polling until the incoming payment is paid in full. Only two things are hand written: a Kiota authentication provider that adds the GNAP token and signs each request (RFC 9421 HTTP message signatures with Ed25519, RFC 9530 Content-Digest), and the flow itself. The README covers running it against a local stand-in that verifies the tokens and signatures, and against the Interledger test network.

Getting there took 29 pull requests to microsoft/kiota, microsoft/kiota-ruby and the former per-gem repositories (all linked below). Along the way the four Ruby runtime gems were consolidated into one repository and released as 0.24.0 (Ruby 3.3+), and the Ruby integration-test suppressions went from 15 to 1 (Microsoft Graph beta, which is not tested for Ruby by design).

The main struggle matched what I anticipated in the proposal as "hidden semantic gaps". Several problems only surfaced when real payloads went through the generated code: enum members were sent with their Ruby name ("IncomingPayment") instead of their wire value ("incoming-payment"), so every grant request was rejected, and a oneOf without a discriminator, which Open Payments uses for grant, continue and error responses, came back as an empty object. Both are fixed in kiota#8314 and kiota-ruby#171. Some fixes were breaking changes to the gems (enum values, unset scalars no longer written as null or ""), which is why they were made now, while the target is still Experimental, rather than later.

A second input that shaped the work was an independent report by @wiebren on kiota#7956, who ran a generated Ruby client through a 29-case contract suite they use across languages. All eight itemized failures are now fixed.

The one scope change against the month-2 plan is that the Text, Form and Multipart serialization gems are not started yet. The Open Payments blockers and the correctness issues above were more valuable to users and took the time. The serialization gems move to month 3, see "What's Next".

Project Impact & Target Audience(s)

The direct beneficiaries are Ruby developers who want a typed client for an OpenAPI-described API without writing it by hand, and the Interledger ecosystem in particular. Ruby is widely used by small teams and in fintech, and before this work there was no viable path to an Open Payments client in Ruby: Kiota's Ruby output did not compile against real-world descriptions. kiota#7956 was opened by a community member precisely to get an Open Payments Ruby SDK, and the generated clients now cover that use case. This lowers the barrier for Rails and Ruby shops to integrate Open Payments, which supports the Foundation's mission of broadening who can build on the Interledger Protocol.

Secondary beneficiaries are all Kiota users: two of the fixes landed in the core generator and apply to every language (kiota#8138 makes generation reproducible, kiota#8193 by @Om-singhaI stops an inline type from clobbering a component with the same name), and the Ruby target now runs the same CI as the mature languages.

The project does not target a specific demographic group. The work is upstream, open source (MIT) and free to use, so anyone can benefit from it without a relationship to me or to the Foundation.

Progress on Objectives, Key Activities

Status against the proposal, grouped as in the original submission. Links go to the merged pull requests.

Critical fixes

Objective Status Links
Binary/stream type support Done. Stream request bodies are sent, binary responses reach the right adapter method, binary aliases resolve to the right model. kiota#8256, kiota#8265, kiota-ruby#163
HTTP send method dispatch (void, collection, collection of primitives) Done. All five send variants exist in the adapter and the generator dispatches every response shape to the right one. kiota-ruby#155, kiota#8256
Text, Form and Multipart serialization gems Not started, moved to month 3. #2077, #3032, #1049
Triage the 15 integration test suppressions Done. 1 suppression remains (Microsoft Graph beta, excluded on purpose). Ruby CI now generates and lints 19 descriptions, including GitHub, Stripe, Notion and Meraki, and runs mock-server tests for errors, inheritance, query parameters, discriminators, enums and default values. kiota#8116, kiota#8127, kiota#8131, kiota#8255, kiota#8301

High-severity gaps

Objective Status Links
Composed types (union/intersection) Done, with and without a discriminator, including primitive and array members. kiota#8065, kiota#8209, kiota#8314, kiota-ruby#106, kiota-ruby#142, kiota-ruby#151, kiota-ruby#171
Backing store (complete or remove) Open. Decision planned for month 3, after asking the maintainers and users whether anyone depends on it.
Scalar vs parsable request body discrimination Done. Scalar bodies and enum collections are serialized. kiota-ruby#158, kiota#8256
Unit test coverage In progress. Every fix above came with unit tests and mock-server integration tests; a dedicated coverage pass is planned for month 3.

Completeness and quality

Objective Status Links
Enum handling (collections, defaults by wire name, wire values) Done. kiota#8053, kiota#8256, kiota#8314, kiota-ruby#158
Typed errors, status code and headers on ApiError Done. kiota-ruby#153, kiota-ruby#171
Idiomatic Ruby output (RuboCop clean, frozen string literals, attr_accessor, no ruby -w warnings, autoloaded models) Done. kiota#8037, kiota#8052, kiota#8301
Unset scalars left off the wire Done. kiota-ruby#154
Runtime gem stabilization toward 1.0 In progress. The four gems now live in one repository with a shared release process, released as 0.24.0 requiring Ruby 3.3+. kiota-ruby#112, kiota-ruby#140
Primary error message, deprecation annotations Open, month 3. kiota-ruby#63
Quickstart documentation In progress. The Open Payments demo README is a working quickstart; the upstream docs page is planned for month 3. https://github.com/andreaTP/kiota-ruby-op-poc
Maturity from Experimental toward Preview To be proposed to the maintainers once month 3 lands.

Expected outcomes from the proposal

  • Correct, idiomatic SDKs for standard OpenAPI specs: yes, verified on 19 public descriptions plus Open Payments.
  • Integration test passes end to end: yes.
  • Suppressions from 15 to zero: 15 to 1, the last one is intentional.
  • All 4 serialization formats via published gems: JSON only so far, the other three are month 3.
  • Test coverage at parity with other languages: in progress.
  • All work merged upstream: yes, every change is in microsoft/kiota or microsoft/kiota-ruby.

Communications and Marketing

All of the work happened in public on GitHub, through pull requests, reviews and issue threads with the Kiota maintainers. The main public writeup is the summary I am posting on kiota#7956, the issue that motivated the Open Payments use case, with the itemized list of what changed and what is still open. The demo repository at https://github.com/andreaTP/kiota-ruby-op-poc documents how to generate the clients and send a payment on the Interledger test network.

I am also in touch with the Kiota team on their Discord. The proposal has no marketing budget. A blog post walking through the Open Payments flow in Ruby is planned once the month-3 work is released.

What's Next?

The remaining month (to November 10, 2026) covers the month-3 plan plus the item moved from month 2:

  1. Text, Form and Multipart serialization gems in microsoft/kiota-ruby, closing #2077, #3032 and #1049.
  2. Backing store: complete or remove, based on maintainer and community input.
  3. Remaining completeness items: primary error message, deprecation annotations.
  4. Unit test coverage expansion in the generator's Ruby writers and in the gems.
  5. Runtime gem stabilization: a release that bundles the above, and the path to 1.0 agreed with the maintainers.
  6. Quickstart documentation on the Kiota docs site, and a blog post on the Open Payments flow.
  7. Proposing to the maintainers that Ruby moves from Experimental to Preview.
  8. Final report by December 10, 2026.

Community Support

  • Try it on Open Payments. If you write Ruby and have a test wallet, run the demo against the Interledger test network and report anything odd. Real usage is what found the last two blockers.
  • Is a Ruby Open Payments SDK wanted? The generated clients could be the basis of an official open-payments gem, in the way the TypeScript and PHP SDKs exist today. I would value a conversation with the Open Payments team about whether that is desirable and who would own it.
  • Backing store. If anyone depends on the backing store in Ruby, I would like to hear it before the keep-or-drop decision is made.

Additional Comments

Thanks to Vincent Biret (@baywet) for reviewing every pull request promptly, to @wiebren for the detailed contract-suite report, to @mahmudsudo for opening the Open Payments issue, and to @Om-singhaI for the core fix on component name collisions.

As stated in the proposal, AI tooling (Claude Code) was used throughout for analysis and implementation, with every change reviewed by me before it was submitted and then by the Kiota maintainers before it was merged.

Relevant Links/Resources (optional)

Generator pull requests, microsoft/kiota:

Runtime pull requests, microsoft/kiota-ruby:

Former per-gem repositories, before the consolidation:

Core fix benefiting all languages: https://github.com/microsoft/kiota/pull/8193

Top comments (0)