Skip to content

Support map-style query parameters (type: object + additionalProperties)#2144

Open
bkoelman wants to merge 2 commits into
microsoft:mainfrom
bkoelman:feat/map-query-param-support
Open

Support map-style query parameters (type: object + additionalProperties)#2144
bkoelman wants to merge 2 commits into
microsoft:mainfrom
bkoelman:feat/map-query-param-support

Conversation

@bkoelman

Copy link
Copy Markdown

Contributes to microsoft/kiota#3800.

Add a Map branch to getSanitizedValues so that plain-object dictionary query parameters are pre-processed before they reach StdUriTemplate.

Without this change, a Map<String, String> value passed through addQueryParameters or addQueryParameter falls through to the else-return branch unchanged. When the map contains a null value the subsequent call to StdUriTemplate.convertNativeTypes(null) throws a NullPointerException (null.getClass() is called in the fallback throw).

The fix mirrors the kiota-dotnet SanitizeDictionary approach exactly: null-valued entries are dropped (RFC 6570 para 2.3 treats undefined variables as absent), and remaining values are normalised to String via the existing getSanitizedValues pipeline. The sanitized HashMap<String, String> is returned so StdUriTemplate.isMap/addMapValue can expand it as individual key=value pairs for RFC 6570 {?param*} templates.

The @SuppressWarnings("unchecked") annotation suppresses the unavoidable raw-type cast of Map<Object,Object> -- Java generics are erased at runtime so the cast to the generic Map type is unverifiable by the compiler, but safe because the entries are accessed only as Object.

…+ additionalProperties)

Add a Map branch to getSanitizedValues so that plain-object dictionary
query parameters are pre-processed before they reach StdUriTemplate.

Without this change, a Map<String, String> value passed through
addQueryParameters or addQueryParameter falls through to the else-return
branch unchanged.  When the map contains a null value the subsequent
call to StdUriTemplate.convertNativeTypes(null) throws a
NullPointerException (null.getClass() is called in the fallback throw).

The fix mirrors the kiota-dotnet SanitizeDictionary approach exactly:
null-valued entries are dropped (RFC 6570 para 2.3 treats undefined
variables as absent), and remaining values are normalised to String via
the existing getSanitizedValues pipeline.  The sanitized HashMap<String,
String> is returned so StdUriTemplate.isMap/addMapValue can expand it as
individual key=value pairs for RFC 6570 {?param*} templates.

The @SuppressWarnings("unchecked") annotation suppresses the unavoidable
raw-type cast of Map<Object,Object> -- Java generics are erased at
runtime so the cast to the generic Map type is unverifiable by the
compiler, but safe because the entries are accessed only as Object.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bkoelman
bkoelman marked this pull request as ready for review July 23, 2026 00:24
@bkoelman
bkoelman requested a review from a team as a code owner July 23, 2026 00:24

@baywet 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!

// the variable expansion results in no output". Use "" to send ?key= (empty value).
@SuppressWarnings("unchecked")
final Map<Object, Object> rawMap = (Map<Object, Object>) value;
final HashMap<String, String> sanitized = new HashMap<>(rawMap.size());

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.

same as dotnet, can we use map string object instead to avoid the call to tostring below?

@github-project-automation github-project-automation Bot moved this to In Progress 🚧 in Kiota Jul 23, 2026
@baywet
baywet requested a review from Copilot July 23, 2026 13:38
@baywet

baywet commented Jul 23, 2026

Copy link
Copy Markdown
Member

CC @andreaTP

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds support for “map-style” (object + additionalProperties) query parameters by sanitizing Map values before URI template expansion, preventing NullPointerException when map entries contain null values and enabling RFC 6570 {?param*} exploded expansion.

Changes:

  • Add Map handling to RequestInformation.getSanitizedValues that drops null-valued entries and normalizes remaining values.
  • Add unit tests covering exploded map query parameter expansion, null-handling, and interaction with scalar query parameters.
  • Extend the test query-parameter model (GetQueryParameters) with a query map field and include it in toQueryParameters().

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
components/abstractions/src/main/java/com/microsoft/kiota/RequestInformation.java Adds Map sanitization so {?query*} can expand dictionary entries safely (dropping null values).
components/abstractions/src/test/java/com/microsoft/kiota/RequestInformationTest.java Adds tests to validate exploded map query parameter expansion and null-handling behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +486 to +492
for (final Map.Entry<Object, Object> entry : rawMap.entrySet()) {
if (entry.getValue() != null) {
sanitized.put(
entry.getKey().toString(),
getSanitizedValues(entry.getValue()).toString());
}
}
@andreaTP

Copy link
Copy Markdown
Contributor

seems like a legit change to me 👍

…rameters

Address PR feedback by using HashMap<String, Object> instead of HashMap<String, String> when sanitizing map query parameters in RequestInformation. This avoids unnecessary .toString() calls on sanitized values and preserves native object types for StdUriTemplate expansion. Also adds null key checks and tests for varied map value types.

Co-authored-by: Cursor <cursoragent@cursor.com>
@bkoelman

Copy link
Copy Markdown
Author

Pushed fixes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress 🚧

Development

Successfully merging this pull request may close these issues.

4 participants