Skip to content

feat: add multipart serialization - #179

Merged
Vincent Biret (baywet) merged 9 commits into
microsoft:mainfrom
andreaTP:feat/serialization-multipart
Oct 19, 2026
Merged

Vincent Biret (baywet) merged 9 commits into
microsoft:mainfrom
andreaTP:feat/serialization-multipart

Conversation

@andreaTP

Copy link
Copy Markdown
Contributor

Closes #55.

  • Abstractions: MultipartBody, and byte array read and write on parse nodes and writers. Setting a multipart body on a request adds the boundary to the content type.
  • JSON: byte arrays as base64.
  • microsoft_kiota_serialization_multipart: the multipart/form-data writer, ported from kiota-python with its tests.

Beyond Python: as in .NET, each body gets its own boundary, an empty part is allowed, and a stream part is read from the start each time. Quotes and line breaks in part names and file names are escaped, as browsers do.

Checked with a client generated from a small description: a JSON part and a file part reach a local server byte for byte. Also adds the gem to CI, the release workflow, release-please and dependabot. The generator registers it in a Kiota PR after the release.

Before the release: please add a pending trusted publisher on RubyGems for microsoft_kiota_serialization_multipart, or its publish job fails.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Existing Content-Type headers can omit the boundary, and part content types permit MIME header injection.

2 open findings
What changed in this PR

Adds multipart/form-data serialization and byte-array support across the Ruby abstractions and JSON serializer.

Changes:

  • Adds MultipartBody and a multipart serialization gem.
  • Adds Base64 JSON byte-array serialization.
  • Integrates multipart packaging, testing, dependency updates, and releases.
File Description
release-please-config.json Adds multipart version tracking.
README.md Documents the multipart gem and test task.
Rakefile Registers the multipart component.
Gemfile Adds the local multipart gem.
components/​serialization/​multipart/​spec/​spec_helper.rb Configures multipart specs.
components/​serialization/​multipart/​spec/​multipart_serialization_writer_spec.rb Tests multipart serialization.
components/​serialization/​multipart/​spec/​multipart_serialization_writer_factory_spec.rb Tests writer factory behavior.
components/​serialization/​multipart/​spec/​multipart_request_body_spec.rb Tests request-body integration.
components/​serialization/​multipart/​spec/​files/​test_entity.rb Provides a multipart test model.
components/​serialization/​multipart/​Rakefile Defines component test and build tasks.
components/​serialization/​multipart/​microsoft_kiota_serialization_multipart.gemspec Defines the new gem.
components/​serialization/​multipart/​lib/​microsoft_kiota_serialization_multipart/​version.rb Defines the gem version.
components/​serialization/​multipart/​lib/​microsoft_kiota_serialization_multipart/​multipart_serialization_writer.rb Implements multipart output.
components/​serialization/​multipart/​lib/​microsoft_kiota_serialization_multipart/​multipart_serialization_writer_factory.rb Creates multipart writers.
components/​serialization/​multipart/​lib/​microsoft_kiota_serialization_multipart.rb Exposes multipart library classes.
components/​serialization/​multipart/​Gemfile Defines component dependencies.
components/​serialization/​json/​spec/​json_byte_array_spec.rb Tests JSON byte arrays.
components/​serialization/​json/​lib/​microsoft_kiota_serialization_json/​json_serialization_writer.rb Writes Base64 byte arrays.
components/​serialization/​json/​lib/​microsoft_kiota_serialization_json/​json_parse_node.rb Decodes Base64 byte arrays.
components/​abstractions/​spec/​request_information_spec.rb Tests multipart request headers.
components/​abstractions/​spec/​multipart_body_spec.rb Tests multipart body behavior.
components/​abstractions/​lib/​microsoft_kiota_abstractions/​serialization/​serialization_writer.rb Adds byte-array writer API.
components/​abstractions/​lib/​microsoft_kiota_abstractions/​serialization/​parse_node.rb Adds byte-array parser API.
components/​abstractions/​lib/​microsoft_kiota_abstractions/​request_information.rb Attaches multipart boundaries.
components/​abstractions/​lib/​microsoft_kiota_abstractions/​multipart_body.rb Models and serializes multipart parts.
components/​abstractions/​lib/​microsoft_kiota_abstractions.rb Exports MultipartBody.
.github/​workflows/​ruby.yml Adds multipart CI coverage.
.github/​workflows/​release.yml Publishes the multipart gem.
.github/​dependabot.yml Enables multipart dependency updates.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI balanced review requested due to automatic review settings October 13, 2026 14:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Multipart request handling can fail with direct subpath loading and can emit conflicting boundary parameters.

1 open finding
2 resolved since last review

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 13, 2026 15:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Existing boundary parameters and non-seekable serialized part streams can currently produce invalid requests or serialization failures.

1 open finding
1 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Use rewind helper for non-seekable model part streams

components/​abstractions/​lib/​microsoft_kiota_abstractions/​multipart_body.rb:112

This direct rewind makes model parts fail when a serialization writer returns a readable but non-seekable stream such as a pipe: such streams respond to rewind but raise Errno::ESPIPE. The class already handles that case for stream-valued parts via its rewind helper, so use the same helper here before reading.

🧠 Review effort: Balanced

Comment thread components/abstractions/lib/microsoft_kiota_abstractions/request_information.rb Outdated
Copilot AI balanced review requested due to automatic review settings October 13, 2026 16:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation, integration, and automated coverage consistently satisfy the described multipart and byte-array requirements.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

@github-actions

Copy link
Copy Markdown
Contributor

This pull request has conflicting changes, the author must resolve the conflicts before this pull request can be merged.

Copilot AI balanced review requested due to automatic review settings October 14, 2026 09:22
@github-actions

Copy link
Copy Markdown
Contributor

Conflicts have been resolved. A maintainer will take a look shortly.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The Dependabot configuration contains duplicate directory keys and must use a separate update entry.

1 open finding

🧠 Review effort: Balanced

Comment thread .github/dependabot.yml
Copilot AI balanced review requested due to automatic review settings October 14, 2026 10:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Boundary parameters containing valid whitespace around the equals sign are duplicated instead of replaced.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

Copilot AI balanced review requested due to automatic review settings October 14, 2026 11:29
auto-merge was automatically disabled October 16, 2026 10:27

Head branch was pushed to by a user without write access

Copilot AI balanced review requested due to automatic review settings October 16, 2026 10:27
@github-actions

Copy link
Copy Markdown
Contributor

Conflicts have been resolved. A maintainer will take a look shortly.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Premature backing-store completion can silently omit model fields in repeated parts or retries after serialization failures.

1 open finding
1 resolved since last review

🧠 Review effort: Balanced

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for making the changes!

@andreaTP

Copy link
Copy Markdown
Contributor Author

Vincent Biret (@baywet) ready to merge whenever you can, then #180 can ship 0.25.0.

Copilot AI balanced review requested due to automatic review settings October 19, 2026 17:11
auto-merge was automatically disabled October 19, 2026 17:11

Head branch was pushed to by a user without write access

This comment was marked as off-topic.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No blocking issues remain, and regression coverage addresses multipart encoding, boundaries, and backing-store failure handling.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

@baywet
Vincent Biret (baywet) merged commit 0c4d56a into microsoft:main Oct 19, 2026
238 checks passed
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.

Ruby - support for multipart form data request boddy

3 participants