WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@EngOmarElsayed
Copy link

Prevent appending ? to URL when query items array is empty

Motivation:

When calling URL.appending(queryItems:) with an empty array, the current implementation appends a trailing ? to the URL (e.g., "www.google.com" becomes "www.google.com?"). This produces potentially invalid URLs and forces users to add defensive checks before calling the method.

Related to this issue #1548

Modifications:

Added an early return guard in appending(queryItems:) that returns self unchanged when the provided queryItems array is empty.

Result:

Calling url.appending(queryItems: []) now returns the original URL without any modifications, allowing developers to chain URL construction methods without defensive empty-array checks:

// Before: "www.google.com?"
// After:  "www.google.com"
let url = URL(string: "www.google.com")!.appending(queryItems: [])

Testing:

  • Added a test case verifying that appending an empty query items array returns the original URL unchanged
  • Verified existing tests pass to ensure no regression in behavior when non-empty query items are provided

@jrflat
Copy link
Contributor

jrflat commented Dec 11, 2025

Thanks for opening this PR up for discussion! I think there's some app compatibility risk with this change we'll need to consider. For instance, an app might assume that a URL they append query items to will always have a query:

url.append(queryItems: queryItems)
print(url.query!) // Crash

It's a bit of a contrived example, but unexpectedly nil properties can often lead to compatibility issues. (It might also trigger different code paths for an if let query = ... block, for example.) Another argument against changing the current behavior is that other URL and URLComponents methods behave similarly, e.g:

var comp = URLComponents(string: "/path")!
comp.queryItems = []
print(comp) // "/path?" -- appends "?"

let url = URL(string: "/path")!
print(url.appending(path: "")) // "/path/" -- appends "/"
print(url.appendingPathComponent("")) // "/path/" -- appends "/"

let hostURL = URL(string: "https://example.com")!
print(hostURL.appending(path: "")) // "https://example.com/" -- appends "/"

I'll admit that URLComponents.queryItems isn't exactly the same as URL.appending(queryItems:) since you can set comp.queryItems = nil to remove the query and "?" entirely, but it's pretty similar.

Overall, I would lean towards keeping the current behavior, but I'm happy to hear a counterargument! :)

@EngOmarElsayed
Copy link
Author

EngOmarElsayed commented Dec 11, 2025

Replied in the issue page: #1548

@EngOmarElsayed
Copy link
Author

EngOmarElsayed commented Dec 12, 2025

Better solution to prevent any compatibility risk #1650 @jrflat

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.

2 participants